gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r11148 - gnunet/src/transport
Date: Sun, 2 May 2010 13:48:52 +0200

Author: grothoff
Date: 2010-05-02 13:48:52 +0200 (Sun, 02 May 2010)
New Revision: 11148

Modified:
   gnunet/src/transport/gnunet-service-transport.c
   gnunet/src/transport/plugin_transport.h
   gnunet/src/transport/plugin_transport_tcp.c
   gnunet/src/transport/plugin_transport_template.c
   gnunet/src/transport/plugin_transport_udp.c
   gnunet/src/transport/test_plugin_transport_http.c
Log:
fixing major issue with how IP addresses go over the network (previously 
ill-defined) -- thanks amatus

Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c     2010-05-01 12:17:38 UTC 
(rev 11147)
+++ gnunet/src/transport/gnunet-service-transport.c     2010-05-02 11:48:52 UTC 
(rev 11148)
@@ -45,9 +45,9 @@
 #include "plugin_transport.h"
 #include "transport.h"
 
-#define DEBUG_BLACKLIST GNUNET_NO
+#define DEBUG_BLACKLIST GNUNET_YES
 
-#define DEBUG_PING_PONG GNUNET_NO
+#define DEBUG_PING_PONG GNUNET_YES
 
 /**
  * Should we do some additional checks (to validate behavior
@@ -1393,6 +1393,32 @@
 
 
 /**
+ * Convert an address to a string.
+ *
+ * @param plugin name of the plugin responsible for the address
+ * @param addr binary address
+ * @param addr_len number of bytes in addr
+ * @return NULL on error, otherwise address string
+ */
+static const char*
+a2s (const char *plugin,
+     const void *addr,
+     size_t addr_len)
+{
+  struct TransportPlugin *p;
+
+  if (plugin == NULL)
+    return NULL;
+  p = find_transport (plugin);
+  if (p == NULL)
+    return NULL;
+  return p->api->address_to_string (p->api->cls,
+                                   addr,
+                                   addr_len);
+}   
+
+
+/**
  * Find an address in any of the available transports for
  * the given neighbour that would be good for message
  * transmission.  This is essentially the transport selection
@@ -1439,8 +1465,9 @@
          if (addresses->addr != NULL)
            GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                        "Have address `%s' for peer `%4s' (status: %d, %d, %d, 
%u, %llums, %u)\n",
-                       GNUNET_a2s (addresses->addr,
-                                   addresses->addrlen),
+                       a2s (head->plugin->short_name,
+                            addresses->addr,
+                            addresses->addrlen),
                        GNUNET_i2s (&neighbour->id),
                        addresses->connected,
                        addresses->in_transmit,
@@ -1601,8 +1628,9 @@
               mq->message_buf_size,
               GNUNET_i2s (&neighbour->id), 
              (mq->specific_address->addr != NULL)
-             ? GNUNET_a2s (mq->specific_address->addr,
-                           mq->specific_address->addrlen)
+             ? a2s (mq->specific_address->plugin->short_name,
+                    mq->specific_address->addr,
+                    mq->specific_address->addrlen)
              : "<inbound>",
              rl->plugin->short_name);
 #endif
@@ -2426,7 +2454,7 @@
 #if DEBUG_TRANSPORT
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Adding address `%s' (%s) for peer `%4s' due to peerinfo data 
for %llums.\n",
-                 GNUNET_a2s (addr, addrlen),
+                 a2s (tname, addr, addrlen),
                  tname,
                  GNUNET_i2s (&n->id),
                  expiration.value);
@@ -3001,8 +3029,9 @@
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Some validation of address `%s' via `%s' for peer `%4s' 
already in progress.\n",
                  (peer_address->addr != NULL)
-                  ? GNUNET_a2s (peer_address->addr,
-                               peer_address->addrlen)
+                  ? a2s (peer_address->plugin->short_name,
+                        peer_address->addr,
+                        peer_address->addrlen)
                  : "<inbound>",
                   tp->short_name,
                   GNUNET_i2s (&neighbour->id));
@@ -3049,8 +3078,9 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Performing re-validation of address `%s' via `%s' for peer 
`%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n",
               (peer_address->addr != NULL) 
-             ? GNUNET_a2s (peer_address->addr,
-                           peer_address->addrlen)
+             ? a2s (peer_address->plugin->short_name,
+                    peer_address->addr,
+                    peer_address->addrlen)
              : "<inbound>",
               tp->short_name,
               GNUNET_i2s (&neighbour->id),
@@ -3231,8 +3261,9 @@
              "Confirmed validity of address, peer `%4s' has address `%s' 
(%s).\n",
              GNUNET_h2s (key),
              (ve->addr != NULL) 
-             ? GNUNET_a2s ((const struct sockaddr *) ve->addr,
-                           ve->addrlen)
+             ? a2s (ve->transport_name,
+                    (const struct sockaddr *) ve->addr,
+                    ve->addrlen)
              : "<inbound>",
              ve->transport_name);
 #endif
@@ -3368,15 +3399,6 @@
       return;
     }
 
-#if 0
-  /* FIXME: add given address to potential pool of our addresses
-     (for voting) */
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
-             _("Another peer saw us using the address `%s' via `%s'.\n"),
-             GNUNET_a2s ((const struct sockaddr *) &pong[1],
-                         ntohs(pong->addrlen)),
-             va->transport_name);
-#endif
 }
 
 
