2007-06-13 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Wed, 13 Jun 2007 20:52:58 +0000 (20:52 +0000)
committerHavoc Pennington <hp@redhat.com>
Wed, 13 Jun 2007 20:52:58 +0000 (20:52 +0000)
* dbus/dbus-server-socket.c (_dbus_server_listen_socket): support
all_interfaces=true|false for tcp servers

* dbus/dbus-sysdeps-unix.c (_dbus_listen_tcp_socket): support
inaddr_any flag

* bus/selinux.c: fix some missing includes

* dbus/dbus-server-socket.c (_dbus_server_listen_socket): allow
port to simply be omitted in addition to specifying 0

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

index 26e9784..88070a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2007-06-13  Havoc Pennington  <hp@redhat.com>
 
+       * dbus/dbus-server-socket.c (_dbus_server_listen_socket): support
+       all_interfaces=true|false for tcp servers
+
+       * dbus/dbus-sysdeps-unix.c (_dbus_listen_tcp_socket): support
+       inaddr_any flag
+
+       * bus/selinux.c: fix some missing includes
+
+       * dbus/dbus-server-socket.c (_dbus_server_listen_socket): allow
+       port to simply be omitted in addition to specifying 0
+
+2007-06-13  Havoc Pennington  <hp@redhat.com>
+
        * configure.ac, bus/selinux.c, dbus/dbus-sysdeps-unix-util.c: add
        libaudit support, no clue what this means really but now we have
        it. Patches from Fedora package.
index a657d28..ce623f8 100644 (file)
@@ -221,13 +221,22 @@ 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.
+A special case is using a port number of zero (or omitting the port),
+which means to choose an available port selected by the operating
+system. The port number chosen can be with the --print-address command
+line parameter and will be present in other cases where the server 
+reports its own address, such as when DBUS_SESSION_BUS_ADDRESS is set.
 
 .PP
 Example: <listen>tcp:host=localhost,port=0</listen>
 
+.PP
+tcp addresses also allow an all_interfaces=true option, which will
+cause the bus to listen on all local address (INADDR_ANY) and not only
+the specified host. However, the specified host will still be used as
+the reported address of the server. The specified host should be a
+valid name of the local machine or weird stuff will happen.
+
 .TP
 .I "<auth>"
 
index c213838..a37e367 100644 (file)
@@ -29,6 +29,8 @@
 #include "config-parser.h"
 
 #ifdef HAVE_SELINUX
+#include <sys/types.h>
+#include <unistd.h>
 #include <errno.h>
 #include <pthread.h>
 #include <syslog.h>
@@ -38,6 +40,7 @@
 #include <selinux/flask.h>
 #include <signal.h>
 #include <stdarg.h>
+#include <stdio.h>
 #ifdef HAVE_LIBAUDIT
 #include <libaudit.h>
 #endif /* HAVE_LIBAUDIT */
