wan/lan detection in plugins
authorMatthias Wachs <wachs@net.in.tum.de>
Wed, 14 Dec 2011 13:32:40 +0000 (13:32 +0000)
committerMatthias Wachs <wachs@net.in.tum.de>
Wed, 14 Dec 2011 13:32:40 +0000 (13:32 +0000)
src/include/gnunet_ats_service.h
src/transport/gnunet-service-transport.c
src/transport/plugin_transport_http.c
src/transport/plugin_transport_udp.c
src/transport/plugin_transport_unix.c

index 4218557108bc0de8b964eec7a5d97cbe3a32b74d..bd55b8c3abbe8d01f150bb5d8aab25f99c184e7b 100644 (file)
 
 enum GNUNET_ATS_Network_Type
 {
-  GNUNET_ATS_NET_UNSPECIFIED,
-  GNUNET_ATS_NET_LOOPBACK,
-  GNUNET_ATS_NET_LAN,
-  GNUNET_ATS_NET_WAN
+  GNUNET_ATS_NET_UNSPECIFIED = 0,
+  GNUNET_ATS_NET_LOOPBACK = 1,
+  GNUNET_ATS_NET_LAN = 2,
+  GNUNET_ATS_NET_WAN = 3
 };
 
 /**
index 8294f35dc2a85c2df6e1240f5b1fa41367532b37..f0e26a434516c8fc7f2184b3224ddb70043e3c54 100644 (file)
@@ -381,7 +381,9 @@ plugin_env_address_to_type (void *cls,
     GNUNET_break (0);
     return ats;
   }
-  if ((addrlen != sizeof (struct sockaddr_in)) && (addrlen != sizeof (struct sockaddr_in6)))
+  if (((addr->sa_family != AF_INET) && (addrlen != sizeof (struct sockaddr_in))) &&
+      ((addr->sa_family != AF_INET6) && (addrlen != sizeof (struct sockaddr_in6))) &&
+      (addr->sa_family != AF_UNIX))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed address with length %u `%s'\n",
                 addrlen,
index b290e5ba2a1dbf8b39ea8b128eeb5298ce895f9e..177a7171958a12dbd28920d23e5064013cfc074f 100644 (file)
@@ -577,6 +577,9 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
       s4.sin_family = AF_INET;
       s4.sin_addr.s_addr = a4->ipv4_addr;
       s4.sin_port = a4->u4_port;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      s4.sin_len = sizeof (struct sockaddr_in);
+#endif
       ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s4, sizeof (struct sockaddr_in));
 
       if ((ntohs (a4->u4_port) == 0) || (plugin->ipv4 == GNUNET_NO))
@@ -590,6 +593,9 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
       s6.sin6_family = AF_INET6;
       s6.sin6_addr = a6->ipv6_addr;
       s6.sin6_port = a6->u6_port;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      s6.sin6_len = sizeof (struct sockaddr_in6);
+#endif
       ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s6, sizeof (struct sockaddr_in6));
 
       if ((ntohs (a6->u6_port) == 0) || (plugin->ipv6 == GNUNET_NO))
index 1ef0bca982a8782fe8f5908b618a3e2095054267..04ec108aa2d4052f8b717f4a74680ef9ef2ff66c 100644 (file)
@@ -192,6 +192,11 @@ struct Session
 
   size_t addrlen;
 
+  /**
+   * ATS network type in NBO
+   */
+  uint32_t ats_address_network_type;
+
   /**
    * Function to call upon completion of the transmission.
    */
@@ -693,6 +698,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
   struct sockaddr_in *v4;
   struct sockaddr_in6 *v6;
   size_t len;
+  struct GNUNET_ATS_Information ats;
 
   switch (addrlen)
   {
@@ -712,6 +718,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
 #endif
     v4->sin_port = t4->u4_port;
     v4->sin_addr.s_addr = t4->ipv4_addr;
+    ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) v4, sizeof (struct sockaddr_in));
     break;
   case sizeof (struct IPv6UdpAddress):
     if (NULL == plugin->sockv6)
@@ -729,6 +736,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
 #endif
     v6->sin6_port = t6->u6_port;
     v6->sin6_addr = t6->ipv6_addr;
+    ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) v6, sizeof (struct sockaddr_in6));
     break;
   default:
     /* Must have a valid address to send to */
@@ -736,6 +744,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
     return NULL;
   }
 
+  peer_session->ats_address_network_type = ats.value;
   peer_session->valid_until = GNUNET_TIME_absolute_get_zero ();
   peer_session->invalidation_task = GNUNET_SCHEDULER_NO_TASK;
   peer_session->addrlen = len;