@@ -3434,7 +3456,8 @@
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Performing validation of address `%s' via `%s' for peer `%4s' 
sending `%s' (%u bytes) and `%s' (%u bytes)\n",
-              GNUNET_a2s ((const void*) &va[1], va->addrlen),
+              a2s (va->transport_name,
+                  (const void*) &va[1], va->addrlen),
              va->transport_name,
              GNUNET_i2s (&neighbour->id),
              "HELLO", hello_size,
@@ -3548,7 +3571,7 @@
 #if DEBUG_TRANSPORT > 1
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Validation of address `%s' via `%s' for peer `%4s' already 
in progress.\n",
-                 GNUNET_a2s (addr, addrlen),
+                 a2s (tname, addr, addrlen),
                  tname,
                  GNUNET_i2s (&id));
 #endif
@@ -3939,8 +3962,9 @@
              "Processing `%s' from `%s'\n",
              "PING", 
              (sender_address != NULL) 
-             ? GNUNET_a2s ((const struct sockaddr *)sender_address, 
-                           sender_address_len)
+             ? a2s (plugin->short_name,
+                    (const struct sockaddr *)sender_address, 
+                    sender_address_len)
              : "<inbound>");
 #endif
   GNUNET_STATISTICS_update (stats,
@@ -4895,6 +4919,7 @@
 int
 main (int argc, char *const *argv)
 {
+  a2s (NULL, NULL, 0); /* make compiler happy */
   return (GNUNET_OK ==
           GNUNET_SERVICE_run (argc,
                               argv,

Modified: gnunet/src/transport/plugin_transport.h
===================================================================
--- gnunet/src/transport/plugin_transport.h     2010-05-01 12:17:38 UTC (rev 
11147)
+++ gnunet/src/transport/plugin_transport.h     2010-05-02 11:48:52 UTC (rev 
11148)
@@ -346,7 +346,24 @@
   (*GNUNET_TRANSPORT_CheckAddress) (void *cls,
                                    void *addr, size_t addrlen);
 
+
 /**
+ * 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 addr_len length of the address
+ * @return string representing the same address 
+ */
+typedef const char* (*GNUNET_TRANSPORT_AddressToString) (void *cls,
+                                                        const void *addr,
+                                                        size_t addrlen);
+
+
+/**
  * Each plugin is required to return a pointer to a struct of this
  * type as the return value from its entry point.
  */
@@ -387,9 +404,19 @@
    * Function that will be called to check if a binary address
    * for this plugin is well-formed.  If clearly needed, patch
    * up information such as port numbers.
+   * FIXME: this API will likely change in the near future since
+   * it currently does not allow the size of the patched address
+   * to be different!
    */
   GNUNET_TRANSPORT_CheckAddress check_address;
 
+
+  /**
+   * Function that will be called to convert a binary address
+   * to a string (numeric conversion only).
+   */
+  GNUNET_TRANSPORT_AddressToString address_to_string;
+
 };
 
 

Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2010-05-01 12:17:38 UTC (rev 
11147)
+++ gnunet/src/transport/plugin_transport_tcp.c 2010-05-02 11:48:52 UTC (rev 
11148)
@@ -64,6 +64,42 @@
 
 
 /**
+ * Network format for IPv4 addresses.
+ */
+struct IPv4TcpAddress
+{
+  /**
+   * IPv4 address, in network byte order.
+   */
+  uint32_t ipv4_addr;
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t t_port;
+
+};
+
+
+/**
+ * Network format for IPv6 addresses.
+ */
+struct IPv6TcpAddress
+{
+  /**
+   * IPv6 address.
+   */
+  unsigned char ipv6_addr[16];
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t t6_port;
+
+};
+
+
+/**
  * Encapsulation of all of the state of the plugin.
  */
 struct Plugin;
@@ -262,7 +298,61 @@
 };
 
 
+
+
 /**
+ * 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 ('struct Plugin*')
+ * @param addr binary address
+ * @param addr_len length of the address
+ * @return string representing the same address 
+ */
+static const char* 
+tcp_address_to_string (void *cls,
+                      const void *addr,
+                      size_t addrlen)
+{
+  static char buf[INET6_ADDRSTRLEN];
+  const void *sb;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4TcpAddress *t4;
+  const struct IPv6TcpAddress *t6;
+  int af;
+
+  if (addrlen == sizeof (struct IPv6TcpAddress))
+    {
+      t6 = addr;
+      af = AF_INET6;
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->t6_port;
+      memcpy (a6.sin6_addr.s6_addr,
+             t6->ipv6_addr,
+             16);      
+      sb = &a6;
+    }
+  else if (addrlen == sizeof (struct IPv4TcpAddress))
+    {
+      t4 = addr;
+      af = AF_INET;
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = t4->t_port;
+      a4.sin_addr.s_addr = t4->ipv4_addr;
+      sb = &a4;
+    }
+  else
+    return NULL;
+  return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
+}
+
+
+/**
  * Find the session handle for the given client.
  *
  * @return NULL if no matching session exists
@@ -520,8 +610,10 @@
                    "Disconnecting from `%4s' at %s (session %p).\n",
                    GNUNET_i2s (&session->target),
                    (session->connect_addr != NULL) ?
-                   GNUNET_a2s (session->connect_addr,
-                               session->connect_alen) : "*", session);
+                   tcp_address_to_string (session->plugin,
+                                         session->connect_addr,
+                                         session->connect_alen) : "*", 
+                  session);
 #endif
   /* remove from session list */
   prev = NULL;
@@ -680,6 +772,12 @@
   struct PendingMessage *pm;
   struct GNUNET_CONNECTION_Handle *sa;
   int af;
+  const void *sb;
+  size_t sbs;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4TcpAddress *t4;
+  const struct IPv6TcpAddress *t6;
 
   GNUNET_STATISTICS_update (plugin->env->stats,
                            gettext_noop ("# bytes TCP was asked to transmit"),
@@ -746,13 +844,29 @@
     }
   if (session == NULL)
     {
-      if (sizeof (struct sockaddr_in) == addrlen)
+      if (addrlen == sizeof (struct IPv6TcpAddress))
        {
-         af = AF_INET;
+         t6 = addr;
+         af = AF_INET6;
+         memset (&a6, 0, sizeof (a6));
+         a6.sin6_family = AF_INET6;
+         a6.sin6_port = t6->t6_port;
+         memcpy (a6.sin6_addr.s6_addr,
+                 t6->ipv6_addr,
+                 16);      
+         sb = &a6;
+         sbs = sizeof (a6);
        }
-      else if (sizeof (struct sockaddr_in6) == addrlen)
+      else if (addrlen == sizeof (struct IPv4TcpAddress))
        {
-         af = AF_INET6;
+         t4 = addr;
+         af = AF_INET;
+         memset (&a4, 0, sizeof (a4));
+         a4.sin_family = AF_INET;
+         a4.sin_port = t4->t_port;
+         a4.sin_addr.s_addr = t4->ipv4_addr;
+         sb = &a4;
+         sbs = sizeof (a4);
        }
       else
        {
@@ -760,7 +874,7 @@
          return -1;
        }
       sa = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched,
-                                                  af, addr, addrlen,
+                                                  af, sb, sbs,
                                                   
GNUNET_SERVER_MAX_MESSAGE_SIZE);
       if (sa == NULL)
        {
@@ -769,7 +883,7 @@
                           "tcp",
                           "Failed to create connection to `%4s' at `%s'\n",
                           GNUNET_i2s (target),
-                          GNUNET_a2s (addr, addrlen));
+                          GNUNET_a2s (sb, sbs));
 #endif
          GNUNET_STATISTICS_update (plugin->env->stats,
                                    gettext_noop ("# bytes discarded by TCP 
(failed to connect)"),
@@ -782,7 +896,7 @@
                        "tcp",
                        "Asked to transmit to `%4s', creating fresh session 
using address `%s'.\n",
                       GNUNET_i2s (target),
-                      GNUNET_a2s (addr, addrlen));
+                      GNUNET_a2s (sb, sbs));
 #endif
       session = create_session (plugin,
                                target,
@@ -948,13 +1062,44 @@
                                    void *asc_cls)
 {
   struct Plugin *plugin = cls;
-  const struct sockaddr_in *v4;
-  const struct sockaddr_in6 *v6;
   struct PrettyPrinterContext *ppc;
+  const void *sb;
+  size_t sbs;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4TcpAddress *t4;
+  const struct IPv6TcpAddress *t6;
+  int af;
+  uint16_t port;
 
-  if ((addrlen != sizeof (struct sockaddr_in)) &&
-      (addrlen != sizeof (struct sockaddr_in6)))
+  if (addrlen == sizeof (struct IPv6TcpAddress))
     {
+      t6 = addr;
+      af = AF_INET6;
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->t6_port;
+      memcpy (a6.sin6_addr.s6_addr,
+             t6->ipv6_addr,
+             16);      
+      port = ntohs (t6->t6_port);
+      sb = &a6;
+      sbs = sizeof (a6);
+    }
+  else if (addrlen == sizeof (struct IPv4TcpAddress))
+    {
+      t4 = addr;
+      af = AF_INET;
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = t4->t_port;
+      a4.sin_addr.s_addr = t4->ipv4_addr;
+      port = ntohs (t4->t_port);
+      sb = &a4;
+      sbs = sizeof (a4);
+    }
+  else
+    {
       /* invalid address */
       GNUNET_break_op (0);
       asc (asc_cls, NULL);
@@ -963,21 +1108,11 @@
   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
   ppc->asc = asc;
   ppc->asc_cls = asc_cls;
-  if (addrlen == sizeof (struct sockaddr_in))
-    {
-      v4 = (const struct sockaddr_in *) addr;
-      ppc->port = ntohs (v4->sin_port);
-    }
-  else
-    {
-      v6 = (const struct sockaddr_in6 *) addr;
-      ppc->port = ntohs (v6->sin6_port);
-
-    }
+  ppc->port = port;
   GNUNET_RESOLVER_hostname_get (plugin->env->sched,
                                 plugin->env->cfg,
-                                addr,
-                                addrlen,
+                                sb,
+                                sbs,
                                 !numeric, timeout, &append_port, ppc);
 }
 
@@ -1004,45 +1139,40 @@
 
 /**
  * Another peer has suggested an address for this peer and transport
- * plugin.  Check that this could be a valid address.
+ * plugin.  Check that this could be a valid address. This function
+ * is not expected to 'validate' the address in the sense of trying to
+ * connect to it but simply to see if the binary format is technically
+ * legal for establishing a connection.
  *
  * @param cls closure, our 'struct Plugin*'
  * @param addr pointer to the address
  * @param addrlen length of addr
  * @return GNUNET_OK if this is a plausible address for this peer
- *         and transport
+ *         and transport, GNUNET_SYSERR if not
  */
 static int
 tcp_plugin_check_address (void *cls, void *addr, size_t addrlen)
 {
   struct Plugin *plugin = cls;
-  char buf[sizeof (struct sockaddr_in6)];
-  struct sockaddr_in *v4;
-  struct sockaddr_in6 *v6;
+  struct IPv4TcpAddress *v4;
+  struct IPv6TcpAddress *v6;
 
-  if ((addrlen != sizeof (struct sockaddr_in)) &&
-      (addrlen != sizeof (struct sockaddr_in6)))
+  if ((addrlen != sizeof (struct IPv4TcpAddress)) &&
+      (addrlen != sizeof (struct IPv6TcpAddress)))
     {
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
-  memcpy (buf, addr, sizeof (struct sockaddr_in6));
-  if (addrlen == sizeof (struct sockaddr_in))
+  if (addrlen == sizeof (struct IPv4TcpAddress))
     {
-      v4 = (struct sockaddr_in *) buf;
-      v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port)));
+      v4 = (struct IPv4TcpAddress *) addr;
+      v4->t_port = htons (check_port (plugin, ntohs (v4->t_port)));
     }
   else
     {
-      v6 = (struct sockaddr_in6 *) buf;
-      v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port)));
+      v6 = (struct IPv6TcpAddress *) addr;
+      v6->t6_port = htons (check_port (plugin, ntohs (v6->t6_port)));
     }
-#if DEBUG_TCP
-  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-                   "tcp",
-                   "Informing transport service about my address `%s'.\n",
-                   GNUNET_a2s (addr, addrlen));
-#endif
   return GNUNET_OK;
 }
 
@@ -1065,7 +1195,12 @@
   struct Session *session;
   size_t alen;
   void *vaddr;
+  struct IPv4TcpAddress *t4;
+  struct IPv6TcpAddress *t6;
+  const struct sockaddr_in *s4;
+  const struct sockaddr_in6 *s6;
 
+
 #if DEBUG_TCP
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
                    "tcp",
@@ -1094,8 +1229,27 @@
                           GNUNET_a2s (vaddr, alen),
                           client);
 #endif
