NEW: local addresses are filtered
authorMatthias Wachs <wachs@net.in.tum.de>
Thu, 19 May 2011 11:37:08 +0000 (11:37 +0000)
committerMatthias Wachs <wachs@net.in.tum.de>
Thu, 19 May 2011 11:37:08 +0000 (11:37 +0000)
src/transport/plugin_transport_http.c
src/transport/plugin_transport_tcp.c
src/transport/plugin_transport_udp.c

index 0c859cdbf595f6e963e058bd06d29a5290a5ce2b..3628517960f0aa8836074bd1599fe210c878a9f7 100644 (file)
@@ -463,6 +463,11 @@ struct Plugin
    */
   int use_ipv4;
 
+  /**
+   * use local addresses?
+   */
+  int use_localaddresses;
+
   /**
    * Closure passed by MHD to the mhd_logger function
    */
@@ -726,6 +731,44 @@ remove_session (struct HTTP_PeerContext * pc,
   return GNUNET_OK;
 }
 
+static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
+{
+       uint32_t res = 0;
+       int local = GNUNET_NO;
+       int af = addr->sa_family;
+    switch (af)
+    {
+      case AF_INET:
+      {
+         uint32_t netmask = 0x7F000000;
+         uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
+         res = (address >> 24) ^ (netmask >> 24);
+         if (res != 0)
+                 local = GNUNET_NO;
+         else
+                 local = GNUNET_YES;
+#if DEBUG_HTTP
+           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                         "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
+#endif
+           break;
+      }
+      case AF_INET6:
+      {
+          if (IN6_IS_ADDR_LOOPBACK  (&((struct sockaddr_in6 *) addr)->sin6_addr) ||
+                  IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
+                  local = GNUNET_YES;
+          else
+                  local = GNUNET_NO;
+#if DEBUG_HTTP
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                         "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
+#endif
+          break;
+      }
+    }
+       return local;
+}
 
 /**
  * Add the IP of our network interface to the list of
@@ -749,40 +792,50 @@ process_interfaces (void *cls,
   struct IPv6HttpAddress * t6;
   int af;
 
+  if (plugin->use_localaddresses == GNUNET_NO)
+  {
+         if (GNUNET_YES == check_localaddress (addr, addrlen))
+         {
+#if DEBUG_HTTP
+          GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                  PROTOCOL_PREFIX,
+                          "Not notifying transport of address `%s' (local address)\n",
+                          GNUNET_a2s (addr, addrlen));
+#endif
+                 return GNUNET_OK;
+         }
+  }
+
 
   GNUNET_assert(cls !=NULL);
   af = addr->sa_family;
-  if ( (af == AF_INET) && 
-       (plugin->use_ipv4 == GNUNET_YES) && 
-       (plugin->bind6_address == NULL) )
-    {
-      struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr;
+  if ((af == AF_INET) &&
+      (plugin->use_ipv4 == GNUNET_YES) &&
+      (plugin->bind6_address == NULL) ) {
+
+         struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr;
       t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress));
-      /* Not skipping loopback addresses
-        if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr))
-        {
+     // Not skipping loopback addresses
+
 
-        return GNUNET_OK;
-      }
-      */
       t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
       t4->u_port = htons (plugin->port_inbound);
-      if (plugin->bind4_address != NULL)
-       {
+      if (plugin->bind4_address != NULL) {
          if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr)))
-           {
-             GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,t4);
-             plugin->env->notify_address(plugin->env->cls,
-                                         PROTOCOL_PREFIX, 
-                                         t4, sizeof (struct IPv4HttpAddress), 
-                                         GNUNET_TIME_UNIT_FOREVER_REL);
-             return GNUNET_OK;
-           }
-         GNUNET_free (t4);
-         return GNUNET_OK;
-       }
+             {
+             GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,
+                                                                                 plugin->ipv4_addr_tail,t4);
+                         plugin->env->notify_address(plugin->env->cls,
+                                                                                 PROTOCOL_PREFIX,
+                                                                                 t4, sizeof (struct IPv4HttpAddress),
+                                                                                 GNUNET_TIME_UNIT_FOREVER_REL);
+                         return GNUNET_OK;
+             }
+         GNUNET_free (t4);
+         return GNUNET_OK;
+         }
       else
