You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by jk...@apache.org on 2019/07/02 00:12:01 UTC

[thrift] branch master updated: THRIFT-4878 - [c_glib] add unix domain socket support to ThriftSocket (#1807)

This is an automated email from the ASF dual-hosted git repository.

jking pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c847d2  THRIFT-4878 - [c_glib] add unix domain socket support to ThriftSocket (#1807)
6c847d2 is described below

commit 6c847d2d028c155534aee006a77a5dca783233c4
Author: Kevin Wojniak <ka...@users.noreply.github.com>
AuthorDate: Mon Jul 1 17:11:56 2019 -0700

    THRIFT-4878 - [c_glib] add unix domain socket support to ThriftSocket (#1807)
---
 .../thrift/c_glib/transport/thrift_server_socket.c | 90 +++++++++++++++++-----
 .../thrift/c_glib/transport/thrift_server_socket.h |  1 +
 .../src/thrift/c_glib/transport/thrift_socket.c    | 55 ++++++++++++-
 .../src/thrift/c_glib/transport/thrift_socket.h    |  1 +
 test/c_glib/src/test_client.c                      | 43 ++++++++---
 test/c_glib/src/test_server.c                      | 33 ++++++--
 test/tests.json                                    |  3 +-
 7 files changed, 187 insertions(+), 39 deletions(-)

diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
index 6ea897c..1646374 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/in.h>
 
 #include <thrift/c_glib/thrift.h>
@@ -36,6 +37,7 @@ enum _ThriftServerSocketProperties
 {
   PROP_0,
   PROP_THRIFT_SERVER_SOCKET_PORT,
+  PROP_THRIFT_SERVER_SOCKET_PATH,
   PROP_THRIFT_SERVER_SOCKET_BACKLOG
 };
 
@@ -48,17 +50,12 @@ gboolean
 thrift_server_socket_listen (ThriftServerTransport *transport, GError **error)
 {
   int enabled = 1; /* for setsockopt() */
-  struct sockaddr_in pin;
   ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
 
-  /* create a address structure */
-  memset (&pin, 0, sizeof(pin));
-  pin.sin_family = AF_INET;
-  pin.sin_addr.s_addr = INADDR_ANY;
-  pin.sin_port = htons(tsocket->port);
+  const int socket_domain = tsocket->path ? PF_UNIX : AF_INET;
 
   /* create a socket */
-  if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
+  if ((tsocket->sd = socket (socket_domain, SOCK_STREAM, 0)) == -1)
   {
     g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
                  THRIFT_SERVER_SOCKET_ERROR_SOCKET,
@@ -76,22 +73,60 @@ thrift_server_socket_listen (ThriftServerTransport *transport, GError **error)
   }
 
   /* bind to the socket */
-  if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+  if (tsocket->path)
   {
-    g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
-                 THRIFT_SERVER_SOCKET_ERROR_BIND,
-                 "failed to bind to port %d - %s",
-                 tsocket->port, strerror(errno));
-    return FALSE;
+    /* create a socket structure */
+    struct sockaddr_un pin;
+    memset (&pin, 0, sizeof(pin));
+    pin.sun_family = AF_UNIX;
+    memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1);
+
+    if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+    {
+      g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+                   THRIFT_SERVER_SOCKET_ERROR_BIND,
+                   "failed to bind to path %s",
+                   tsocket->path, strerror(errno));
+      return FALSE;
+    }
+  }
+  else
+  {
+    /* create a address structure */
+    struct sockaddr_in pin;
+    memset (&pin, 0, sizeof(pin));
+    pin.sin_family = AF_INET;
+    pin.sin_addr.s_addr = INADDR_ANY;
+    pin.sin_port = htons(tsocket->port);
+
+    if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+    {
+      g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+                   THRIFT_SERVER_SOCKET_ERROR_BIND,
+                   "failed to bind to port %d - %s",
+                   tsocket->port, strerror(errno));
+      return FALSE;
+    }
   }
 
   if (listen(tsocket->sd, tsocket->backlog) == -1)
   {
-    g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
-                 THRIFT_SERVER_SOCKET_ERROR_LISTEN,
-                 "failed to listen to port %d - %s",
-                 tsocket->port, strerror(errno));
-    return FALSE;
+    if (tsocket->path)
+    {
+      g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+                   THRIFT_SERVER_SOCKET_ERROR_BIND,
+                   "failed to bind to path %s",
+                   tsocket->path, strerror(errno));
+      return FALSE;
+    }
+    else
+    {
+      g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
+                   THRIFT_SERVER_SOCKET_ERROR_LISTEN,
+                   "failed to listen to port %d - %s",
+                   tsocket->port, strerror(errno));
+      return FALSE;
+    }
   }
 
   return TRUE;