-         session->connect_addr = vaddr;
-         session->connect_alen = alen;
+         if (alen == sizeof (struct sockaddr_in))
+           {
+             s4 = vaddr;
+             t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
+             t4->t_port = s4->sin_port;
+             t4->ipv4_addr = s4->sin_addr.s_addr;
+             session->connect_addr = t4;
+             session->connect_alen = sizeof (struct IPv4TcpAddress);
+           }
+         else if (alen == sizeof (struct sockaddr_in6))
+           {
+             s6 = vaddr;
+             t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
+             t6->t6_port = s6->sin6_port;
+             memcpy (t6->ipv6_addr,
+                     s6->sin6_addr.s6_addr,
+                     16);
+             session->connect_addr = t6;
+             session->connect_alen = sizeof (struct IPv6TcpAddress);
+           }
+         GNUNET_free (vaddr);
        }
       else
         {
@@ -1227,7 +1381,8 @@
  * @param client identification of the client
  */
 static void
-disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client)
+disconnect_notify (void *cls, 
+                  struct GNUNET_SERVER_Client *client)
 {
   struct Plugin *plugin = cls;
   struct Session *session;
@@ -1243,8 +1398,10 @@
                    "Destroying session of `%4s' with %s (%p) due to 
network-level disconnect.\n",
                    GNUNET_i2s (&session->target),
                    (session->connect_addr != NULL) ?
-                   GNUNET_a2s (session->connect_addr,
-                               session->connect_alen) : "*", client);
+                   tcp_address_to_string (session->plugin,
+                                         session->connect_addr,
+                                         session->connect_alen) : "*",
+                  client);
 #endif
   disconnect_session (session);
 }
