2003-02-19 Mikael Hallendal <micke@codefactory.se>
authorMikael Hallendal <micke@codefactory.se>
Wed, 19 Feb 2003 08:13:31 +0000 (08:13 +0000)
committerMikael Hallendal <micke@codefactory.se>
Wed, 19 Feb 2003 08:13:31 +0000 (08:13 +0000)
* dbus/dbus-server.c (dbus_server_listen): Support tcp: addresses.

* dbus/dbus-transport-unix.c (_dbus_transport_new_for_tcp_socket):
Added to create a transport connecting using a tcp/ip socket.

* dbus/dbus-sysdeps.c (_dbus_connect_tcp_socket): Added to connect
to a tcp socket at given host and port.
(_dbus_listen_tcp_socket): added to listen on tcp socket for given
hostname and port.

* dbus/dbus-server.c (dbus_server_listen): Support tcp: addresses.

* dbus/dbus-server-unix.c (_dbus_server_new_for_tcp_socket):
Added to create a server listening on a TCP/IP socket.

ChangeLog
dbus/dbus-server-unix.c
dbus/dbus-server-unix.h
dbus/dbus-server.c
dbus/dbus-sysdeps.c
dbus/dbus-sysdeps.h
dbus/dbus-transport-unix.c
dbus/dbus-transport-unix.h
dbus/dbus-transport.c

index 196e8f8..e26ffc6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2003-02-19  Mikael Hallendal  <micke@codefactory.se>
+
+       * dbus/dbus-server.c (dbus_server_listen): Support tcp: addresses.
+
+       * dbus/dbus-transport-unix.c (_dbus_transport_new_for_tcp_socket): 
+       Added to create a transport connecting using a tcp/ip socket.
+
+       * dbus/dbus-sysdeps.c (_dbus_connect_tcp_socket): Added to connect
+       to a tcp socket at given host and port.
+       (_dbus_listen_tcp_socket): added to listen on tcp socket for given
+       hostname and port.
+
+       * dbus/dbus-server.c (dbus_server_listen): Support tcp: addresses.
+
+       * dbus/dbus-server-unix.c (_dbus_server_new_for_tcp_socket): 
+       Added to create a server listening on a TCP/IP socket.
+
 2003-02-19  Havoc Pennington  <hp@pobox.com>
 
        Throughout: mop up all the Doxygen warnings and undocumented
index 6da7053..a6635dd 100644 (file)
@@ -264,5 +264,40 @@ _dbus_server_new_for_domain_socket (const char     *path,
   return server;
 }
 
+/**
+ * Creates a new server listening on the given hostname and port
+ *
+ * @param host the hostname to listen on.
+ * @param port the port to listen on.
+ * @param result 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,
+                                 DBusResultCode *result)
+{
+  DBusServer *server;
+  int listen_fd;
+  
+  listen_fd = _dbus_listen_tcp_socket (host, port, result);
+  _dbus_fd_set_close_on_exec (listen_fd);
+  
+  if (listen_fd < 0)
+    return NULL;
+  
+  server = _dbus_server_new_for_fd (listen_fd);
+  if (server == NULL)
+    {
+      dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
+      close (listen_fd);
+      return NULL;
+    }
+
+  return server;
+
+
+}
+
 /** @} */
 
index 43614cc..ebd017d 100644 (file)
@@ -31,6 +31,9 @@ DBUS_BEGIN_DECLS;
 DBusServer* _dbus_server_new_for_fd            (int             fd);
 DBusServer* _dbus_server_new_for_domain_socket (const char     *path,
                                                 DBusResultCode *result);
+DBusServer* _dbus_server_new_for_tcp_socket    (const char     *host,
+                                                dbus_uint32_t   port,
+                                                DBusResultCode *result);
 
 DBUS_END_DECLS;
 
index 862aead..fd03423 100644 (file)
@@ -19,7 +19,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- */
+ */ 
+#include <stdlib.h>
 #include "dbus-server.h"
 #include "dbus-server-unix.h"
 #ifdef DBUS_BUILD_TESTS
@@ -228,6 +229,29 @@ dbus_server_listen (const char     *address,
          if (server)
            break;
        }