-       {
+         {
           GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head,
                                       plugin->ipv4_addr_tail,
                                       t4);
@@ -791,25 +844,21 @@ process_interfaces (void *cls,
                                       t4, sizeof (struct IPv4HttpAddress), 
                                       GNUNET_TIME_UNIT_FOREVER_REL);
          return GNUNET_OK;
-       }
-    }
-  else if ( (af == AF_INET6) && 
+         }
+   }
+   if ((af == AF_INET6) &&
            (plugin->use_ipv6 == GNUNET_YES) && 
-           (plugin->bind4_address == NULL) )
-    {
-      struct in6_addr bnd_cmp6 = ((struct sockaddr_in6 *) addr)->sin6_addr;
-      if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
-        {
-          return GNUNET_OK;
-        }
+           (plugin->bind4_address == NULL) ) {
+
+         struct in6_addr bnd_cmp6 = ((struct sockaddr_in6 *) addr)->sin6_addr;
+
       t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress));
       GNUNET_assert(t6 != NULL);
-      if (plugin->bind6_address != NULL)
-       {
+
+      if (plugin->bind6_address != NULL) {
          if (0 == memcmp(&plugin->bind6_address->sin6_addr,
-                         &bnd_cmp6, 
-                         sizeof (struct in6_addr)))
-           {
+                                                 &bnd_cmp6,
+                                                sizeof (struct in6_addr))) {
              memcpy (&t6->ipv6_addr,
                      &((struct sockaddr_in6 *) addr)->sin6_addr,
                      sizeof (struct in6_addr));
@@ -821,21 +870,21 @@ process_interfaces (void *cls,
              GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,
                                          plugin->ipv6_addr_tail,
                                          t6);
-             return GNUNET_OK;
-           }
+             return GNUNET_OK;
+             }
          GNUNET_free (t6);
          return GNUNET_OK;
-       }
+         }
       memcpy (&t6->ipv6_addr,
-             &((struct sockaddr_in6 *) addr)->sin6_addr,
-             sizeof (struct in6_addr));
+                 &((struct sockaddr_in6 *) addr)->sin6_addr,
+                 sizeof (struct in6_addr));
       t6->u6_port = htons (plugin->port_inbound);
       GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6);
       plugin->env->notify_address(plugin->env->cls,
                                  PROTOCOL_PREFIX,
                                  t6, sizeof (struct IPv6HttpAddress), 
                                  GNUNET_TIME_UNIT_FOREVER_REL);
-    }
+  }
   return GNUNET_OK;
 }
 
@@ -2962,8 +3011,10 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
   plugin->env = env;
   plugin->peers = NULL;
   plugin->bind4_address = NULL;
+  plugin->bind6_address = NULL;
   plugin->use_ipv6  = GNUNET_YES;
   plugin->use_ipv4  = GNUNET_YES;
+  plugin->use_localaddresses = GNUNET_NO;
 
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
@@ -2992,6 +3043,15 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
       plugin->use_ipv4 = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
                                                               component_name,"USE_IPv4");
     }