@@ -1259,6 +1416,7 @@
  * @param isDefault do we think this may be our default interface
  * @param addr address of the interface
  * @param addrlen number of bytes in addr
+ * @return GNUNET_OK to continue iterating
  */
 static int
 process_interfaces (void *cls,
@@ -1268,28 +1426,41 @@
 {
   struct Plugin *plugin = cls;
   int af;
-  struct sockaddr_in *v4;
-  struct sockaddr_in6 *v6;
+  struct IPv4TcpAddress t4;
+  struct IPv6TcpAddress t6;
+  void *arg;
+  uint16_t args;
 
   af = addr->sa_family;
   if (af == AF_INET)
     {
-      v4 = (struct sockaddr_in *) addr;
-      v4->sin_port = htons (plugin->adv_port);
+      t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+      t4.t_port = htons (plugin->adv_port);
+      arg = &t4;
+      args = sizeof (t4);
     }
+  else if (af == AF_INET6)
+    {
+      memcpy (t6.ipv6_addr,
+             ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
+             16);
+      t6.t6_port = htons (plugin->adv_port);
+      arg = &t6;
+      args = sizeof (t6);
+    }
   else
     {
-      GNUNET_assert (af == AF_INET6);
-      v6 = (struct sockaddr_in6 *) addr;
-      v6->sin6_port = htons (plugin->adv_port);
+      GNUNET_break (0);
+      return GNUNET_OK;
     }
   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
                    GNUNET_ERROR_TYPE_BULK,
-                   "tcp", _("Found address `%s' (%s)\n"),
+                   "tcp", 
+                  _("Found address `%s' (%s)\n"),
                    GNUNET_a2s (addr, addrlen), name);
   plugin->env->notify_address (plugin->env->cls,
                                "tcp",
-                               addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL);
+                               arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
   return GNUNET_OK;
 }
 