@@ -178,6 +213,9 @@ thrift_server_socket_get_property (GObject *object, guint property_id,
     case PROP_THRIFT_SERVER_SOCKET_PORT:
       g_value_set_uint (value, socket->port);
       break;
+    case PROP_THRIFT_SERVER_SOCKET_PATH:
+      g_value_set_string (value, socket->path);
+      break;
     case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
       g_value_set_uint (value, socket->backlog);
       break;
@@ -199,6 +237,12 @@ thrift_server_socket_set_property (GObject *object, guint property_id,
     case PROP_THRIFT_SERVER_SOCKET_PORT:
       socket->port = g_value_get_uint (value);
       break;
+    case PROP_THRIFT_SERVER_SOCKET_PATH:
+      if (socket->path) {
+        g_free(socket->path);
+      }
+      socket->path = g_strdup (g_value_get_string (value));
+      break;
     case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
       socket->backlog = g_value_get_uint (value);
       break;
@@ -232,6 +276,16 @@ thrift_server_socket_class_init (ThriftServerSocketClass *cls)
                                    PROP_THRIFT_SERVER_SOCKET_PORT,
                                    param_spec);
 
+  param_spec = g_param_spec_string ("path",
+                                    "path (construct)",
+                                    "Set the path to listen to",
+                                    NULL, /* default value */
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_SERVER_SOCKET_PATH,
+                                   param_spec);
+
   param_spec = g_param_spec_uint ("backlog",
                                   "backlog (construct)",
                                   "Set the accept backlog",
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h
index fd04954..7710d51 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h
@@ -50,6 +50,7 @@ struct _ThriftServerSocket
 
   /* private */
   guint port;
+  gchar *path;
   gshort backlog;
   int sd;
   guint8 *buf;
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
index 560c24e..b7b4139 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/in.h>
 
 #include <thrift/c_glib/thrift.h>
@@ -34,7 +35,8 @@ enum _ThriftSocketProperties
 {
   PROP_0,
   PROP_THRIFT_SOCKET_HOSTNAME,
-  PROP_THRIFT_SOCKET_PORT
+  PROP_THRIFT_SOCKET_PORT,
+  PROP_THRIFT_SOCKET_PATH
 };
 
 G_DEFINE_TYPE(ThriftSocket, thrift_socket, THRIFT_TYPE_TRANSPORT)
@@ -128,6 +130,35 @@ thrift_socket_open (ThriftTransport *transport, GError **error)
 
   ThriftSocket *tsocket = THRIFT_SOCKET (transport);
   g_return_val_if_fail (tsocket->sd == THRIFT_INVALID_SOCKET, FALSE);
+  
+  if (tsocket->path) {
+    /* create a socket structure */
+    struct sockaddr_un pin;
+    memset (&pin, 0, sizeof(pin));
+    pin.sun_family = AF_UNIX;
+    memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1);
+
+    /* create the socket */
+    if ((tsocket->sd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
+    {
+      g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET,
+                   "failed to create socket for path %s: - %s",
+                   tsocket->path,
+                   strerror(errno));
+      return FALSE;
+    }
+
+    /* open a connection */
+    if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
+    {
+        thrift_socket_close(tsocket, NULL);
+        g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
+                   "failed to connect to path %s: - %s",
+                   tsocket->path, strerror(errno));
+      return FALSE;
+    }
+    return TRUE;
+  }
 
   /* lookup the destination host */
 #if defined(HAVE_GETHOSTBYNAME_R)
@@ -278,6 +309,10 @@ thrift_socket_finalize (GObject *object)
     g_free (socket->hostname);
   }
   socket->hostname = NULL;