+  /* use local addresses? */
+
+  if (GNUNET_CONFIGURATION_have_value (env->cfg,
+                                      component_name, "USE_LOCALADDR"))
+    {
+      plugin->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
+                                                              component_name,
+                                                              "USE_LOCALADDR");
+    }
   /* Reading port number from config file */
   if ((GNUNET_OK !=
        GNUNET_CONFIGURATION_get_value_number (env->cfg,
index 6771571949f174135486fa31c592182a4788fc6e..b500b3a72a5c21e8480f8ec6e28a71018eae67fa 100644 (file)
@@ -38,9 +38,9 @@
 #include "gnunet_transport_plugin.h"
 #include "transport.h"
 
-#define DEBUG_TCP GNUNET_YES
+#define DEBUG_TCP GNUNET_NO
 
-#define DEBUG_TCP_NAT GNUNET_NO
+#define DEBUG_TCP_NAT GNUNET_YES
 
 /**
  * How long until we give up on transmitting the welcome message?
@@ -433,6 +433,11 @@ struct Plugin
    */
   char *bind_address;
 
+  /**
+   * use local addresses?
+   */
+  int use_localaddresses;
+
   /**
    * List of our IP addresses.
    */
@@ -2139,6 +2144,45 @@ disconnect_notify (void *cls,
 }
 
 
+static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
+{
+       uint32_t res = 0;
+       int local = GNUNET_NO;
+       int af = addr->sa_family;
+    switch (af)
+    {
+      case AF_INET:
+      {
+         uint32_t netmask = 0x7F000000;
+         uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
+         res = (address >> 24) ^ (netmask >> 24);
+         if (res != 0)
+                 local = GNUNET_NO;
+         else
+                 local = GNUNET_YES;
+#if DEBUG_TCP
+           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                         "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
+#endif
+           break;
+      }
+      case AF_INET6:
+      {
+          if (IN6_IS_ADDR_LOOPBACK  (&((struct sockaddr_in6 *) addr)->sin6_addr) ||
+                  IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
+                  local = GNUNET_YES;
+          else
+                  local = GNUNET_NO;
+#if DEBUG_TCP
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                         "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
+#endif
+          break;
+      }
+    }
+       return local;
+}
+
 /**
  * Add the IP of our network interface to the list of
  * our internal IP addresses.
@@ -2169,6 +2213,21 @@ process_interfaces (void *cls,
 
   af = addr->sa_family;
   arg_nat = NULL;
+
+  if (plugin->use_localaddresses == GNUNET_NO)
+  {
+         if (GNUNET_YES == check_localaddress (addr, addrlen))
+         {
+#if DEBUG_TCP
+          GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                  "tcp",
+                          "Not notifying transport of address `%s' (local address)\n",
+                          GNUNET_a2s (addr, addrlen));
+#endif
+                 return GNUNET_OK;
+         }
+  }
+
   switch (af)
     {
     case AF_INET:
@@ -2254,6 +2313,8 @@ process_interfaces (void *cls,
       GNUNET_break (0);
       return GNUNET_OK;
     }
+  if (plugin->adv_port != 0)
+  {
 #if DEBUG_TCP
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
                   "tcp",
@@ -2263,6 +2324,7 @@ process_interfaces (void *cls,
   plugin->env->notify_address (plugin->env->cls,
                                "tcp",
                                arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
+  }
 
   if (arg_nat != NULL)
     {
@@ -2497,9 +2559,7 @@ tcp_transport_start_nat_server (struct Plugin *plugin)
 #if DEBUG_TCP_NAT
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
                   "tcp"
-                   "Starting %s %s\n", 
-                  "gnunet-nat-server", 
-                  plugin->internal_address);
+                   "Starting %s %s\n", "gnunet-nat-server", plugin->internal_address);
 #endif
   /* Start the server process */
   plugin->server_proc = GNUNET_OS_start_process (NULL,
@@ -2677,7 +2737,7 @@ process_external_ip (void *cls,
       t4.t_port = htons(0);
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 
                       "tcp",
-                      "Notifying transport of address %s:%d\n", 
+                      "Notifying transport of address %s:%d\n",
                       plugin->external_address,
                       0);
     }
@@ -2748,6 +2808,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
   int enable_nat_client;
   int enable_nat_server;
   int enable_upnp;
+  int use_localaddresses;
   char *internal_address;
   char *external_address;
   char *bind_address;
@@ -2899,6 +2960,15 @@ libgnunet_plugin_transport_tcp_init (void *cls)
       return NULL;
     }
 
+  use_localaddresses = GNUNET_NO;
+  if (GNUNET_CONFIGURATION_have_value (env->cfg,
+                 "transport-tcp", "USE_LOCALADDR"))
+    {
+                 use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
+                                                                  "transport-tcp",
+                                                              "USE_LOCALADDR");
+    }
+
   if (aport == 0)
     aport = bport;
   if (bport == 0)
@@ -2929,6 +2999,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
   plugin->enable_nat_client = enable_nat_client;
   plugin->enable_nat_server = enable_nat_server;
   plugin->enable_upnp = enable_upnp;
+  plugin->use_localaddresses = use_localaddresses;
   plugin->env = env;
   plugin->lsock = NULL;
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
index 26644bdd34e86f00161aa690f4670de98a73ca5a..8e6deb0376d8c9f916f2b9c15f8723c8d1dfd320 100644 (file)
@@ -52,7 +52,7 @@
 #include "gnunet_transport_plugin.h"
 #include "transport.h"
 
-#define DEBUG_UDP GNUNET_YES
+#define DEBUG_UDP GNUNET_NO
 
 #define MAX_PROBES 20
 
@@ -462,6 +462,11 @@ struct Plugin
    */
   int only_nat_addresses;
 
+  /**
+   * use local addresses?
+   */
+  int use_localaddresses;
+
   /**
    * The process id of the server process (if behind NAT)
    */
@@ -918,6 +923,45 @@ check_local_addr (struct Plugin *plugin,
   return GNUNET_SYSERR;
 }
 
+static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
+{
+       uint32_t res = 0;
+       int local = GNUNET_NO;
+       int af = addr->sa_family;
+    switch (af)
+    {
+      case AF_INET:
+      {
+         uint32_t netmask = 0x7F000000;
+         uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr);
+         res = (address >> 24) ^ (netmask >> 24);
+         if (res != 0)
+                 local = GNUNET_NO;
+         else
+                 local = GNUNET_YES;
+#if DEBUG_UDP
+           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                         "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
+#endif
+           break;
+      }
+      case AF_INET6:
+      {
+          if (IN6_IS_ADDR_LOOPBACK  (&((struct sockaddr_in6 *) addr)->sin6_addr) ||
+                  IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
+                  local = GNUNET_YES;
+          else
+                  local = GNUNET_NO;
+#if DEBUG_UDP
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                         "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global");
+#endif
+          break;
+      }
+    }
+       return local;
+}
+
 
 /**
  * Add the IP of our network interface to the list of
@@ -941,6 +985,20 @@ process_interfaces (void *cls,
   addr_nat = NULL;
   af = addr->sa_family;
 
+  if (plugin->use_localaddresses == GNUNET_NO)
+  {
+         if (GNUNET_YES == check_localaddress (addr, addrlen))
+         {
+#if DEBUG_UDP
+          GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+                  "udp",
+                          "Not notifying transport of address `%s' (local address)\n",
+                          GNUNET_a2s (addr, addrlen));
+#endif
+                 return GNUNET_OK;
+         }
+  }
+
   memset(buf, 0, INET6_ADDRSTRLEN);
   if (af == AF_INET)
     {
@@ -1271,7 +1329,7 @@ udp_demultiplexer(struct Plugin *plugin,
   struct MessageQueue *pending_message;
   struct MessageQueue *pending_message_temp;
   uint16_t incoming_port;
-
+  struct GNUNET_TRANSPORT_ATS_Information distance[2];
   if (memcmp(sender, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)) == 0)
     {
 #if DEBUG_UDP
@@ -1471,12 +1529,13 @@ udp_demultiplexer(struct Plugin *plugin,
       /* If we receive these just ignore! */
       break;
     default:
+
 #if DEBUG_UDP
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Sending message type %d to transport!\n",
                   ntohs(currhdr->type));
 #endif
