gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r27673 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r27673 - gnunet/src/transport
Date: Fri, 28 Jun 2013 14:32:52 +0200

Author: wachs
Date: 2013-06-28 14:32:52 +0200 (Fri, 28 Jun 2013)
New Revision: 27673

Modified:
   gnunet/src/transport/plugin_transport_unix.c
Log:
options support for unix


Modified: gnunet/src/transport/plugin_transport_unix.c
===================================================================
--- gnunet/src/transport/plugin_transport_unix.c        2013-06-28 12:07:11 UTC 
(rev 27672)
+++ gnunet/src/transport/plugin_transport_unix.c        2013-06-28 12:32:52 UTC 
(rev 27673)
@@ -43,6 +43,8 @@
  */
 #define RETRY 0
 
+#define PLUGIN_NAME "unix"
+
 /**
  * How long until we give up on transmitting the welcome message?
  */
@@ -60,6 +62,14 @@
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
+struct UnixAddress
+{
+       uint32_t options GNUNET_PACKED;
+
+       uint32_t addrlen GNUNET_PACKED;
+};
+
+
 /**
  * UNIX Message-Packet header.
  */
@@ -77,8 +87,14 @@
 
 };
 
+GNUNET_NETWORK_STRUCT_END
 
 /**
+ * Address options
+ */
+static uint32_t myoptions;
+
+/**
  * Handle for a session.
  */
 struct Session
@@ -87,7 +103,7 @@
 
   struct Plugin * plugin;
 
-  void *addr;
+  struct UnixAddress *addr;
 
   size_t addrlen;
 
@@ -330,6 +346,19 @@
 static void
 unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
 
+/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address.  Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addrlen length of the address
+ * @return string representing the same address
+ */
+static const char *
+unix_address_to_string (void *cls, const void *addr, size_t addrlen);
 
 /**
  * Re-schedule the main 'select' callback (unix_plugin_select)
@@ -381,7 +410,9 @@
   /**
    * Address we are looking for.
    */
-  const struct sockaddr_un *addr;
+  const struct UnixAddress *ua;
+
+  size_t ua_len;
 };
 
 
@@ -401,7 +432,10 @@
   struct LookupCtx *lctx = cls;
   struct Session *t = value;
 
-  if (0 == strcmp (t->addr, lctx->addr->sun_path))
+  if (t->addrlen != lctx->ua_len)
+    return GNUNET_YES;
+
+  if (0 == memcmp (&t->addr, lctx->ua, lctx->ua_len))
   {
     lctx->s = t;
     return GNUNET_NO;
@@ -421,15 +455,16 @@
 static struct Session *
 lookup_session (struct Plugin *plugin, 
                const struct GNUNET_PeerIdentity *sender, 
-               const struct sockaddr_un *addr)
+               const struct UnixAddress *ua, size_t ua_len)
 {
   struct LookupCtx lctx;
 
   GNUNET_assert (NULL != plugin);
   GNUNET_assert (NULL != sender);
-  GNUNET_assert (NULL != addr);
+  GNUNET_assert (NULL != ua);
   lctx.s = NULL;
-  lctx.addr = addr;
+  lctx.ua = ua;
+  lctx.ua_len = ua_len;
   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, 
                                              &sender->hashPubKey,
                                              &lookup_session_it, &lctx);
@@ -519,7 +554,7 @@
                 const struct GNUNET_PeerIdentity *target, const char *msgbuf,
                 size_t msgbuf_size, unsigned int priority,
                 struct GNUNET_TIME_Absolute timeout,
-                const void *addr,
+                const struct UnixAddress *addr,
                 size_t addrlen,
                 size_t payload,
                 GNUNET_TRANSPORT_TransmitContinuation cont,
@@ -531,7 +566,9 @@
   size_t sbs;
   struct sockaddr_un un;
   size_t slen;
+  const char *unix_path;
 
+
   GNUNET_assert (NULL != plugin);
   if (NULL == send_handle)
   {
@@ -545,13 +582,14 @@
   }
 
   /* Prepare address */
+  unix_path = (const char *)  &addr[1];
   memset (&un, 0, sizeof (un));
   un.sun_family = AF_UNIX;
-  slen = strlen (addr) + 1;
+  slen =  strlen (unix_path);
   if (slen >= sizeof (un.sun_path))
     slen = sizeof (un.sun_path) - 1;
   GNUNET_assert (slen < sizeof (un.sun_path));