+  if (socket->path != NULL)
+  {
+    g_free (socket->path);
+  }
 
   if (socket->sd != THRIFT_INVALID_SOCKET)
   {
@@ -303,6 +338,9 @@ thrift_socket_get_property (GObject *object, guint property_id,
     case PROP_THRIFT_SOCKET_PORT:
       g_value_set_uint (value, socket->port);
       break;
+    case PROP_THRIFT_SOCKET_PATH:
+      g_value_set_string (value, socket->path);
+      break;
   }
 }
 
@@ -326,6 +364,12 @@ thrift_socket_set_property (GObject *object, guint property_id,
     case PROP_THRIFT_SOCKET_PORT:
       socket->port = g_value_get_uint (value);
       break;
+    case PROP_THRIFT_SOCKET_PATH:
+      if (socket->path) {
+        g_free(socket->path);
+      }
+      socket->path = g_strdup (g_value_get_string (value));
+      break;
   }
 }
 
@@ -361,6 +405,15 @@ thrift_socket_class_init (ThriftSocketClass *cls)
   g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PORT,
                                    param_spec);
 
+  param_spec = g_param_spec_string ("path",
+                                    "path (construct)",
+                                    "Set the path of the remote host",
+                                    NULL, /* default value */
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PATH,
+                                   param_spec);
+
   gobject_class->finalize = thrift_socket_finalize;
   ttc->is_open = thrift_socket_is_open;
   ttc->peek = thrift_socket_peek;
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
index 2f6f67d..c91f52f 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
@@ -51,6 +51,7 @@ struct _ThriftSocket
   /* private */
   gchar *hostname;
   guint port;
+  gchar *path;
   int sd;
 };
 
diff --git a/test/c_glib/src/test_client.c b/test/c_glib/src/test_client.c
index ef24ab7..7126a86 100644
--- a/test/c_glib/src/test_client.c
+++ b/test/c_glib/src/test_client.c
@@ -113,6 +113,7 @@ main (int argc, char **argv)
 {
   static gchar *  host = NULL;
   static gint     port = 9090;
+  static gchar *  path = NULL;
   static gboolean ssl  = FALSE;
   static gchar *  transport_option = NULL;
   static gchar *  protocol_option = NULL;
@@ -124,6 +125,8 @@ main (int argc, char **argv)
       "Host to connect (=localhost)", NULL },
     { "port",            'p', 0, G_OPTION_ARG_INT,      &port,
       "Port number to connect (=9090)", NULL },