+      else if (strcmp (method, "tcp") == 0)
+       {
+         const char *host = dbus_address_entry_get_value (entries[i], "host");
+          const char *port = dbus_address_entry_get_value (entries[i], "port");
+          DBusString  str;
+          long lport;
+          dbus_bool_t sresult;
+          
+         if (port == NULL)
+           goto bad_address;
+
+          _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)
+            goto bad_address;
+          
+         server = _dbus_server_new_for_tcp_socket (host, lport, result);
+
+         if (server)
+           break;
+       }
 #ifdef DBUS_BUILD_TESTS
       else if (strcmp (method, "debug") == 0)
        {
index 316d278..bf4793e 100644 (file)
@@ -40,6 +40,8 @@
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <netinet/in.h>
+#include <netdb.h>
 
 #ifdef HAVE_WRITEV
 #include <sys/uio.h>
@@ -394,6 +396,161 @@ _dbus_listen_unix_socket (const char     *path,
   return listen_fd;
 }
 
+/**
+ * Creates a socket and connects to a socket at the given host 
+ * and port. The connection fd is returned, and is set up as
+ * nonblocking.
+ *
+ * @param host the host name to connect to
+ * @param port the prot to connect to
+ * @param result return location for error code
+ * @returns connection file descriptor or -1 on error
+ */
+int
+_dbus_connect_tcp_socket (const char     *host,
+                          dbus_uint32_t   port,
+                          DBusResultCode *result)
+{
+  int fd;
+  struct sockaddr_in addr;
+  struct hostent *he;
+  struct in_addr *haddr;
+  
+  fd = socket (AF_INET, SOCK_STREAM, 0);
+  
+  if (fd < 0)
+    {
+      dbus_set_result (result,
+                       _dbus_result_from_errno (errno));
+      
+      _dbus_verbose ("Failed to create socket: %s\n",
+                     _dbus_strerror (errno)); 
+      
+      return -1;
+    }
+
+  if (host == NULL)
+    host = "localhost";
+
+  he = gethostbyname (host);
+  if (he == NULL) 
+    {
+      dbus_set_result (result,
+                       _dbus_result_from_errno (errno));
+      _dbus_verbose ("Failed to lookup hostname: %s\n",
+                     host);
+      return -1;
+    }
+  
+  haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+
+  _DBUS_ZERO (addr);
+  memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons (port);
+  
+  if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
+    {      
+      dbus_set_result (result,
+                       _dbus_result_from_errno (errno));
+
+      _dbus_verbose ("Failed to connect to socket %s: %s:%d\n",
+                     host, port, _dbus_strerror (errno));
+
+      close (fd);
+      fd = -1;
+      
+      return -1;
+    }
+
+  if (!_dbus_set_fd_nonblocking (fd, result))
+    {
+      close (fd);
+      fd = -1;
+
+      return -1;
+    }
+
+  return fd;
+}
+
+/**
+ * Creates a socket and binds it to the given path,
+ * then listens on the socket. The socket is
+ * set to be nonblocking. 
+ *
+ * @param host the host name to listen on
+ * @param port the prot to listen on
+ * @param result 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,
+                         DBusResultCode *result)
+{
+  int listen_fd;
+  struct sockaddr_in addr;
+  struct hostent *he;
+  struct in_addr *haddr;
+  
+  listen_fd = socket (AF_INET, SOCK_STREAM, 0);
+  
+  if (listen_fd < 0)
+    {
+      dbus_set_result (result, _dbus_result_from_errno (errno));
+      _dbus_verbose ("Failed to create socket \"%s:%d\": %s\n",
+                     host, port, _dbus_strerror (errno));
+      return -1;
+    }
+
+  if (host == NULL)
+    host = "localhost";
+  
+  he = gethostbyname (host);
+  if (he == NULL) 
+    {
+      dbus_set_result (result,
+                       _dbus_result_from_errno (errno));
+      _dbus_verbose ("Failed to lookup hostname: %s\n",
+                     host);
+      return -1;
+    }
+  
+  haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+
+  _DBUS_ZERO (addr);
+  memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons (port);
+
+  if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
+    {
+      dbus_set_result (result, _dbus_result_from_errno (errno));
+      _dbus_verbose ("Failed to bind socket \"%s:%d\": %s\n",
+                     host, port, _dbus_strerror (errno));
+      close (listen_fd);
+      return -1;
+    }
+
+  if (listen (listen_fd, 30 /* backlog */) < 0)
+    {
+      dbus_set_result (result, _dbus_result_from_errno (errno));      
+      _dbus_verbose ("Failed to listen on socket \"%s:%d\": %s\n",
+                     host, port, _dbus_strerror (errno));
+      close (listen_fd);
+      return -1;
+    }
+
+  if (!_dbus_set_fd_nonblocking (listen_fd, result))
+    {
+      close (listen_fd);
+      return -1;
+    }
+  
+  return listen_fd;
+}
+
 /* try to read a single byte and return #TRUE if we read it
  * and it's equal to nul.
  */