-  memcpy (un.sun_path, addr, slen);
+  memcpy (un.sun_path, unix_path, slen);
   un.sun_path[slen] = '\0';
   slen = sizeof (struct sockaddr_un);
 #if LINUX
@@ -703,10 +741,39 @@
   struct Plugin *plugin = cls;
   struct Session *s;
   struct GetSessionIteratorContext gsi;
+  struct UnixAddress *ua;
+  char * addrstr;
+  uint32_t addr_str_len;
 
   GNUNET_assert (NULL != plugin);
   GNUNET_assert (NULL != address);
 
+  ua = (struct UnixAddress *) address->address;
+  if ((NULL == address->address) || (0 == address->address_length) ||
+               (sizeof (struct UnixAddress) > address->address_length))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+       addrstr = (char *) &ua[1];
+       addr_str_len = ntohl (ua->addrlen);
+       if (addr_str_len != address->address_length - sizeof (struct 
UnixAddress *))
+  {
+               /* This can be a legacy address */
+    return NULL;
+  }
+
+  if ('\0' != addrstr[addr_str_len - 1])
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  if (strlen (addrstr) + 1 != addr_str_len)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+
   /* Check if already existing */
   gsi.address = (const char *) address->address;
   gsi.addrlen = address->address_length;
@@ -723,21 +790,18 @@
 
   /* create a new session */
   s = GNUNET_malloc (sizeof (struct Session) + address->address_length);
-  s->addr = &s[1];
+  s->addr = (struct UnixAddress *) &s[1];
   s->addrlen = address->address_length;
   s->plugin = plugin;
-  memcpy (s->addr, address->address, s->addrlen);
+  memcpy (s->addr, address->address, address->address_length);
   memcpy (&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity));
-
   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task);
   s->timeout_task = GNUNET_SCHEDULER_add_delayed 
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                                  &session_timeout,
                                                  s);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Creating a new session %p with timeout set to %s\n",
-       s,  
-       GNUNET_STRINGS_relative_time_to_string 
(GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
-                                              GNUNET_YES));
+       "Creating a new session %p for address `%s'\n",
+       s,  unix_address_to_string (NULL, address->address, 
address->address_length));
   (void) GNUNET_CONTAINER_multihashmap_put (plugin->session_map,
                                            &address->peer.hashPubKey, s,
                                            
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -852,18 +916,18 @@
 static void
 unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
                     const struct GNUNET_MessageHeader *currhdr,
-                    const struct sockaddr_un *un, size_t fromlen)
+                    const struct UnixAddress *ua, size_t ua_len)
 {
   struct Session *s = NULL;
   struct GNUNET_HELLO_Address * addr;
 
   GNUNET_break (ntohl(plugin->ats_network.value) != 
GNUNET_ATS_NET_UNSPECIFIED);
 
-  GNUNET_assert (fromlen >= sizeof (struct sockaddr_un));
+  GNUNET_assert (ua_len >= sizeof (struct UnixAddress));
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, 
        "Received message from %s\n",
-       un->sun_path);
+       unix_address_to_string(NULL, ua, ua_len));
   GNUNET_STATISTICS_update (plugin->env->stats,
                            "# bytes received via UNIX",
                            ntohs (currhdr->size),
@@ -871,20 +935,19 @@
 
   addr = GNUNET_HELLO_address_allocate (sender,
                                        "unix",
-                                       un->sun_path, 
-                                       strlen (un->sun_path) + 1);
-  s = lookup_session (plugin, sender, un);
+                                       ua,
+                                       ua_len);
+  s = lookup_session (plugin, sender, ua, ua_len);
   if (NULL == s)
     s = unix_plugin_get_session (plugin, addr);
   reschedule_session_timeout (s);
 
   plugin->env->receive (plugin->env->cls, sender, currhdr,
-                        s, un->sun_path, strlen (un->sun_path) + 1);
+                        s, (const char *) ua, ua_len);
 
   plugin->env->update_address_metrics (plugin->env->cls,
                                       sender,
-                                      un->sun_path,
-                                      strlen (un->sun_path) + 1,
+                                      (const char *) ua, ua_len,
                                       s,
                                       &plugin->ats_network, 1);
 