index 3a0da35..e6fd7d5 100644 (file)
@@ -295,17 +295,24 @@ _dbus_server_new_for_socket (int               fd,
 }
 
 /**
- * Creates a new server listening on the given hostname and port.
- * If the hostname is NULL, listens on localhost.
+ * Creates a new server listening on TCP.
+ * If inaddr_any is TRUE, listens on all local interfaces.
+ * Otherwise, it resolves the hostname and listens only on
+ * the resolved address of the hostname. The hostname is used
+ * even if inaddr_any is TRUE, as the hostname to report when
+ * dbus_server_get_address() is called. If the hostname is #NULL,
+ * localhost is used.
  *
  * @param host the hostname to listen on.
- * @param port the port to listen on.
+ * @param port the port to listen on or 0 to let the OS choose
+ * @param inaddr_any #TRUE to listen on all local interfaces
  * @param error location to store reason for failure.
  * @returns the new server, or #NULL on failure.
  */
 DBusServer*
 _dbus_server_new_for_tcp_socket (const char     *host,
                                  dbus_uint32_t   port,
+                                 dbus_bool_t     inaddr_any,
                                  DBusError      *error)
 {
   DBusServer *server;
@@ -324,7 +331,7 @@ _dbus_server_new_for_tcp_socket (const char     *host,
   if (host == NULL)
     host = "localhost";
   
-  listen_fd = _dbus_listen_tcp_socket (host, &port, error);
+  listen_fd = _dbus_listen_tcp_socket (host, &port, inaddr_any, error);
   _dbus_fd_set_close_on_exec (listen_fd);
 
   _dbus_string_init_const (&host_str, host);
@@ -386,30 +393,57 @@ _dbus_server_listen_socket (DBusAddressEntry *entry,
   
   if (strcmp (method, "tcp") == 0)
     {
-      const char *host = dbus_address_entry_get_value (entry, "host");
-      const char *port = dbus_address_entry_get_value (entry, "port");
-      DBusString  str;
+      const char *host;
+      const char *port;
+      const char *all_interfaces;
+      dbus_bool_t inaddr_any;
       long lport;
-      dbus_bool_t sresult;
-          
+
+      host = dbus_address_entry_get_value (entry, "host");
+      port = dbus_address_entry_get_value (entry, "port");
+      all_interfaces = dbus_address_entry_get_value (entry, "all_interfaces");
+
+      inaddr_any = FALSE;
+      if (all_interfaces != NULL)
+        {
+          if (strcmp (all_interfaces, "true") == 0)
+            {
+              inaddr_any = TRUE;
+            }
+          else if (strcmp (all_interfaces, "false") == 0)
+            {
+              inaddr_any = FALSE;
+            }
+          else
+            {
+              _dbus_set_bad_address(error, NULL, NULL, 
+                                    "all_interfaces flag in tcp: address should be 'true' or 'false'");
+              return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+            }
+        }
+      
       if (port == NULL)
         {
-          _dbus_set_bad_address(error, "tcp", "port", NULL);
-          return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+          lport = 0;
         }
-
-      _dbus_string_init_const (&str, port);
-      sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
-      _dbus_string_free (&str);
-          
-      if (sresult == FALSE || lport < 0 || lport > 65535)
+      else
         {
-          _dbus_set_bad_address(error, NULL, NULL, 
-                                "Port is not an integer between 0 and 65535");
-          return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+          dbus_bool_t sresult;
+          DBusString  str;
+          
+          _dbus_string_init_const (&str, port);
+          sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
+          _dbus_string_free (&str);
+          
+          if (sresult == FALSE || lport < 0 || lport > 65535)
+            {
+              _dbus_set_bad_address(error, NULL, NULL, 
+                                    "Port is not an integer between 0 and 65535");
+              return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+            }
         }
           
-      *server_p = _dbus_server_new_for_tcp_socket (host, lport, error);
+      *server_p = _dbus_server_new_for_tcp_socket (host, lport, inaddr_any, error);
 
       if (*server_p)
         {
index 384098e..176304f 100644 (file)
@@ -32,6 +32,7 @@ DBusServer* _dbus_server_new_for_socket           (int               fd,
                                                    const DBusString *address);
 DBusServer* _dbus_server_new_for_tcp_socket       (const char       *host,
                                                    dbus_uint32_t     port,
+                                                   dbus_bool_t       inaddr_any,
                                                    DBusError        *error);
 DBusServerListenResult _dbus_server_listen_socket (DBusAddressEntry  *entry,
                                                    DBusServer       **server_p,
index f1c133f..b3ffe04 100644 (file)
@@ -807,30 +807,28 @@ _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. 
+ * 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.
+ * If inaddr_any is specified, the hostname is ignored.
  *
  * @param host the host name to listen on
- * @param port the prot to listen on, if zero a free port will be used 
+ * @param port the prot to listen on, if zero a free port will be used
+ * @param inaddr_any TRUE to listen on all local interfaces instead of on the host name
  * @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_bool_t     inaddr_any,
                          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);
-  
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);  
   
   if (!_dbus_open_tcp_socket (&listen_fd, error))
     {
@@ -839,21 +837,33 @@ _dbus_listen_tcp_socket (const char     *host,
     }
   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 
-  he = gethostbyname (host);
-  if (he == NULL) 
+  _DBUS_ZERO (addr);
+  
+  if (inaddr_any)
     {
-      dbus_set_error (error,
-                      _dbus_error_from_errno (errno),
-                      "Failed to lookup hostname: %s",
-                      host);
-      _dbus_close (listen_fd, NULL);
-      return -1;
+      addr.sin_addr.s_addr = INADDR_ANY;
     }
-  
-  haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+  else
+    {
+      struct hostent *he;
+      struct in_addr *haddr;      
 
-  _DBUS_ZERO (addr);
-  memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
+      he = gethostbyname (host);
+      if (he == NULL) 
+        {
+          dbus_set_error (error,
+                          _dbus_error_from_errno (errno),
+                          "Failed to lookup hostname: %s",
+                          host);
+          _dbus_close (listen_fd, NULL);
+          return -1;
+        }
+  
+      haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+      
+      memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
+    }
+  
   addr.sin_family = AF_INET;
   addr.sin_port = htons (*port);
 
index 87bfc8f..0cb92c6 100644 (file)
@@ -151,6 +151,7 @@ int _dbus_connect_tcp_socket  (const char     *host,
                                DBusError      *error);
 int _dbus_listen_tcp_socket   (const char     *host,
                                dbus_uint32_t  *port,
+                               dbus_bool_t     inaddr_any,
                                DBusError      *error);
 int _dbus_accept              (int             listen_fd);