fix
[oweals/gnunet.git] / src / dv / plugin_transport_dv.c
index 30e5b6ac1278aa7ab6bde9900e5c5cfabf4d8068..5e2a6bd6c072ee677f9b760d3a156241fdebb070 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 #include "gnunet_statistics_service.h"
 #include "gnunet_dv_service.h"
 #include "gnunet_transport_service.h"
 #include "gnunet_statistics_service.h"
 #include "gnunet_dv_service.h"
 #include "gnunet_transport_service.h"
-#include "../transport/plugin_transport.h"
+#include "gnunet_transport_plugin.h"
 #include "dv.h"
 
 #include "dv.h"
 
-#define DEBUG_TEMPLATE GNUNET_NO
+#define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING
 
 /**
  * Encapsulation of all of the state of the plugin.
 
 /**
  * Encapsulation of all of the state of the plugin.
@@ -144,31 +144,35 @@ struct Plugin
 /**
  * Handler for messages received from the DV service.
  */
 /**
  * Handler for messages received from the DV service.
  */
-void handle_dv_message_received (void *cls,
-                                 struct GNUNET_PeerIdentity *sender,
-                                 char *msg,
-                                 size_t msg_len,
-                                 uint32_t distance,
-                                 char *sender_address,
-                                 size_t sender_address_len)
+void
+handle_dv_message_received (void *cls, struct GNUNET_PeerIdentity *sender,
+                            char *msg, size_t msg_len, uint32_t distance,
+                            char *sender_address, size_t sender_address_len)
 {
   struct Plugin *plugin = cls;
 {
   struct Plugin *plugin = cls;
+
 #if DEBUG_DV_MESSAGES
   char *my_id;
 #if DEBUG_DV_MESSAGES
   char *my_id;
-  my_id = GNUNET_strdup(GNUNET_i2s(plugin->env->my_identity));
-  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-                   "plugin_transport_dv",
-                   _("%s Received message from %s) of type %d, distance %u!\n"),
-                   my_id, GNUNET_i2s(sender), ntohs(((struct GNUNET_MessageHeader *)msg)->type), distance);
-  GNUNET_free_non_null(my_id);
+
+  my_id = GNUNET_strdup (GNUNET_i2s (plugin->env->my_identity));
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "plugin_transport_dv",
+                   _("%s Received message from %s of type %d, distance %u!\n"),
+                   my_id, GNUNET_i2s (sender),
+                   ntohs (((struct GNUNET_MessageHeader *) msg)->type),
+                   distance);
+  GNUNET_free_non_null (my_id);
 #endif
 #endif
-  plugin->env->receive(plugin->env->cls,
-                       sender,
-                       (struct GNUNET_MessageHeader *)msg,
-                       distance,
-                      NULL,
-                       sender_address,
-                       sender_address_len);
+  struct GNUNET_ATS_Information ats[2];
+
+  ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+  ats[0].value = htonl (distance);
+  ats[1].type = htonl (GNUNET_ATS_ARRAY_TERMINATOR);
+  ats[1].value = htonl (0);
+
+  plugin->env->receive (plugin->env->cls, sender,
+                        (struct GNUNET_MessageHeader *) msg,
+                        (const struct GNUNET_ATS_Information *) &ats,
+                        2, NULL, sender_address, sender_address_len);
 
 }
 
 
 }
 
