fixes to plugin API for DV
authorChristian Grothoff <christian@grothoff.org>
Mon, 28 Jun 2010 11:07:52 +0000 (11:07 +0000)
committerChristian Grothoff <christian@grothoff.org>
Mon, 28 Jun 2010 11:07:52 +0000 (11:07 +0000)
src/transport/Makefile.am
src/transport/gnunet-service-transport.c
src/transport/plugin_transport.h
src/transport/plugin_transport_tcp.c
src/transport/plugin_transport_template.c
src/transport/plugin_transport_udp.c

index e65c932861119b4a4c16e68ea80ecc852d98c231..58e02f99556ad2483a839eb062e2d1d443562752 100644 (file)
@@ -6,7 +6,7 @@ if MINGW
   WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
 endif
 
-if HAVE_MHD 
+if MINGW
  GN_LIBMHD = -lmicrohttpd
  HTTP_PLUGIN_LA = libgnunet_plugin_transport_http.la
  HTTP_PLUGIN_CHECK = test_plugin_transport_http
index 56480d02009b31f6b8b860b1b124314e2816bec0..4390377a666cac6c0930e94b796c847039fef97d 100644 (file)
@@ -4338,6 +4338,18 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
       /* peer wants to confirm that this is one of our addresses */
       addr += slen;
       alen -= slen;
+      if (GNUNET_OK !=
+         plugin->api->check_address (plugin->api->cls,
+                                     addr,
+                                     alen))
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                     _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
+                     a2s (plugin->short_name,
+                          addr,
+                          alen));
+         return GNUNET_NO;
+       }
       oal = plugin->addresses;
       while (NULL != oal)
        {
@@ -4348,15 +4360,6 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
            break;
          oal = oal->next;
        }
-      if (oal == NULL)
-       {
-         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                     _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
-                     a2s (plugin->short_name,
-                          addr,
-                          alen));
-         return GNUNET_NO;
-       }
       pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
       pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen);
       pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
@@ -4372,8 +4375,9 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
             &my_identity, 
             sizeof(struct GNUNET_PeerIdentity));
       memcpy (&pong[1], plugin->short_name, slen);
-      memcpy (&((char*)&pong[1])[slen], &oal[1], alen);
-      if (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4)
+      memcpy (&((char*)&pong[1])[slen], addr, alen);
+      if ( (oal != NULL) &&
+          (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4) )
        {
          /* create / update cached sig */
 #if DEBUG_TRANSPORT
@@ -4386,15 +4390,28 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
          GNUNET_assert (GNUNET_OK ==
                         GNUNET_CRYPTO_rsa_sign (my_private_key,
                                                 &pong->purpose,
-                                                &oal->pong_signature));
+                                                &oal->pong_signature));            
+         memcpy (&pong->signature,
+                 &oal->pong_signature,
+                 sizeof (struct GNUNET_CRYPTO_RsaSignature));    
+       }
+      else if (oal == NULL)
+       {
+         /* not using cache (typically DV-only) */
+         pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
+         GNUNET_assert (GNUNET_OK ==
+                        GNUNET_CRYPTO_rsa_sign (my_private_key,
+                                                &pong->purpose,
+                                                &pong->signature));        
        }
       else
        {
+         /* can used cached version */
          pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
+         memcpy (&pong->signature,
+                 &oal->pong_signature,
+                 sizeof (struct GNUNET_CRYPTO_RsaSignature));    
        }
-      memcpy (&pong->signature,
-             &oal->pong_signature,
-             sizeof (struct GNUNET_CRYPTO_RsaSignature));    
     }
   n = find_neighbour(peer);
   GNUNET_assert (n != NULL);
index bb64a1bfc904e6562b90557c85852e2368b07af8..ef5303df5d1335cc9e0bce012ece86de38b5bd4a 100644 (file)
@@ -359,16 +359,18 @@ typedef void
  * 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.
+ * legal for establishing a connection to this peer (and make sure that
+ * the address really corresponds to our network connection/settings
+ * and not some potential man-in-the-middle).
  *
- * @param addr pointer to the address, may be modified (slightly)
+ * @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, GNUNET_SYSERR if not
  */
 typedef int
-  (*GNUNET_TRANSPORT_CheckAddress) (void *cls,
-                                   void *addr, size_t addrlen);
+(*GNUNET_TRANSPORT_CheckAddress) (void *cls,
+                                 const void *addr, size_t addrlen);
 
 
 /**
@@ -426,15 +428,15 @@ struct GNUNET_TRANSPORT_PluginFunctions
 
   /**
    * 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!
+   * for this plugin is well-formed and corresponds to an
+   * address for THIS peer (as per our configuration).  Naturally,
+   * if absolutely necessary, plugins can be a bit conservative in
+   * their answer, but in general plugins should make sure that the
+   * address does not redirect traffic to a 3rd party that might
+   * try to man-in-the-middle our traffic.
    */
   GNUNET_TRANSPORT_CheckAddress check_address;
 
-
   /**
    * Function that will be called to convert a binary address
    * to a string (numeric conversion only).
index 08bb00ff6b179c19cef416abe29c69c38d5daa9c..edf403ac6aaab762fd906e4f020917ce42afdb47 100644 (file)
@@ -1366,29 +1366,29 @@ tcp_plugin_address_pretty_printer (void *cls,
 /**
  * Check if the given port is plausible (must be either
  * our listen port or our advertised port).  If it is
- * neither, we return one of these two ports at random.
+ * neither, we return GNUNET_SYSERR.
  *
  * @param plugin global variables
  * @param in_port port number to check
- * @return either in_port or a more plausible port
+ * @return GNUNET_OK if port is either open_port or adv_port
  */
