determine network scope for ATS even if we do not yet have a session and only have...
[oweals/gnunet.git] / src / transport / plugin_transport_tcp.c
index 3a283e17b6f97c9f6d7ae68da9c8032eae5ab2ae..453a0095f30620d7be247372914e910c80a6f14e 100644 (file)
@@ -14,8 +14,8 @@
 
   You should have received a copy of the GNU General Public License
   along with GNUnet; see the file COPYING.  If not, write to the
-  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-  Boston, MA 02111-1307, USA.
+  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA 02110-1301, USA.
  */
 /**
  * @file transport/plugin_transport_tcp.c
@@ -154,7 +154,7 @@ struct IPv4TcpAddress
    * Optional options and flags for this address,
    * see `enum TcpAddressOptions`
    */
-  uint32_t options;
+  uint32_t options GNUNET_PACKED;
 
   /**
    * IPv4 address, in network byte order.
@@ -177,7 +177,7 @@ struct IPv6TcpAddress
    * Optional flags for this address
    * see `enum TcpAddressOptions`
    */
-  uint32_t options;
+  uint32_t options GNUNET_PACKED;
 
   /**
    * IPv6 address.
@@ -1887,6 +1887,9 @@ append_port (void *cls,
   struct Plugin *plugin = ppc->plugin;
   char *ret;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "append_port called with hostname `%s'\n",
+              hostname);
   if (NULL == hostname)
   {
     /* Final call, done */
@@ -1982,6 +1985,9 @@ tcp_plugin_address_pretty_printer (void *cls,
   else
   {
     /* invalid address */
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         _("Unexpected address length: %u bytes\n"),
+         (unsigned int) addrlen);
     asc (asc_cls, NULL, GNUNET_SYSERR);
     asc (asc_cls, NULL, GNUNET_OK);
     return;
@@ -1996,6 +2002,8 @@ tcp_plugin_address_pretty_printer (void *cls,
   ppc->asc_cls = asc_cls;
   ppc->port = port;
   ppc->options = options;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Starting DNS reverse lookup\n");
   ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sb,
                                                        sbs,
                                                        ! numeric,
@@ -2545,6 +2553,8 @@ connect_notify (void *cls,
 {
   struct Plugin *plugin = cls;
 
+  if (NULL == client)
+    return;
   plugin->cur_connections++;
   GNUNET_STATISTICS_set (plugin->env->stats,
                          gettext_noop ("# TCP server connections active"),
@@ -2583,7 +2593,10 @@ disconnect_notify (void *cls,
 
   if (NULL == client)
     return;
-  session = lookup_session_by_client (plugin, client);
+  GNUNET_assert (plugin->cur_connections >= 1);
+  plugin->cur_connections--;
+  session = lookup_session_by_client (plugin,
+                                      client);
   if (NULL == session)
     return; /* unknown, nothing to do */
   LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -2601,8 +2614,6 @@ disconnect_notify (void *cls,
                               GNUNET_NO);
     GNUNET_SERVER_resume (plugin->server); /* Resume server  */
   }
-  GNUNET_assert (plugin->cur_connections >= 1);
-  plugin->cur_connections--;
   GNUNET_STATISTICS_set (plugin->env->stats,
                          gettext_noop ("# TCP server connections active"),
                          plugin->cur_connections,
@@ -2722,6 +2733,66 @@ tcp_plugin_get_network (void *cls,
 }
 
 
+/**
+ * Function obtain the network type for an address.
+ *
+ * @param cls closure (`struct Plugin *`)
+ * @param address the address
+ * @return the network type
+ */
+static enum GNUNET_ATS_Network_Type
+tcp_plugin_get_network_for_address (void *cls,
+                                    const struct GNUNET_HELLO_Address *address)
+{
+  struct Plugin *plugin = cls;
+  size_t addrlen;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4TcpAddress *t4;
+  const struct IPv6TcpAddress *t6;
+  const void *sb;
+  size_t sbs;
+
+  addrlen = address->address_length;
+  if (addrlen == sizeof(struct IPv6TcpAddress))
+  {
+    GNUNET_assert (NULL != address->address); /* make static analysis happy */
+    t6 = address->address;
+    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->t6_port;
+    memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof(struct in6_addr));
+    sb = &a6;
+    sbs = sizeof(a6);
+  }
+  else if (addrlen == sizeof(struct IPv4TcpAddress))
+  {
+    GNUNET_assert (NULL != address->address); /* make static analysis happy */
+    t4 = address->address;
+    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->t4_port;
+    a4.sin_addr.s_addr = t4->ipv4_addr;
+    sb = &a4;
+    sbs = sizeof(a4);
+  }
+  else
+  {
+    GNUNET_break (0);
+    return GNUNET_ATS_NET_UNSPECIFIED;
+  }
+  return plugin->env->get_address_type (plugin->env->cls,
+                                        sb,
+                                        sbs);
+}
+
+
 /**
  * Return information about the given session to the
  * monitor callback.
@@ -2949,7 +3020,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
                              (const struct sockaddr **) addrs, addrlens,
                              &tcp_nat_port_map_callback,
                              &try_connection_reversal,
-                             plugin);
+                             plugin, NULL);
     for (ret = ret_s -1; ret >= 0; ret--)
       GNUNET_free (addrs[ret]);
     GNUNET_free_non_null (addrs);
@@ -2965,7 +3036,8 @@ libgnunet_plugin_transport_tcp_init (void *cls)
                                        NULL,
                                        NULL,
                                        &try_connection_reversal,
-                                       plugin);
+                                       plugin,
+                                       NULL);
   }
   api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions);
   api->cls = plugin;
@@ -2979,6 +3051,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
   api->address_to_string = &tcp_plugin_address_to_string;
   api->string_to_address = &tcp_plugin_string_to_address;
   api->get_network = &tcp_plugin_get_network;
+  api->get_network_for_address = &tcp_plugin_get_network_for_address;
   api->update_session_timeout = &tcp_plugin_update_session_timeout;
   api->update_inbound_delay = &tcp_plugin_update_inbound_delay;
   api->setup_monitor = &tcp_plugin_setup_monitor;