@@ -1320,6 +1491,9 @@
 
 /**
  * Entry point for the plugin.
+ *
+ * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
+ * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
  */
 void *
 libgnunet_plugin_transport_tcp_init (void *cls)
@@ -1377,6 +1551,7 @@
   api->disconnect = &tcp_plugin_disconnect;
   api->address_pretty_printer = &tcp_plugin_address_pretty_printer;
   api->check_address = &tcp_plugin_check_address;
+  api->address_to_string = &tcp_address_to_string;
   plugin->service = service;
   plugin->server = GNUNET_SERVICE_get_server (service);
   plugin->handlers = GNUNET_malloc (sizeof (my_handlers));

Modified: gnunet/src/transport/plugin_transport_template.c
===================================================================
--- gnunet/src/transport/plugin_transport_template.c    2010-05-01 12:17:38 UTC 
(rev 11147)
+++ gnunet/src/transport/plugin_transport_template.c    2010-05-02 11:48:52 UTC 
(rev 11148)
@@ -248,6 +248,29 @@
 
 
 /**
+ * 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 addr_len length of the address
+ * @return string representing the same address 
+ */
+static const char* 
+template_plugin_address_to_string (void *cls,
+                                  const void *addr,
+                                  size_t addrlen)
+{
+  GNUNET_break (0);
+  return NULL;
+}
+
+
+
+
+/**
  * Entry point for the plugin.
  */
 void *
@@ -266,6 +289,7 @@
   api->disconnect = &template_plugin_disconnect;
   api->address_pretty_printer = &template_plugin_address_pretty_printer;
   api->check_address = &template_plugin_address_suggested;
+  api->address_to_string = &template_plugin_address_to_string;
   return api;
 }
 

Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2010-05-01 12:17:38 UTC (rev 
11147)
+++ gnunet/src/transport/plugin_transport_udp.c 2010-05-02 11:48:52 UTC (rev 
11148)
@@ -71,13 +71,64 @@
 };
 
 
+/**
+ * Network format for IPv4 addresses.
+ */
+struct IPv4UdpAddress
+{
+  /**
+   * IPv4 address, in network byte order.
+   */
+  uint32_t ipv4_addr;
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t u_port;
+
+};
+
+
+/**
+ * Network format for IPv6 addresses.
+ */
+struct IPv6UdpAddress
+{
+  /**
+   * IPv6 address.
+   */
+  unsigned char ipv6_addr[16];
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t u6_port;
+
+};
+
+
+/**
+ *
+ */
 struct PrettyPrinterContext
 {
+  /**
+   *
+   */
   GNUNET_TRANSPORT_AddressStringCallback asc;
+
+  /**
+   * Closure for 'asc'.
+   */
   void *asc_cls;
+
+  /**
+   *
+   */
   uint16_t port;
 };
 