index 50da679..3c95227 100644 (file)
@@ -79,6 +79,12 @@ int _dbus_connect_unix_socket (const char     *path,
                                DBusResultCode *result);
 int _dbus_listen_unix_socket  (const char     *path,
                                DBusResultCode *result);
+int _dbus_connect_tcp_socket  (const char     *host,
+                               dbus_uint32_t   port,
+                               DBusResultCode *result);
+int _dbus_listen_tcp_socket   (const char     *host,
+                               dbus_uint32_t   port,
+                               DBusResultCode *result);
 int _dbus_accept              (int             listen_fd);
 
 dbus_bool_t _dbus_read_credentials_unix_socket (int              client_fd,
index 8470334..c5dce8d 100644 (file)
@@ -1118,6 +1118,43 @@ _dbus_transport_new_for_domain_socket (const char     *path,
   return transport;
 }
 
+/**
+ * Creates a new transport for the given hostname and port.
+ *
+ * @param host the host to connect to
+ * @param port the port to connect to
+ * @param server #TRUE if this transport is on the server side of a connection
+ * @param result location to store reason for failure.
+ * @returns a new transport, or #NULL on failure.
+ */
+DBusTransport*
+_dbus_transport_new_for_tcp_socket (const char     *host,
+                                    dbus_int32_t    port,
+                                    dbus_bool_t     server,
+                                    DBusResultCode *result)
+{
+  int fd;
+  DBusTransport *transport;
+  
+  fd = _dbus_connect_tcp_socket (host, port, result);
+  if (fd < 0)
+    return NULL;
+
+  _dbus_fd_set_close_on_exec (fd);
+  
+  _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
+                 host, port);
+  
+  transport = _dbus_transport_new_for_fd (fd, server);
+  if (transport == NULL)
+    {
+      dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
+      close (fd);
+      fd = -1;
+    }
+
+  return transport;
+}
 
 /** @} */
 
index 0c7d04f..1fd0134 100644 (file)
@@ -32,7 +32,10 @@ DBusTransport* _dbus_transport_new_for_fd            (int             fd,
 DBusTransport* _dbus_transport_new_for_domain_socket (const char     *path,
                                                       dbus_bool_t     server,
                                                       DBusResultCode *result);
-
+DBusTransport* _dbus_transport_new_for_tcp_socket    (const char     *host,
+                                                      dbus_int32_t    port,
+                                                      dbus_bool_t     server,
+                                                      DBusResultCode *result);
 
 DBUS_END_DECLS;
 
index 5a25a67..1f34b3b 100644 (file)
@@ -199,6 +199,35 @@ _dbus_transport_open (const char     *address,
 
          transport = _dbus_transport_new_for_domain_socket (path, FALSE, result);
        }
+      else if (strcmp (method, "tcp") == 0)
+       {
+         const char *host = dbus_address_entry_get_value (entries[i], "host");
+          const char *port = dbus_address_entry_get_value (entries[i], "port");
+          DBusString  str;
+          long lport;
+          dbus_bool_t sresult;
+          
+         if (port == NULL)
+           goto bad_address;
+
+          _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)
+            goto bad_address;
+          
+         transport = _dbus_transport_new_for_tcp_socket (host, lport, FALSE, result);
+       }
+      else if (strcmp (method, "tcp") == 0)
+       {
+         const char *path = dbus_address_entry_get_value (entries[i], "path");
+
+         if (path == NULL)
+           goto bad_address;
+
+         transport = _dbus_transport_new_for_domain_socket (path, FALSE, result);
+       }
 #ifdef DBUS_BUILD_TESTS
       else if (strcmp (method, "debug") == 0)
        {