gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r11953 - gnunet/src/transport
Date: Fri, 25 Jun 2010 18:41:59 +0200

Author: nevans
Date: 2010-06-25 18:41:59 +0200 (Fri, 25 Jun 2010)
New Revision: 11953

Modified:
   gnunet/src/transport/plugin_transport_udp.c
Log:
fixing christians overwritten changes

Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2010-06-25 15:37:07 UTC (rev 
11952)
+++ gnunet/src/transport/plugin_transport_udp.c 2010-06-25 16:41:59 UTC (rev 
11953)
@@ -90,7 +90,39 @@
 
 };
 
+/**
+ * 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;
+};
+
 /* Forward definition */
 struct Plugin;
 
@@ -512,12 +544,18 @@
   struct UDPMessage *message;
   int ssize;
   ssize_t sent;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4UdpAddress *t4;
+  const struct IPv6UdpAddress *t6;
+  const void *sb;
+  size_t sbs;
 
   if ((addr == NULL) || (addrlen == 0))
     {
 #if DEBUG_UDP_NAT
   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
-                   ("udp_plugin_send called without address, returning!\n"));
+                   ("udp_real_send called without address, returning!\n"));
 #endif
       if (cont != NULL)
         cont (cont_cls, target, GNUNET_SYSERR);
@@ -534,11 +572,45 @@
           sizeof (struct GNUNET_PeerIdentity));
   memcpy (&message[1], msgbuf, msgbuf_size);
 
+  if (addrlen == sizeof (struct IPv6UdpAddress))
+    {
+      t6 = addr;
+      memset (&a6, 0, sizeof (a6));
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      a6.sin6_len = sizeof (a6);
+#endif
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->u6_port;
+      memcpy (&a6.sin6_addr,
+              &t6->ipv6_addr,
+              sizeof (struct in6_addr));
+      sb = &a6;
+      sbs = sizeof (a6);
+    }
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
+    {
+      t4 = addr;
+      memset (&a4, 0, sizeof (a4));
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      a4.sin_len = sizeof (a4);
+#endif
+      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;
+    }
+
   /* Actually send the message */
   sent =
     GNUNET_NETWORK_socket_sendto (send_handle, message, ssize,
-                                  addr,
-                                  addrlen);
+                                  sb,
+                                  sbs);
 
   if (cont != NULL)
     {
@@ -646,16 +718,27 @@
   ssize_t sent;
   struct MessageQueue *temp_message;
   struct PeerSession *peer_session;
-  struct sockaddr_in *sockaddr = (struct sockaddr_in *)addr;
   int other_peer_natd;
+  const struct IPv4UdpAddress *t4;
 
   GNUNET_assert (NULL == session);
   other_peer_natd = GNUNET_NO;
-  if ((sockaddr->sin_family == AF_INET) && (ntohs(sockaddr->sin_port) == 0))
+
+  if (addrlen == sizeof(struct IPv4UdpAddress))
     {
-      other_peer_natd = GNUNET_YES;
+      t4 = addr;
+      if (ntohs(t4->u_port) == 0)
+        other_peer_natd = GNUNET_YES;
     }
+  else if (addrlen == sizeof(struct IPv6UdpAddress))
+    {
 
+    }
+  else
+    {
+      GNUNET_break_op(0);
+    }
+
   sent = 0;
 
   if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES))
@@ -742,72 +825,87 @@
 {
   struct Plugin *plugin = cls;
   int af;
-  struct sockaddr_in *v4;
-  struct sockaddr_in6 *v6;
-  struct sockaddr *addr_nat;
+  struct IPv4UdpAddress t4;
+  struct IPv6UdpAddress t6;
+  void *arg;
+  uint16_t args;
 
+  void *addr_nat;
+
   addr_nat = NULL;
   af = addr->sa_family;
   if (af == AF_INET)
     {
-      v4 = (struct sockaddr_in *) addr;
+      t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
       if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == 
GNUNET_YES))
         {
-          v4->sin_port = htons (DEFAULT_NAT_PORT); /* Indicates to receiver we 
are behind NAT */
+          t4.u_port = htons (DEFAULT_NAT_PORT);
         }
       else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but 
will advertise NAT and normal addresses */
         {
-          addr_nat = GNUNET_malloc(addrlen);
-          memcpy(addr_nat, addr, addrlen);
-          v4 = (struct sockaddr_in *) addr_nat;
-          v4->sin_port = htons(plugin->port);
+          addr_nat = GNUNET_malloc(sizeof(t4));
+          memcpy(addr_nat, &t4, sizeof(t4));
+          t4.u_port = plugin->port;
+          ((struct IPv4UdpAddress *)addr_nat)->u_port = 
htons(DEFAULT_NAT_PORT);
         }
       else
         {
-          v4->sin_port = htons (plugin->port);
+          t4.u_port = htons(plugin->port);
         }
+      arg = &t4;
+      args = sizeof (t4);
     }