@@ -971,17 +980,22 @@ process_inbound_tokenized_messages (void *cls, void *client,
 {
   struct Plugin *plugin = cls;
   struct SourceInformation *si = client;
-  struct GNUNET_ATS_Information distance;
+  struct GNUNET_ATS_Information atsi[2];
   struct GNUNET_TIME_Relative delay;
 
   /* setup ATS */
-  distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
-  distance.value = htonl (1);
+  atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+  atsi[0].value = htonl (1);
+  atsi[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+  atsi[1].value = si->session->ats_address_network_type;
+  GNUNET_break (ntohl(si->session->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED);
+
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving Session %X %s  to transport\n",
        si->session, GNUNET_i2s (&si->session->target));
   delay =
-      plugin->env->receive (plugin->env->cls, &si->sender, hdr, &distance, 1,
+      plugin->env->receive (plugin->env->cls, &si->sender, hdr,
+                            (const struct GNUNET_ATS_Information *) &atsi, 2,
                             si->session, si->arg, si->args);
   si->session->flow_delay_for_other_peer = delay;
 }
@@ -1021,6 +1035,7 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
   struct SourceInformation si;
   struct IPv4UdpAddress u4;
   struct IPv6UdpAddress u6;
+  struct GNUNET_ATS_Information ats;
   const void *arg;
   size_t args;
 
@@ -1036,6 +1051,8 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
     return;
   }
 
+  ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
+  ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED);
   /* convert address */
   switch (sender_addr->sa_family)
   {
@@ -1085,6 +1102,8 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
   else
   {
     s = create_session (plugin, &udp_msg->sender, arg, args, NULL, NULL);
+    ats = plugin->env->get_address_type (plugin->env->cls, sender_addr, sender_addr_len);
+    s->ats_address_network_type = ats.value;
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Creating inbound UDP sessions 0x%X for peer `%s' address `%s'\n", s,
          GNUNET_i2s (&s->target), udp_address_to_string (NULL, arg, args));
@@ -1247,6 +1266,10 @@ struct Mstv4Context
   struct Plugin *plugin;
 
   struct IPv4UdpAddress addr;
+  /**
+   * ATS network type in NBO
+   */
+  uint32_t ats_address_network_type;
 };
 
 struct Mstv6Context
@@ -1254,6 +1277,10 @@ struct Mstv6Context
   struct Plugin *plugin;
 
   struct IPv6UdpAddress addr;
+  /**
+   * ATS network type in NBO
+   */
+  uint32_t ats_address_network_type;
 };
 
 
@@ -1279,6 +1306,7 @@ udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
   struct FindReceiveContext frc;
   struct Session *s = NULL;
   struct GNUNET_TIME_Relative flow_delay;
+  struct GNUNET_ATS_Information ats;
 
   fromlen = sizeof (addr);
   memset (&addr, 0, sizeof (addr));
@@ -1318,6 +1346,8 @@ udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
 
       mc->addr.ipv4_addr = av4->sin_addr.s_addr;
       mc->addr.u4_port = av4->sin_port;
+      ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &addr, fromlen);
+      mc->ats_address_network_type = ats.value;
       if (GNUNET_OK !=
           GNUNET_SERVER_mst_receive (plugin->broadcast_ipv4_mst, mc, buf, ret,
                                      GNUNET_NO, GNUNET_NO))
@@ -1336,6 +1366,8 @@ udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
 
       mc->addr.ipv6_addr = av6->sin6_addr;
       mc->addr.u6_port = av6->sin6_port;
+      ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &addr, fromlen);
+      mc->ats_address_network_type = ats.value;
 
       if (GNUNET_OK !=
           GNUNET_SERVER_mst_receive (plugin->broadcast_ipv6_mst, mc, buf, ret,
@@ -1515,13 +1547,18 @@ broadcast_ipv4_mst_cb (void *cls, void *client,
        ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
        udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
 
-  struct GNUNET_ATS_Information ats;
+  struct GNUNET_ATS_Information atsi[2];
 
-  ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
-  ats.value = htonl (1);
+  /* setup ATS */
+  atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+  atsi[0].value = htonl (1);
+  atsi[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+  atsi[1].value = mc->ats_address_network_type;
+  GNUNET_break (ntohl(mc->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED);
 
   hello = (struct GNUNET_MessageHeader *) &msg[1];
-  plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL,
+  plugin->env->receive (plugin->env->cls, &msg->sender, hello,
+                        (const struct GNUNET_ATS_Information *) &atsi, 2, NULL,
                         (const char *) &mc->addr, sizeof (mc->addr));
 
   GNUNET_STATISTICS_update (plugin->env->stats,
@@ -1553,13 +1590,18 @@ broadcast_ipv6_mst_cb (void *cls, void *client,
        ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
        udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
 
-  struct GNUNET_ATS_Information ats;
+  struct GNUNET_ATS_Information atsi[2];
 
-  ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
-  ats.value = htonl (1);
+  /* setup ATS */
+  atsi[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+  atsi[0].value = htonl (1);
+  atsi[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+  atsi[1].value = mc->ats_address_network_type;
+  GNUNET_break (ntohl(mc->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED);
 
   hello = (struct GNUNET_MessageHeader *) &msg[1];
-  plugin->env->receive (plugin->env->cls, &msg->sender, hello, &ats, 1, NULL,
+  plugin->env->receive (plugin->env->cls, &msg->sender, hello,
+                        (const struct GNUNET_ATS_Information *) &atsi, 2, NULL,
                         (const char *) &mc->addr, sizeof (mc->addr));
 
   GNUNET_STATISTICS_update (plugin->env->stats,
index fc5719b3d7751f1ffc77c165d45c9663c882c616..5f6c967f295f1985d54da174ced76edcde26afe2 100644 (file)
@@ -331,6 +331,10 @@ struct Plugin
    */
   char *unix_socket_path;
 
+  /**
+   * ATS network
+   */
+  struct GNUNET_ATS_Information ats_network;
 };
 
 /**
@@ -723,8 +727,8 @@ unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
 
   ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
   ats[0].value = htonl (UNIX_DIRECT_DISTANCE);
-  ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
-  ats[1].value = htonl (GNUNET_ATS_NET_LOOPBACK);
+  ats[1] = plugin->ats_network;
+  GNUNET_break (ntohl(plugin->ats_network.value) != GNUNET_ATS_NET_UNSPECIFIED);
 
   GNUNET_assert (fromlen >= sizeof (struct sockaddr_un));
 
@@ -867,7 +871,7 @@ unix_transport_server_start (void *cls)
 #if LINUX
   un.sun_path[0] = '\0';
 #endif
-
+  plugin->ats_network = plugin->env->get_address_type (plugin->env->cls, serverAddr, addrlen);
   plugin->unix_sock.desc =
       GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
   if (NULL == plugin->unix_sock.desc)