+    { "domain-socket",    0, 0, G_OPTION_ARG_STRING,   &path,
+      "Unix socket domain path to connect", NULL },
     { "ssl",             's', 0, G_OPTION_ARG_NONE,     &ssl,
       "Enable SSL", NULL },
     { "transport",       't', 0, G_OPTION_ARG_STRING,   &transport_option,
@@ -227,12 +230,20 @@ main (int argc, char **argv)
   if (!options_valid)
     return 254;
 
-  printf ("Connecting (%s/%s) to: %s/%s:%d\n",
-          transport_name,
-          protocol_name,
-          socket_name,
-          host,
-          port);
+  if (path) {
+    printf ("Connecting (%s/%s) to: %s/%s\n",
+            transport_name,
+            protocol_name,
+            socket_name,
+            path);
+  } else {
+    printf ("Connecting (%s/%s) to: %s/%s:%d\n",
+            transport_name,
+            protocol_name,
+            socket_name,
+            host,
+            port);
+  }
 
   /* Install our SIGPIPE handler, which outputs an error message to
      standard error before exiting so testers can know what
@@ -247,10 +258,16 @@ main (int argc, char **argv)
   }
 
   /* Establish all our connection objects */
-  socket = g_object_new (socket_type,
-                         "hostname", host,
-                         "port",     port,
-                         NULL);
+  if (path) {
+    socket = g_object_new (socket_type,
+                           "path", path,
+                           NULL);
+  } else {
+    socket = g_object_new (socket_type,
+                           "hostname", host,
+                           "port",     port,
+                           NULL);
+  }
 
   if (ssl && !thrift_ssl_load_cert_from_file(THRIFT_SSL_SOCKET(socket), "../keys/CA.pem")) {
     fprintf(stderr, "Unable to load validation certificate ../keys/CA.pem - did you run in the test/c_glib directory?\n");
@@ -336,7 +353,11 @@ main (int argc, char **argv)
       gboolean first;
       gint32 i, j;
 
-      printf ("Test #%d, connect %s:%d\n", test_num + 1, host, port);
+      if (path) {
+        printf ("Test #%d, connect %s\n", test_num + 1, path);
+      } else {
+        printf ("Test #%d, connect %s:%d\n", test_num + 1, host, port);
+      }
       gettimeofday (&time_start, NULL);
 
       /* These test routines have been ported from the C++ test
diff --git a/test/c_glib/src/test_server.c b/test/c_glib/src/test_server.c
index 2d716ec..0819b8c 100644
--- a/test/c_glib/src/test_server.c
+++ b/test/c_glib/src/test_server.c
@@ -69,6 +69,7 @@ int
 main (int argc, char **argv)
 {
   static gint   port = 9090;
+  static gchar *path_option = NULL;
   static gchar *server_type_option = NULL;
   static gchar *transport_option = NULL;
   static gchar *protocol_option = NULL;
@@ -79,6 +80,8 @@ main (int argc, char **argv)
     GOptionEntry option_entries[] = {
     { "port",            0, 0, G_OPTION_ARG_INT,      &port,
       "Port number to connect (=9090)", NULL },
+    { "domain-socket",   0, 0, G_OPTION_ARG_STRING,   &path_option,
+      "Unix socket domain path to connect", NULL },
     { "server-type",     0, 0, G_OPTION_ARG_STRING,   &server_type_option,
       "Type of server: simple (=simple)", NULL },
     { "transport",       0, 0, G_OPTION_ARG_STRING,   &transport_option,
@@ -218,9 +221,15 @@ main (int argc, char **argv)
                                         "handler", handler,
                                         NULL);
   }
-  server_transport  = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
-                                    "port", port,
-                                    NULL);
+  if (path_option) {
+    server_transport  = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+                                      "path", path_option,
+                                      NULL);
+  } else {
+    server_transport  = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+                                      "port", port,
+                                      NULL);
+  }
   transport_factory = g_object_new (transport_factory_type,
                                     NULL);
 
@@ -250,11 +259,19 @@ main (int argc, char **argv)
   sigint_action.sa_flags = SA_RESETHAND;
   sigaction (SIGINT, &sigint_action, NULL);
 
-  printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
-          server_name,
-          transport_name,
-          protocol_name,
-          port);
+  if (path_option) {
+    printf ("Starting \"%s\" server (%s/%s) listen on: %s\n",
+            server_name,
+            transport_name,
+            protocol_name,
+            path_option);
+  } else {
+    printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
+            server_name,
+            transport_name,
+            protocol_name,
+            port);
+  }
   fflush (stdout);
 
   /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
diff --git a/test/tests.json b/test/tests.json
index 851244e..6a41639 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -32,7 +32,8 @@
       "framed"
     ],
     "sockets": [
-      "ip"
+      "ip",
+      "domain"
     ],
     "protocols": [
       "binary",