]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
2007-06-08 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Fri, 8 Jun 2007 20:43:35 +0000 (20:43 +0000)
committerHavoc Pennington <hp@redhat.com>
Fri, 8 Jun 2007 20:43:35 +0000 (20:43 +0000)
* backport fix to allow a server to use port=0 or omit port so
the port can be auto-selected by the OS

ChangeLog
bus/dbus-daemon.1.in
dbus/dbus-server-socket.c
dbus/dbus-sysdeps-unix.c
dbus/dbus-sysdeps.h

index e16b3b8d2632521494913150922e454789eda5e4..d9d6e66f7c15c476b478ea85dc801550ff294daa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-06-08  Havoc Pennington  <hp@redhat.com>
+
+       * backport fix to allow a server to use port=0 or omit port so 
+       the port can be auto-selected by the OS
+
 2007-05-23  Havoc Pennington  <hp@redhat.com>
 
        * bus/Makefile.am (install-data-hook): create session.d
index 5c8468363ddb34a932f63b50b8f0e5c11c4675c6..acee933ab6d32a4daa5c18a8633268207e84fce0 100644 (file)
@@ -210,6 +210,9 @@ a transport name plus possible parameters/options.
 .PP
 Example: <listen>unix:path=/tmp/foo</listen>
 
+.PP
+Example: <listen>tcp:host=localhost,port=1234</listen>
+
 .PP
 If there are multiple <listen> elements, then the bus listens 
 on multiple addresses. The bus will pass its address to 
@@ -217,6 +220,14 @@ started services or other interested parties with
 the last address given in <listen> first. That is, 
 apps will try to connect to the last <listen> address first.
 
+.PP
+A special case is using a port number of zero which means to 
+pick up a random free port. The real used port number could be retrieved
+by using the --print-address command line parameter.
+
+.PP
+Example: <listen>tcp:host=localhost,port=0</listen>
+
 .TP
 .I "<auth>"
 
index 5c11e145bc46824cb4265f8240d2fe08d660265b..3a0da35f5dafe504e81cb8dff8f39e0d5239fa47 100644 (file)
@@ -323,6 +323,9 @@ _dbus_server_new_for_tcp_socket (const char     *host,
 
   if (host == NULL)
     host = "localhost";
+  
+  listen_fd = _dbus_listen_tcp_socket (host, &port, error);
+  _dbus_fd_set_close_on_exec (listen_fd);
 
   _dbus_string_init_const (&host_str, host);
   if (!_dbus_string_append (&address, "tcp:host=") ||
@@ -334,9 +337,7 @@ _dbus_server_new_for_tcp_socket (const char     *host,
       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
       return NULL;
     }
-  
-  listen_fd = _dbus_listen_tcp_socket (host, port, error);
-  _dbus_fd_set_close_on_exec (listen_fd);
+
   
   if (listen_fd < 0)
     {
@@ -401,7 +402,7 @@ _dbus_server_listen_socket (DBusAddressEntry *entry,
       sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
       _dbus_string_free (&str);
           
-      if (sresult == FALSE || lport <= 0 || lport > 65535)
+      if (sresult == FALSE || lport < 0 || lport > 65535)
         {
           _dbus_set_bad_address(error, NULL, NULL, 
                                 "Port is not an integer between 0 and 65535");
index 1c96d6e3454502e2dbba86a04de4b7845b808cfc..eedbe33b1d4eacfaf24b6411568dceb8575f0842 100644 (file)
@@ -757,21 +757,24 @@ _dbus_connect_tcp_socket (const char     *host,
  * Creates a socket and binds it to the given path,
  * then listens on the socket. The socket is
  * set to be nonblocking. 
+ * In case of port=0 a random free port is used and 
+ * returned in the port parameter. 
  *
  * @param host the host name to listen on
- * @param port the prot to listen on
+ * @param port the prot to listen on, if zero a free port will be used 
  * @param error return location for errors
  * @returns the listening file descriptor or -1 on error
  */
 int
 _dbus_listen_tcp_socket (const char     *host,
-                         dbus_uint32_t   port,
+                         dbus_uint32_t  *port,
                          DBusError      *error)
 {
   int listen_fd;
   struct sockaddr_in addr;
   struct hostent *he;
   struct in_addr *haddr;
+  socklen_t len = (socklen_t) sizeof (struct sockaddr);
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   
@@ -799,13 +802,13 @@ _dbus_listen_tcp_socket (const char     *host,
   _DBUS_ZERO (addr);
   memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
   addr.sin_family = AF_INET;
-  addr.sin_port = htons (port);
+  addr.sin_port = htons (*port);
 
   if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
     {
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Failed to bind socket \"%s:%d\": %s",
-                      host, port, _dbus_strerror (errno));
+                      host, *port, _dbus_strerror (errno));
       _dbus_close (listen_fd, NULL);
       return -1;
     }
@@ -814,11 +817,14 @@ _dbus_listen_tcp_socket (const char     *host,
     {
       dbus_set_error (error, _dbus_error_from_errno (errno),  
                       "Failed to listen on socket \"%s:%d\": %s",
-                      host, port, _dbus_strerror (errno));
+                      host, *port, _dbus_strerror (errno));
       _dbus_close (listen_fd, NULL);
       return -1;
     }
 
+  getsockname(listen_fd, (struct sockaddr*) &addr, &len);
+  *port = (dbus_uint32_t) ntohs(addr.sin_port);
+
   if (!_dbus_set_fd_nonblocking (listen_fd, error))
     {
       _dbus_close (listen_fd, NULL);
index 2218cfc1262612e8fb371d661bb4db6d65ff9997..d3659f24af7f870bfa570f3b076929b0cb60fbe1 100644 (file)
@@ -141,7 +141,7 @@ int _dbus_connect_tcp_socket  (const char     *host,
                                dbus_uint32_t   port,
                                DBusError      *error);
 int _dbus_listen_tcp_socket   (const char     *host,
-                               dbus_uint32_t   port,
+                               dbus_uint32_t  *port,
                                DBusError      *error);
 int _dbus_accept              (int             listen_fd);