+
 /**
  * Encapsulation of all of the state of the plugin.
  */
@@ -134,7 +185,7 @@
 /* *********** globals ************* */
 
 /**
- * the socket that we transmit all data with
+ * The socket that we transmit all data with
  */
 static struct GNUNET_NETWORK_Handle *udp_sock;
 
@@ -146,7 +197,8 @@
  * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
  */
 void
-udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
+udp_disconnect (void *cls, 
+               const struct GNUNET_PeerIdentity *target)
 {
   /* nothing to do, UDP is stateless */
 }
@@ -154,6 +206,8 @@
 /**
  * Shutdown the server process (stop receiving inbound traffic). Maybe
  * restarted later!
+ *
+ * @param cls closure, the 'struct Plugin*'
  */
 static int
 udp_transport_server_stop (void *cls)
@@ -178,7 +232,7 @@
  * Function that can be used by the transport service to transmit
  * a message using the plugin.
  *
- * @param cls closure
+ * @param cls closure, the 'struct Plugin*'
  * @param target who should receive this message (ignored by UDP)
  * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
  * @param msgbuf_size the size of the msgbuf to send
@@ -217,6 +271,13 @@
   struct UDPMessage *message;
   int ssize;
   ssize_t sent;
+  int af;
+  const void *sb;
+  size_t sbs;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4UdpAddress *t4;
+  const struct IPv6UdpAddress *t6;
 
   GNUNET_assert (NULL == session);
   GNUNET_assert(udp_sock != NULL);
@@ -231,13 +292,45 @@
   if (force_address == GNUNET_SYSERR)
     return -1; /* never reliable */
 
+  if (addrlen == sizeof (struct IPv6UdpAddress))
+    {
+      t6 = addr;
+      af = AF_INET6;
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->u6_port;
+      memcpy (a6.sin6_addr.s6_addr,
+             t6->ipv6_addr,
+             16);      
+      sb = &a6;
+      sbs = sizeof (a6);
+    }
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
+    {
+      t4 = addr;
+      af = AF_INET;
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = t4->u_port;
+      a4.sin_addr.s_addr = t4->ipv4_addr;
+      sb = &a4;
+      sbs = sizeof (a4);
+    }
+  else
+    {
+      GNUNET_break_op (0);
+      return -1;
+    }
+
   /* Build the message to be sent */
   message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size);
   ssize = sizeof (struct UDPMessage) + msgbuf_size;
 
 #if DEBUG_UDP
-  GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
-                   ("In udp_send, ssize is %d, sending message to %s\n"), 
ssize, GNUNET_a2s((const struct sockaddr *)addr, addrlen));
+  GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", 
+                   "In udp_send, ssize is %d, sending message to `%s'\n", 
+                  ssize, 
+                  GNUNET_a2s(sb, sbs));
 #endif
   message->header.size = htons (ssize);
   message->header.type = htons (0);
@@ -246,8 +339,7 @@
   memcpy (&message[1], msgbuf, msgbuf_size);
   sent =
     GNUNET_NETWORK_socket_sendto (udp_sock, message, ssize,
-                                  addr,
-                                  addrlen);
+                                  sb, sbs);
   if ( (cont != NULL) &&
        (sent != -1) )
     cont (cont_cls, target, GNUNET_OK);
@@ -259,6 +351,13 @@
 /**
  * Add the IP of our network interface to the list of
  * our external IP addresses.
+ *
+ * @param cls closure (the 'struct Plugin*')
+ * @param name name of the interface (can be NULL for unknown)
+ * @param isDefault is this presumably the default interface
+ * @param addr address of this interface (can be NULL for unknown or 
unassigned)
+ * @param addrlen length of the address
+ * @return GNUNET_OK to continue iterating
  */
 static int
 process_interfaces (void *cls,
@@ -268,29 +367,42 @@
 {
   struct Plugin *plugin = cls;
   int af;
-  struct sockaddr_in *v4;
-  struct sockaddr_in6 *v6;
+  struct IPv4UdpAddress t4;
+  struct IPv6UdpAddress t6;
+  void *arg;
+  uint16_t args;
 
   af = addr->sa_family;
   if (af == AF_INET)
     {
-      v4 = (struct sockaddr_in *) addr;
-      v4->sin_port = htons (plugin->adv_port);
+      t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+      t4.u_port = htons (plugin->adv_port);
+      arg = &t4;
+      args = sizeof (t4);
     }
+  else if (af == AF_INET6)
+    {
+      memcpy (t6.ipv6_addr,
+             ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
+             16);
+      t6.u6_port = htons (plugin->adv_port);
+      arg = &t6;
+      args = sizeof (t6);
+    }
   else
     {
-      GNUNET_assert (af == AF_INET6);
-      v6 = (struct sockaddr_in6 *) addr;
-      v6->sin6_port = htons (plugin->adv_port);
+      GNUNET_break (0);
+      return GNUNET_OK;
     }
   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
                    GNUNET_ERROR_TYPE_BULK,
-                   "udp", _("Found address `%s' (%s)\n"),
-                   GNUNET_a2s (addr, addrlen), name);
+                   "udp", 
+                  _("Found address `%s' (%s)\n"),
+                   GNUNET_a2s (addr, addrlen), 
+                  name);
   plugin->env->notify_address (plugin->env->cls,
                                "udp",
-                               addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL);
-
+                               arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
   return GNUNET_OK;
 }
 