@@ -205,36 +209,18 @@ void handle_dv_message_received (void *cls,
  *         and does NOT mean that the message was not transmitted (DV)
  */
 static ssize_t
  *         and does NOT mean that the message was not transmitted (DV)
  */
 static ssize_t
-dv_plugin_send (void *cls,
-                const struct GNUNET_PeerIdentity *target,
-                const char *msgbuf,
-                size_t msgbuf_size,
-                unsigned int priority,
-                struct GNUNET_TIME_Relative timeout,
-               struct Session *session,
-                const void *addr,
-                size_t addrlen,
-                int force_address,
-                GNUNET_TRANSPORT_TransmitContinuation
-                cont, void *cont_cls)
+dv_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
+                const char *msgbuf, size_t msgbuf_size, unsigned int priority,
+                struct GNUNET_TIME_Relative timeout, struct Session *session,
+                const void *addr, size_t addrlen, int force_address,
+                GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 {
   int ret = 0;
   struct Plugin *plugin = cls;
 
 {
   int ret = 0;
   struct Plugin *plugin = cls;
 
-  ret = GNUNET_DV_send(plugin->dv_handle,
-                       target,
-                       msgbuf,
-                       msgbuf_size,
-                       priority,
-                       timeout,
-                       addr,
-                       addrlen,
-                       cont,
-                       cont_cls);
-#if DEBUG_DV
-  GNUNET_free_non_null(my_identity);
-#endif
-
+  ret =
+      GNUNET_DV_send (plugin->dv_handle, target, msgbuf, msgbuf_size, priority,
+                      timeout, addr, addrlen, cont, cont_cls);
   return ret;
 }
 
   return ret;
 }
 
@@ -249,8 +235,7 @@ dv_plugin_send (void *cls,
  * @param target peer from which to disconnect
  */
 static void
  * @param target peer from which to disconnect
  */
 static void
-dv_plugin_disconnect (void *cls,
-                      const struct GNUNET_PeerIdentity *target)
+dv_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
 {
   // struct Plugin *plugin = cls;
   // TODO: Add message type to send to dv service to "disconnect" a peer
 {
   // struct Plugin *plugin = cls;
   // TODO: Add message type to send to dv service to "disconnect" a peer
@@ -272,35 +257,37 @@ dv_plugin_disconnect (void *cls,
  * @param asc_cls closure for asc
  */
 static void
  * @param asc_cls closure for asc
  */
 static void
-dv_plugin_address_pretty_printer (void *cls,
-                                  const char *type,
-                                  const void *addr,
-                                  size_t addrlen,
-                                  int numeric,
+dv_plugin_address_pretty_printer (void *cls, const char *type, const void *addr,
+                                  size_t addrlen, int numeric,
                                   struct GNUNET_TIME_Relative timeout,
                                   struct GNUNET_TIME_Relative timeout,
-                                  GNUNET_TRANSPORT_AddressStringCallback
-                                  asc, void *asc_cls)
+                                  GNUNET_TRANSPORT_AddressStringCallback asc,
+                                  void *asc_cls)
 {
   char *dest_peer;
   char *via_peer;
   char *print_string;
 {
   char *dest_peer;
   char *via_peer;
   char *print_string;
-  char *addr_buf = (char *)addr;
+  char *addr_buf = (char *) addr;
 
 
-  if (addrlen != sizeof(struct GNUNET_PeerIdentity) * 2)
-    {
-      asc (asc_cls, NULL);
-    }
+  if (addrlen != sizeof (struct GNUNET_PeerIdentity) * 2)
+  {
+    asc (asc_cls, NULL);
+  }
   else
   else
-    {
-      dest_peer = GNUNET_strdup(GNUNET_i2s((struct GNUNET_PeerIdentity *)addr));
-      via_peer = GNUNET_strdup(GNUNET_i2s((struct GNUNET_PeerIdentity *)&addr_buf[sizeof(struct GNUNET_PeerIdentity)]));
-      GNUNET_asprintf(&print_string, "DV Peer `%s' via peer`%s'", dest_peer, via_peer);
-      asc (asc_cls, print_string);
-      asc (asc_cls, NULL);
-      GNUNET_free(via_peer);
-      GNUNET_free(dest_peer);
-      GNUNET_free(print_string);
-    }
+  {
+    dest_peer =
+        GNUNET_strdup (GNUNET_i2s ((struct GNUNET_PeerIdentity *) addr));
+    via_peer =
+        GNUNET_strdup (GNUNET_i2s
+                       ((struct GNUNET_PeerIdentity *)
+                        &addr_buf[sizeof (struct GNUNET_PeerIdentity)]));
+    GNUNET_asprintf (&print_string, "DV Peer `%s' via peer`%s'", dest_peer,
+                     via_peer);
+    asc (asc_cls, print_string);
+    asc (asc_cls, NULL);
+    GNUNET_free (via_peer);
+    GNUNET_free (dest_peer);
+    GNUNET_free (print_string);
+  }
 }
 
 /**
 }
 
 /**
@@ -312,9 +299,8 @@ dv_plugin_address_pretty_printer (void *cls,
  *
  * @return string representing the DV address
  */
  *
  * @return string representing the DV address
  */
-static const char *address_to_string (void *cls,
-                                       const void *addr,
-                                       size_t addrlen)
+static const char *
+address_to_string (void *cls, const void *addr, size_t addrlen)
 {
   static char return_buffer[2 * 4 + 2]; // Two four character peer identity prefixes a ':' and '\0'
 
 {
   static char return_buffer[2 * 4 + 2]; // Two four character peer identity prefixes a ':' and '\0'
 
@@ -322,23 +308,22 @@ static const char *address_to_string (void *cls,
   struct GNUNET_CRYPTO_HashAsciiEncoded via_hash;
   struct GNUNET_PeerIdentity *peer;
   struct GNUNET_PeerIdentity *via;
   struct GNUNET_CRYPTO_HashAsciiEncoded via_hash;
   struct GNUNET_PeerIdentity *peer;
   struct GNUNET_PeerIdentity *via;
-  char *addr_buf = (char *)addr;
+  char *addr_buf = (char *) addr;
 
 
-  if (addrlen == (2 * sizeof(struct GNUNET_PeerIdentity)))
-    {
-      peer = (struct GNUNET_PeerIdentity *)addr_buf;
-      via = (struct GNUNET_PeerIdentity *)&addr_buf[sizeof(struct GNUNET_PeerIdentity)];
-
-      GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &peer_hash);
-      peer_hash.encoding[4] = '\0';
-      GNUNET_CRYPTO_hash_to_enc (&via->hashPubKey, &via_hash);
-      via_hash.encoding[4] = '\0';
-      GNUNET_snprintf (return_buffer,
-                       sizeof (return_buffer),
-                       "%s:%s",
-                       &peer_hash,
-                       &via_hash);
-    }
+  if (addrlen == (2 * sizeof (struct GNUNET_PeerIdentity)))
+  {
+    peer = (struct GNUNET_PeerIdentity *) addr_buf;
+    via =
+        (struct GNUNET_PeerIdentity *)
+        &addr_buf[sizeof (struct GNUNET_PeerIdentity)];
+
+    GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &peer_hash);
+    peer_hash.encoding[4] = '\0';
+    GNUNET_CRYPTO_hash_to_enc (&via->hashPubKey, &via_hash);
+    via_hash.encoding[4] = '\0';
+    GNUNET_snprintf (return_buffer, sizeof (return_buffer), "%s:%s", &peer_hash,
+                     &via_hash);
+  }
   else
     return NULL;
 
   else
     return NULL;
 
@@ -346,28 +331,43 @@ static const char *address_to_string (void *cls,
 }
 
 /**
 }
 
 /**
- * Another peer has suggested an address for this
- * peer and transport plugin.  Check that this could be a valid
- * address.  If so, consider adding it to the list
- * of addresses.
+ * 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 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 cls closure
  * @param addr pointer to the address
  * @param addrlen length of addr
  * @return GNUNET_OK if this is a plausible address for this peer
  *
  * @param cls closure
  * @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
+ *         and transport, GNUNET_SYSERR if not
  *
  *
- * FIXME: does this mean anything for the DV plugin?
  */
 static int
  */
 static int
-dv_plugin_address_suggested (void *cls,
-                                  void *addr, size_t addrlen)
+dv_plugin_check_address (void *cls, const void *addr, size_t addrlen)
 {
 {
-  /* struct Plugin *plugin = cls; */
+  struct Plugin *plugin = cls;
 
 
-  /* check if the address is plausible; if so,
-     add it to our list! */
-  return GNUNET_NO;
+  /* Verify that the first peer of this address matches our peer id! */
+  if ((addrlen != (2 * sizeof (struct GNUNET_PeerIdentity))) ||
+      (0 !=
+       memcmp (addr, plugin->env->my_identity,
+               sizeof (struct GNUNET_PeerIdentity))))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "%s: Address not correct size or identity doesn't match ours!\n",
+                GNUNET_i2s (plugin->env->my_identity));
+    if (addrlen == (2 * sizeof (struct GNUNET_PeerIdentity)))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer in address is %s\n",
+                  GNUNET_i2s (addr));
+    }
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
 }
 
 
 }
 
 
@@ -383,14 +383,13 @@ libgnunet_plugin_transport_dv_init (void *cls)
 
   plugin = GNUNET_malloc (sizeof (struct Plugin));
   plugin->env = env;
 
   plugin = GNUNET_malloc (sizeof (struct Plugin));
   plugin->env = env;
-  //plugin->service = service;
-  //plugin->server = GNUNET_SERVICE_get_server (service);
 
 
-  plugin->dv_handle = GNUNET_DV_connect(env->sched, env->cfg, &handle_dv_message_received, plugin);
+  plugin->dv_handle =
+      GNUNET_DV_connect (env->cfg, &handle_dv_message_received, plugin);
 
   if (plugin->dv_handle == NULL)
   {
 
   if (plugin->dv_handle == NULL)
   {
-    GNUNET_free(plugin);
+    GNUNET_free (plugin);
     return NULL;
   }
 
     return NULL;
   }
 
@@ -399,7 +398,7 @@ libgnunet_plugin_transport_dv_init (void *cls)
   api->send = &dv_plugin_send;
   api->disconnect = &dv_plugin_disconnect;
   api->address_pretty_printer = &dv_plugin_address_pretty_printer;
   api->send = &dv_plugin_send;
   api->disconnect = &dv_plugin_disconnect;
   api->address_pretty_printer = &dv_plugin_address_pretty_printer;
-  api->check_address = &dv_plugin_address_suggested;
+  api->check_address = &dv_plugin_check_address;
   api->address_to_string = &address_to_string;
   return api;
 }
   api->address_to_string = &address_to_string;
   return api;
 }
@@ -415,7 +414,7 @@ libgnunet_plugin_transport_dv_done (void *cls)
   struct Plugin *plugin = api->cls;
 
   if (plugin->dv_handle != NULL)
   struct Plugin *plugin = api->cls;
 
   if (plugin->dv_handle != NULL)
-    GNUNET_DV_disconnect(plugin->dv_handle);
+    GNUNET_DV_disconnect (plugin->dv_handle);
 
   GNUNET_free (plugin);
   GNUNET_free (api);
 
   GNUNET_free (plugin);
   GNUNET_free (api);