-  else
+  else if (af == AF_INET6)
     {
-      GNUNET_assert (af == AF_INET6);
-      v6 = (struct sockaddr_in6 *) addr;
+
+      if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
+        {
+          /* skip link local addresses */
+          return GNUNET_OK;
+        }
+      memcpy (&t6.ipv6_addr,
+              &((struct sockaddr_in6 *) addr)->sin6_addr,
+              sizeof (struct in6_addr));
       if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == 
GNUNET_YES))
         {
-          v6->sin6_port = htons (0);
+          t6.u6_port = htons (0);
         }
-      else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but 
will advertise NAT and normal addresses */
+      else if (plugin->behind_nat == GNUNET_YES)
         {
-          addr_nat = GNUNET_malloc(addrlen);
-          memcpy(addr_nat, addr, addrlen);
-          v6 = (struct sockaddr_in6 *) addr_nat;
-          v6->sin6_port = htons(plugin->port);
+          addr_nat = GNUNET_malloc(sizeof(t6));
+          memcpy(addr_nat, &t6, sizeof(t6));
+          t6.u6_port = plugin->port;
+          ((struct IPv6UdpAddress *)addr_nat)->u6_port = 
htons(DEFAULT_NAT_PORT);
         }
       else
         {
-          v6->sin6_port = htons (plugin->port);
+          t6.u6_port = htons (plugin->port);
         }
+
+      arg = &t6;
+      args = sizeof (t6);
     }
 
-    GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO |
                      GNUNET_ERROR_TYPE_BULK,
-                      "udp", _("Found address `%s' (%s)\n"),
+                       _("Found address `%s' (%s)\n"),
                       GNUNET_a2s (addr, addrlen), name);
 
     if (addr_nat != NULL)
       {
         plugin->env->notify_address (plugin->env->cls,
                                     "udp",
-                                    addr_nat, addrlen, 
GNUNET_TIME_UNIT_FOREVER_REL);
-        GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
+                                    addr_nat, args, 
GNUNET_TIME_UNIT_FOREVER_REL);
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO |
                          GNUNET_ERROR_TYPE_BULK,
-                         "udp", _("Found NAT address `%s' (%s)\n"),
-                         GNUNET_a2s (addr_nat, addrlen), name);
+                          _("Found NAT address `%s' (%s)\n"),
+                         GNUNET_a2s (addr_nat, args), name);
         GNUNET_free(addr_nat);
       }
 
     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;
 }
@@ -1042,7 +1140,10 @@
  * @param sockinfo which socket did we receive the message on
  */
 static void
-udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, 
const struct GNUNET_MessageHeader *currhdr, struct sockaddr_storage 
*sender_addr, socklen_t fromlen, struct UDP_Sock_Info *sockinfo)
+udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
+                  const struct GNUNET_MessageHeader *currhdr,
+                  const void *sender_addr,
+                  size_t fromlen, struct UDP_Sock_Info *sockinfo)
 {
   struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply;
   struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation;
@@ -1079,7 +1180,7 @@
                        (char *)outgoing_probe_reply,
                        ntohs(outgoing_probe_reply->header.size), 0, 
                        GNUNET_TIME_relative_get_unit(), 
-                       sender_addr, fromlen, 
+                       sender_addr, fromlen,
                        NULL, NULL);
 
 #if DEBUG_UDP_NAT
@@ -1094,7 +1195,7 @@
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp",
                       _("Received PROBE REPLY from port %d on incoming port 
%d\n"), ntohs(((struct sockaddr_in *)sender_addr)->sin_port), sockinfo->port);
 #endif
-      if (sender_addr->ss_family == AF_INET)
+      if (sizeof(sender_addr) == sizeof(struct IPv4UdpAddress))
         {
           memset(&addr_buf, 0, sizeof(addr_buf));
           if (NULL == inet_ntop (AF_INET, 
@@ -1212,7 +1313,7 @@
       break;
     default:
       plugin->env->receive (plugin->env->cls, sender, currhdr, 
UDP_DIRECT_DISTANCE, 
-                           NULL, (char *)sender_addr, fromlen);
+                           NULL, sender_addr, fromlen);
   }
 
 }
@@ -1236,13 +1337,19 @@
   struct GNUNET_PeerIdentity *sender;
   unsigned int buflen;
   socklen_t fromlen;
-  struct sockaddr_storage addr;
+  struct sockaddr addr;
   ssize_t ret;
   int offset;
   int count;
   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;
 
   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
 
@@ -1259,11 +1366,36 @@
 
   buf = GNUNET_malloc (buflen);
   fromlen = sizeof (addr);
-  memset (&addr, 0, fromlen);
+  memset (&addr, 0, sizeof(addr));
   ret =
     GNUNET_NETWORK_socket_recvfrom (udp_sock.desc, buf, buflen,
-                                    (struct sockaddr *) &addr, &fromlen);
+                                    &addr, &fromlen);
 
+  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 (t4);
+    }
+  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,
+              sizeof (struct in6_addr));
+      ca = &t6;
+      calen = sizeof (t6);
+    }
+  else
+    {
+      GNUNET_break (0);
+      ca = NULL;
+      calen = 0;
+    }
+
 #if DEBUG_UDP_NAT
   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
                    ("socket_recv returned %u, src_addr_len is %u\n"), ret,