@@ -346,6 +458,12 @@
   int tsize;
   char *msgbuf;
   const struct GNUNET_MessageHeader *currhdr;
+  struct IPv4UdpAddress t4;
+  struct IPv6UdpAddress t6;
+  const struct sockaddr_in *s4;
+  const struct sockaddr_in6 *s6;
+  const void *ca;
+  size_t calen;
 
 #if DEBUG_UDP
       GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
@@ -411,6 +529,31 @@
                      ("offset is %d, tsize is %d (UDPMessage size is %d)\n"),
                      offset, tsize, sizeof(struct UDPMessage));
 #endif
+
+    if (fromlen == sizeof (struct sockaddr_in))
+      {
+       s4 = (const struct sockaddr_in*) &addr;
+       t4.u_port = s4->sin_port;
+       t4.ipv4_addr = s4->sin_addr.s_addr;
+       ca = &t4;
+       calen = sizeof (struct IPv4UdpAddress);
+      }
+    else if (fromlen == sizeof (struct sockaddr_in6))
+      {
+       s6 = (const struct sockaddr_in6*) &addr;
+       t6.u6_port = s6->sin6_port;
+       memcpy (t6.ipv6_addr,
+               s6->sin6_addr.s6_addr,
+               16);
+       ca = &t6;
+       calen = sizeof (struct IPv6UdpAddress);
+      }
+    else
+      {
+       GNUNET_break (0);
+       ca = NULL;
+       calen = 0;
+      }
     while (offset < tsize)
       {
         currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
@@ -421,7 +564,7 @@
 #endif
         plugin->env->receive (plugin->env->cls,
                              sender, currhdr, UDP_DIRECT_DISTANCE, 
-                             NULL, (const char *)&addr, fromlen);
+                             NULL, ca, calen);
         offset += ntohs(currhdr->size);
 #if DEBUG_UDP
     GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
@@ -446,6 +589,7 @@
 /**
  * Create a UDP socket.  If possible, use IPv6, otherwise
  * try IPv4.
+ * @param cls closure, the 'struct Plugin*'
  */
 static struct GNUNET_NETWORK_Handle *
 udp_transport_server_start (void *cls)
@@ -550,44 +694,31 @@
  * @param addrlen length of addr
  * @return GNUNET_OK if this is a plausible address for this peer
  *         and transport, GNUNET_SYSERR if not
- *
- * TODO: perhaps make everything work with sockaddr_storage, it may
- *       be a cleaner way to handle addresses in UDP
  */
 static int
 udp_check_address (void *cls, void *addr, size_t addrlen)
 {
   struct Plugin *plugin = cls;
-  char buf[sizeof (struct sockaddr_in6)];
+  struct IPv4UdpAddress *v4;
+  struct IPv6UdpAddress *v6;
 
-  struct sockaddr_in *v4;
-  struct sockaddr_in6 *v6;
-
-  if ((addrlen != sizeof (struct sockaddr_in)) &&
-      (addrlen != sizeof (struct sockaddr_in6)))
+  if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
+      (addrlen != sizeof (struct IPv6UdpAddress)))
     {
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
-  memcpy (buf, addr, sizeof (struct sockaddr_in6));
-  if (addrlen == sizeof (struct sockaddr_in))
+  if (addrlen == sizeof (struct IPv4UdpAddress))
     {
-      v4 = (struct sockaddr_in *) buf;
-      v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port)));
+      v4 = (struct IPv4UdpAddress *) addr;
+      v4->u_port = htons (check_port (plugin, ntohs (v4->u_port)));
     }
   else
     {
-      v6 = (struct sockaddr_in6 *) buf;
-      v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port)));
+      v6 = (struct IPv6UdpAddress *) addr;
+      v6->u6_port = htons (check_port (plugin, ntohs (v6->u6_port)));
     }
-#if DEBUG_UDP
-  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-                   "tcp",
-                   "Informing transport service about my address `%s'.\n",
-                   GNUNET_a2s (addr, addrlen));
-#endif
   return GNUNET_OK;
-  return GNUNET_OK;
 }
 
 