-      struct GNUNET_TRANSPORT_ATS_Information distance[2];
+
       distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
       distance[0].value = htonl (UDP_DIRECT_DISTANCE);
       distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
@@ -2167,6 +2226,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
   int behind_nat;
   int allow_nat;
   int only_nat_addresses;
+  int use_localaddresses;
   char *internal_address;
   char *external_address;
   struct IPv4UdpAddress v4_address;
@@ -2271,6 +2331,15 @@ libgnunet_plugin_transport_udp_init (void *cls)
                 _("MTU %llu for `%s' is probably too low!\n"), mtu,
                 "UDP");
 
+  use_localaddresses = GNUNET_NO;
+  if (GNUNET_CONFIGURATION_have_value (env->cfg,
+                 "transport-udp", "USE_LOCALADDR"))
+    {
+      use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
+                                                                  "transport-udp",
+                                                              "USE_LOCALADDR");
+    }
+
   plugin = GNUNET_malloc (sizeof (struct Plugin));
   plugin->external_address = external_address;
   plugin->internal_address = internal_address;
@@ -2279,6 +2348,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
   plugin->allow_nat = allow_nat;
   plugin->only_nat_addresses = only_nat_addresses;
   plugin->env = env;
+  plugin->use_localaddresses = use_localaddresses;
 
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;