-static uint16_t
+static int
 check_port (struct Plugin *plugin, uint16_t in_port)
 {
   if ((in_port == plugin->adv_port) || (in_port == plugin->open_port))
-    return in_port;
-  return (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
-                                    2) == 0)
-    ? plugin->open_port : plugin->adv_port;
+    return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 
-/**
- * Another peer has suggested an address for this peer and transport
- * 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.
+/** 
+ * Function that will be called to check if a binary address for this
+ * plugin is well-formed and corresponds to an address for THIS peer
+ * (as per our configuration).  Naturally, if absolutely necessary,
+ * plugins can be a bit conservative in their answer, but in general
+ * plugins should make sure that the address does not redirect
+ * traffic to a 3rd party that might try to man-in-the-middle our
+ * traffic.
  *
  * @param cls closure, our 'struct Plugin*'
  * @param addr pointer to the address
@@ -1397,7 +1397,9 @@ check_port (struct Plugin *plugin, uint16_t in_port)
  *         and transport, GNUNET_SYSERR if not
  */
 static int
-tcp_plugin_check_address (void *cls, void *addr, size_t addrlen)
+tcp_plugin_check_address (void *cls, 
+                         const void *addr, 
+                         size_t addrlen)
 {
   struct Plugin *plugin = cls;
   struct IPv4TcpAddress *v4;
@@ -1412,7 +1414,10 @@ tcp_plugin_check_address (void *cls, void *addr, size_t addrlen)
   if (addrlen == sizeof (struct IPv4TcpAddress))
     {
       v4 = (struct IPv4TcpAddress *) addr;
-      v4->t_port = htons (check_port (plugin, ntohs (v4->t_port)));
+      if (GNUNET_OK !=
+         check_port (plugin, ntohs (v4->t_port)))
+       return GNUNET_SYSERR;
+      /* FIXME: check IP! */
     }
   else
     {
@@ -1422,7 +1427,10 @@ tcp_plugin_check_address (void *cls, void *addr, size_t addrlen)
          GNUNET_break_op (0);
          return GNUNET_SYSERR;
        }
-      v6->t6_port = htons (check_port (plugin, ntohs (v6->t6_port)));
+      if (GNUNET_OK != 
+         check_port (plugin, ntohs (v6->t6_port)))
+       return GNUNET_SYSERR;
+      /* FIXME: check IP! */
     }
   return GNUNET_OK;
 }
index f5eec84d3f943cfea14eb415b69f6fb2fb177542..27cb9044ed57adb48eee44eef5c178d307616c54 100644 (file)
@@ -232,7 +232,8 @@ template_plugin_address_pretty_printer (void *cls,
  */
 static int
 template_plugin_address_suggested (void *cls,
-                                  void *addr, size_t addrlen)
+                                  const void *addr,
+                                  size_t addrlen)
 {
   /* struct Plugin *plugin = cls; */
 
index 52e59818901d4974d95a9ef0eb248f5d7849e763..724dfe6b3fc6f8e02fbb0b2e82636bad3189df88 100644 (file)
@@ -1586,47 +1586,77 @@ udp_transport_server_start (void *cls)
 }
 
 
+
+/**
+ * Check if the given port is plausible (must be either
+ * our listen port or our advertised port).  If it is
+ * neither, we return GNUNET_SYSERR.
+ *
+ * @param plugin global variables
+ * @param in_port port number to check
+ * @return GNUNET_OK if port is either open_port or adv_port
+ */
+static int
+check_port (struct Plugin *plugin, uint16_t in_port)
+{
+  if (in_port == plugin->port) 
+    return GNUNET_OK;
+  return GNUNET_SYSERR;
+}
+
+
 /**
- * Another peer has suggested an address for this peer and transport
- * 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.
+ * Function that will be called to check if a binary address for this
+ * plugin is well-formed and corresponds to an address for THIS peer
+ * (as per our configuration).  Naturally, if absolutely necessary,
+ * plugins can be a bit conservative in their answer, but in general
+ * plugins should make sure that the address does not redirect
+ * traffic to a 3rd party that might try to man-in-the-middle our
+ * traffic.
  *
  * @param cls closure, should be our handle to the Plugin
- * @param addr pointer to the address, may be modified (slightly)
+ * @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, GNUNET_SYSERR if not
  *
  */
 static int
-udp_check_address (void *cls, void *addr, size_t addrlen)
+udp_check_address (void *cls, 
+                  const 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 (plugin->port);
+      v4 = (struct IPv4UdpAddress *) addr;
+      if (GNUNET_OK !=
+         check_port (plugin, ntohs (v4->u_port)))
+       return GNUNET_SYSERR;
+      /* FIXME: check IP! */
     }
   else
     {
-      v6 = (struct sockaddr_in6 *) buf;
-      v6->sin6_port = htons (plugin->port);
+      v6 = (struct IPv6UdpAddress *) addr;
+      if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
+       {
+         GNUNET_break_op (0);
+         return GNUNET_SYSERR;
+       }
+      if (GNUNET_OK != 
+         check_port (plugin, ntohs (v6->u6_port)))
+       return GNUNET_SYSERR;
+      /* FIXME: check IP! */
     }
-
 #if DEBUG_UDP
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
                    "udp",