@@ -901,6 +964,7 @@
 unix_plugin_select_read (struct Plugin *plugin)
 {
   char buf[65536] GNUNET_ALIGN;
+  struct UnixAddress *ua;
   struct UNIXMessage *msg;
   struct GNUNET_PeerIdentity sender;
   struct sockaddr_un un;
@@ -911,6 +975,7 @@
   char *msgbuf;
   const struct GNUNET_MessageHeader *currhdr;
   uint16_t csize;
+  size_t ua_len;
 
   addrlen = sizeof (un);
   memset (&un, 0, sizeof (un));
@@ -937,6 +1002,11 @@
   }
 
   GNUNET_assert (AF_UNIX == (un.sun_family));
+  ua_len = sizeof (struct UnixAddress) + strlen (&un.sun_path[0]) +1;
+  ua = GNUNET_malloc (ua_len);
+  ua->addrlen = htonl (strlen (&un.sun_path[0]) +1);
+  ua->options = htonl (0);
+  memcpy (&ua[1], &un.sun_path[0], strlen (&un.sun_path[0]) +1);
 
   msg = (struct UNIXMessage *) buf;
   csize = ntohs (msg->header.size);
@@ -959,9 +1029,10 @@
       GNUNET_break_op (0);
       break;
     }
-    unix_demultiplexer (plugin, &sender, currhdr, &un, sizeof (un));
+    unix_demultiplexer (plugin, &sender, currhdr, ua, ua_len);
     offset += csize;
   }
+  GNUNET_free (ua);
 }
 
 
@@ -1173,6 +1244,57 @@
 
 
 /**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address.  Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addrlen length of the address
+ * @return string representing the same address
+ */
+static const char *
+unix_address_to_string (void *cls, const void *addr, size_t addrlen)
+{
+  static char rbuf[1024];
+       struct UnixAddress *ua = (struct UnixAddress *) addr;
+       char *addrstr;
+       char *tmp;
+       size_t addr_str_len;
+
+  if ((NULL == addr) || (0 == addrlen) || (sizeof (struct UnixAddress) > 
addrlen))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+       addrstr = (char *) &ua[1];
+       addr_str_len = ntohl (ua->addrlen);
+
+       if (addr_str_len != addrlen - sizeof (struct UnixAddress *))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  if ('\0' != addrstr[addr_str_len - 1])
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  if (strlen (addrstr) + 1 != addr_str_len)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  GNUNET_asprintf(&tmp, "%s.%u.%s", PLUGIN_NAME, ntohl (ua->options), addrstr);
+  memcpy (rbuf, tmp, strlen (tmp) + 1);
+  GNUNET_free (tmp);
+  return rbuf;
+}
+
+/**
  * Function that will be called to check if a binary address for this
  * plugin is well-formed and corresponds to an address for THIS peer
  * (as per our configuration).  Naturally, if absolutely necessary,
@@ -1191,10 +1313,32 @@
 static int
 unix_check_address (void *cls, const void *addr, size_t addrlen)
 {
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-              "Informing transport service about my address `%s'\n",
-              (char *) addr);
-  return GNUNET_OK;
+       struct Plugin* plugin = cls;
+       struct UnixAddress *ua = (struct UnixAddress *) addr;
+       char *addrstr;
+       size_t addr_str_len;
+
+  if ((NULL == addr) || (0 == addrlen) || (sizeof (struct UnixAddress) > 
addrlen))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+       addrstr = (char *) &ua[1];
+       addr_str_len = ntohl (ua->addrlen);
+  if ('\0' != addrstr[addr_str_len - 1])
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (strlen (addrstr) + 1 != addr_str_len)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+
+  if (0 == strcmp (plugin->unix_socket_path, addrstr))
+       return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 
@@ -1222,7 +1366,7 @@
 {
   if ((NULL != addr) && (addrlen > 0))
   {
-    asc (asc_cls, (const char *) addr);
+    asc (asc_cls, unix_address_to_string (NULL, addr, addrlen));
   }
   else
   {
@@ -1249,51 +1393,74 @@
 unix_string_to_address (void *cls, const char *addr, uint16_t addrlen,
     void **buf, size_t *added)
 {
-  if ((NULL == addr) || (0 == addrlen))
+       struct UnixAddress *ua;
+  char *address;
+  char *plugin;
+  char *optionstr;
+  uint32_t options;
+  size_t ua_size;
+
+  /* Format unix.options.address */
+  address = NULL;
+  plugin = NULL;
+  optionstr = NULL;
+  options = 0;
+  if ((NULL == addr) || (addrlen == 0))
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-
   if ('\0' != addr[addrlen - 1])
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-
   if (strlen (addr) != addrlen - 1)
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
+  plugin = GNUNET_strdup (addr);
+  optionstr = strchr (plugin, '.');
+  if (NULL == optionstr)
+  {
+    GNUNET_break (0);
+    GNUNET_free (plugin);
+    return GNUNET_SYSERR;
+  }
+  optionstr[0] = '\0';
+  optionstr ++;
+  options = atol (optionstr);
+  address = strchr (optionstr, '.');
+  if (NULL == address)
+  {
+    GNUNET_break (0);
+    GNUNET_free (plugin);
+    return GNUNET_SYSERR;
+  }
+  address[0] = '\0';
+  address ++;
+  if (0 != strcmp(plugin, PLUGIN_NAME))
+  {
+    GNUNET_break (0);
+    GNUNET_free (plugin);
+    return GNUNET_SYSERR;
+  }
 