@@ -637,13 +768,44 @@
                                    void *asc_cls)
 {
   struct Plugin *plugin = cls;
-  const struct sockaddr_in *v4;
-  const struct sockaddr_in6 *v6;
   struct PrettyPrinterContext *ppc;
+  const void *sb;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4UdpAddress *t4;
+  const struct IPv6UdpAddress *t6;
+  int af;
+  size_t sbs;
+  uint16_t port;
 
-  if ((addrlen != sizeof (struct sockaddr_in)) &&
-      (addrlen != sizeof (struct sockaddr_in6)))
+  if (addrlen == sizeof (struct IPv6UdpAddress))
     {
+      t6 = addr;
+      af = AF_INET6;
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->u6_port;
+      port = ntohs (t6->u6_port);
+      memcpy (a6.sin6_addr.s6_addr,
+             t6->ipv6_addr,
+             16);      
+      sb = &a6;
+      sbs = sizeof (a6);
+    }
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
+    {
+      t4 = addr;
+      af = AF_INET;
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = t4->u_port;
+      a4.sin_addr.s_addr = t4->ipv4_addr;
+      port = ntohs (t4->u_port);
+      sb = &a4;
+      sbs = sizeof (a4);
+    }
+  else
+    {
       /* invalid address */
       GNUNET_break_op (0);
       asc (asc_cls, NULL);
@@ -652,28 +814,75 @@
   ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
   ppc->asc = asc;
   ppc->asc_cls = asc_cls;
-  if (addrlen == sizeof (struct sockaddr_in))
+  ppc->port = port;
+  GNUNET_RESOLVER_hostname_get (plugin->env->sched,
+                                plugin->env->cfg,
+                                sb,
+                                sbs,
+                                !numeric, timeout, &append_port, ppc);
+}
+
+
+
+/**
+ * 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 addr_len length of the address
+ * @return string representing the same address 
+ */
+static const char* 
+udp_address_to_string (void *cls,
+                      const void *addr,
+                      size_t addrlen)
+{
+  static char buf[INET6_ADDRSTRLEN];
+  const void *sb;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4UdpAddress *t4;
+  const struct IPv6UdpAddress *t6;
+  int af;
+
+  if (addrlen == sizeof (struct IPv6UdpAddress))
     {
-      v4 = (const struct sockaddr_in *) addr;
-      ppc->port = ntohs (v4->sin_port);
+      t6 = addr;
+      af = AF_INET6;
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->u6_port;
+      memcpy (a6.sin6_addr.s6_addr,
+             t6->ipv6_addr,
+             16);      
+      sb = &a6;
     }
-  else
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
     {
-      v6 = (const struct sockaddr_in6 *) addr;
-      ppc->port = ntohs (v6->sin6_port);
-
+      t4 = addr;
+      af = AF_INET;
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = t4->u_port;
+      a4.sin_addr.s_addr = t4->ipv4_addr;
+      sb = &a4;
     }
-  GNUNET_RESOLVER_hostname_get (plugin->env->sched,
-                                plugin->env->cfg,
-                                addr,
-                                addrlen,
-                                !numeric, timeout, &append_port, ppc);
+  else
+    return NULL;
+  
+  return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
 }
 
 
 /**
  * The exported method. Makes the core api available via a global and
  * returns the udp transport API.
+ *
+ * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
+ * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
  */
 void *
 libgnunet_plugin_transport_udp_init (void *cls)
@@ -737,7 +946,7 @@
   api->disconnect = &udp_disconnect;
   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
   api->check_address = &udp_check_address;
-
+  api->address_to_string = &udp_address_to_string;
   plugin->service = service;
 
   /* FIXME: do the two calls below periodically again and

Modified: gnunet/src/transport/test_plugin_transport_http.c
===================================================================
--- gnunet/src/transport/test_plugin_transport_http.c   2010-05-01 12:17:38 UTC 
(rev 11147)
+++ gnunet/src/transport/test_plugin_transport_http.c   2010-05-02 11:48:52 UTC 
(rev 11148)
@@ -36,7 +36,7 @@
 #include "plugin_transport.h"
 #include "transport.h"
 
-#define VERBOSE GNUNET_YES
+#define VERBOSE GNUNET_NO
 
 /**
  * How long until we give up on transmitting the message?
@@ -91,15 +91,17 @@
 /**
  * Initialize Environment for this plugin
  */
-static void
+static struct GNUNET_TIME_Relative
 receive (void *cls,
-        const struct GNUNET_PeerIdentity * peer,
-        const struct GNUNET_MessageHeader * message,
-        uint32_t distance,
-        const char *sender_address,
-        size_t sender_address_len)
+        const struct GNUNET_PeerIdentity * peer,
+        const struct GNUNET_MessageHeader * message,
+        uint32_t distance,
+        struct Session *session,
+        const char *sender_address,
+        size_t sender_address_len)
 {
   /* do nothing */
+  return GNUNET_TIME_UNIT_ZERO;
 }
 
 void





reply via email to

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