@@ -1304,7 +1436,7 @@
                        ("processing msg %d: type %d, size %d at offset %d\n"),
                        count, ntohs(currhdr->type), ntohs(currhdr->size), 
offset);
 #endif
-      udp_demultiplexer(plugin, sender, currhdr, &addr, fromlen, &udp_sock);
+      udp_demultiplexer(plugin, sender, currhdr, ca, calen, &udp_sock);
 #if DEBUG_UDP_NAT
       GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
                        ("processing done msg %d: type %d, size %d at offset 
%d\n"),
@@ -1659,6 +1791,59 @@
 }
 
 /**
+ * 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*
+udp_address_to_string (void *cls,
+                       const void *addr,
+                       size_t addrlen)
+{
+  static char rbuf[INET6_ADDRSTRLEN + 10];
+  char buf[INET6_ADDRSTRLEN];
+  const void *sb;
+  struct in_addr a4;
+  struct in6_addr a6;
+  const struct IPv4UdpAddress *t4;
+  const struct IPv6UdpAddress *t6;
+  int af;
+  uint16_t port;
+
+  if (addrlen == sizeof (struct IPv6UdpAddress))
+    {
+      t6 = addr;
+      af = AF_INET6;
+      port = ntohs (t6->u6_port);
+      memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
+      sb = &a6;
+    }
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
+    {
+      t4 = addr;
+      af = AF_INET;
+      port = ntohs (t4->u_port);
+      memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
+      sb = &a4;
+    }
+  else
+    return NULL;
+  inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
+  GNUNET_snprintf (rbuf,
+                   sizeof (rbuf),
+                   "%s:%u",
+                   buf,
+                   port);
+  return rbuf;
+}
+
+/**
  * The exported method. Makes the core api available via a global and
  * returns the udp transport API.
  */
@@ -1677,7 +1862,7 @@
   int only_nat_addresses;
   char *internal_address;
   char *external_address;
-  struct sockaddr_in in_addr;
+  struct IPv4UdpAddress v4_address;
 
   service = GNUNET_SERVICE_start ("transport-udp", env->sched, env->cfg);
   if (service == NULL)
@@ -1743,7 +1928,7 @@
       return NULL;
     }
 
-  if ((external_address != NULL) && (inet_pton(AF_INET, external_address, 
&in_addr.sin_addr) != 1))
+  if ((external_address != NULL) && (inet_pton(AF_INET, external_address, 
&v4_address.ipv4_addr) != 1))
     {
       GNUNET_log_from(GNUNET_ERROR_TYPE_WARNING, "udp", "Malformed 
EXTERNAL_ADDRESS %s given in configuration!\n", external_address);
     }
@@ -1765,7 +1950,7 @@
       return NULL;
     }
 
-  if ((internal_address != NULL) && (inet_pton(AF_INET, internal_address, 
&in_addr.sin_addr) != 1))
+  if ((internal_address != NULL) && (inet_pton(AF_INET, internal_address, 
&v4_address.ipv4_addr) != 1))
     {
       GNUNET_log_from(GNUNET_ERROR_TYPE_WARNING, "udp", "Malformed 
INTERNAL_ADDRESS %s given in configuration!\n", internal_address);
     }
@@ -1812,6 +1997,7 @@
   api->send = &udp_plugin_send;
   api->disconnect = &udp_disconnect;
   api->address_pretty_printer = &udp_plugin_address_pretty_printer;
+  api->address_to_string = &udp_address_to_string;
   api->check_address = &udp_check_address;
 
   plugin->service = service;
@@ -1828,21 +2014,19 @@
                                                            
&process_hostname_ips,
                                                            plugin);
 
-  if ((plugin->behind_nat == GNUNET_YES) && (inet_pton(AF_INET, 
plugin->external_address, &in_addr.sin_addr) == 1))
+  if ((plugin->behind_nat == GNUNET_YES) && (inet_pton(AF_INET, 
plugin->external_address, &v4_address.ipv4_addr) == 1))
     {
-      in_addr.sin_port = htons(0);
-      in_addr.sin_family = AF_INET;
+      v4_address.u_port = htons(0);
       plugin->env->notify_address (plugin->env->cls,
                                   "udp",
-                                  &in_addr, sizeof(in_addr), 
GNUNET_TIME_UNIT_FOREVER_REL);
+                                  &v4_address, sizeof(v4_address), 
GNUNET_TIME_UNIT_FOREVER_REL);
     }
-  else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, 
plugin->external_address, &in_addr.sin_addr) == 1))
+  else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, 
plugin->external_address, &v4_address.ipv4_addr) == 1))
     {
-      in_addr.sin_port = htons(plugin->port);
-      in_addr.sin_family = AF_INET;
+      v4_address.u_port = htons(plugin->port);
       plugin->env->notify_address (plugin->env->cls,
                                   "udp",
-                                  &in_addr, sizeof(in_addr), 
GNUNET_TIME_UNIT_FOREVER_REL);
+                                  &v4_address, sizeof(v4_address), 
GNUNET_TIME_UNIT_FOREVER_REL);
     }
 
   sockets_created = udp_transport_server_start (plugin);




reply via email to

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