-  (*buf) = strdup (addr);
-  (*added) = strlen (addr) + 1;
+  ua_size = sizeof (struct UnixAddress) + strlen (address) + 1;
+  ua = GNUNET_malloc (ua_size);
+  ua->options = htonl (options);
+  ua->addrlen = htonl (strlen (address) + 1);
+  memcpy (&ua[1], address, strlen (address) + 1);
+  GNUNET_free (plugin);
+
+  (*buf) = ua;
+  (*added) = ua_size;
   return GNUNET_OK;
 }
 
 
 /**
- * Function called for a quick conversion of the binary address to
- * a numeric address.  Note that the caller must not free the
- * address and that the next call to this function is allowed
- * to override the address again.
- *
- * @param cls closure
- * @param addr binary address
- * @param addrlen length of the address
- * @return string representing the same address
- */
-static const char *
-unix_address_to_string (void *cls, const void *addr, size_t addrlen)
-{
-  if ((addr != NULL) && (addrlen > 0))
-    return (const char *) addr;
-  return NULL;
-}
-
-
-/**
  * Notify transport service about address
  *
  * @param cls the plugin
@@ -1304,12 +1471,19 @@
                      const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct Plugin *plugin = cls;
+  size_t len;
+  struct UnixAddress *ua;
 
+  len = sizeof (struct UnixAddress) + strlen (plugin->unix_socket_path) + 1;
+  ua = GNUNET_malloc (len);
+  ua->options = htonl (myoptions);
+  ua->addrlen = htonl(strlen (plugin->unix_socket_path) + 1);
+  memcpy (&ua[1], plugin->unix_socket_path, strlen (plugin->unix_socket_path) 
+ 1);
+
   plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
   plugin->env->notify_address (plugin->env->cls, GNUNET_YES,
-                               plugin->unix_socket_path,
-                               strlen (plugin->unix_socket_path) + 1,
-                               "unix");
+                               ua, len, "unix");
+  GNUNET_free (ua);
 }
 
 
@@ -1411,6 +1585,9 @@
                   "/tmp/unix-plugin-sock.%d",
                    plugin->port);
 
+  /* Initialize my flags */
+  myoptions = 0;
+
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
 
@@ -1443,16 +1620,24 @@
   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
   struct Plugin *plugin = api->cls;
   struct UNIXMessageWrapper * msgw;
+  struct UnixAddress *ua;
+  size_t len;
 
   if (NULL == plugin)
   {
     GNUNET_free (api);
     return NULL;
   }
+
+  len = sizeof (struct UnixAddress) + strlen (plugin->unix_socket_path) + 1;
+  ua = GNUNET_malloc (len);
+  ua->options = htonl (myoptions);
+  ua->addrlen = htonl(strlen (plugin->unix_socket_path) + 1);
+  memcpy (&ua[1], plugin->unix_socket_path, strlen (plugin->unix_socket_path) 
+ 1);
+
   plugin->env->notify_address (plugin->env->cls, GNUNET_NO,
-                               plugin->unix_socket_path,
-                               strlen (plugin->unix_socket_path) + 1,
-                               "unix");
+                                                                               
                                 ua, len, "unix");
+  GNUNET_free (ua);
   while (NULL != (msgw = plugin->msg_head))
   {
     GNUNET_CONTAINER_DLL_remove (plugin->msg_head, plugin->msg_tail, msgw);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]