gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r16412 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r16412 - gnunet/src/transport
Date: Sat, 6 Aug 2011 21:39:49 +0200

Author: grothoff
Date: 2011-08-06 21:39:49 +0200 (Sat, 06 Aug 2011)
New Revision: 16412

Modified:
   gnunet/src/transport/gnunet-service-transport-new.c
   gnunet/src/transport/gnunet-service-transport.h
   gnunet/src/transport/gnunet-service-transport_validation.c
   gnunet/src/transport/gnunet-service-transport_validation.h
Log:
transmit PONGs

Modified: gnunet/src/transport/gnunet-service-transport-new.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport-new.c 2011-08-06 19:09:40 UTC 
(rev 16411)
+++ gnunet/src/transport/gnunet-service-transport-new.c 2011-08-06 19:39:49 UTC 
(rev 16412)
@@ -66,7 +66,7 @@
 /**
  * Our private key.
  */
-static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
+struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key;
 
 
 /**
@@ -140,10 +140,10 @@
       GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
       GST_stats = NULL;
     }  
-  if (my_private_key != NULL)
+  if (GST_my_private_key != NULL)
     {
-      GNUNET_CRYPTO_rsa_key_free (my_private_key);
-      my_private_key = NULL;
+      GNUNET_CRYPTO_rsa_key_free (GST_my_private_key);
+      GST_my_private_key = NULL;
     }
 }
 
@@ -180,9 +180,9 @@
       GNUNET_SCHEDULER_shutdown ();
       return;
     }
-  my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
+  GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
   GNUNET_free (keyfile);
-  if (my_private_key == NULL)
+  if (GST_my_private_key == NULL)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _("Transport service could not access hostkey.  
Exiting.\n"));
@@ -191,7 +191,7 @@
     }
   GST_stats = GNUNET_STATISTICS_create ("transport", c);
   GST_peerinfo = GNUNET_PEERINFO_connect (c);
-  GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &GST_my_public_key);
+  GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key);
   GNUNET_CRYPTO_hash (&GST_my_public_key,
                       sizeof (GST_my_public_key), &GST_my_identity.hashPubKey);
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,

Modified: gnunet/src/transport/gnunet-service-transport.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport.h     2011-08-06 19:09:40 UTC 
(rev 16411)
+++ gnunet/src/transport/gnunet-service-transport.h     2011-08-06 19:39:49 UTC 
(rev 16412)
@@ -55,5 +55,10 @@
  */
 extern struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key;
 
+/**
+ * Our private key.
+ */
+extern struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key;
+
 #endif
 /* end of file gnunet-service-transport_plugins.h */

Modified: gnunet/src/transport/gnunet-service-transport_validation.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport_validation.c  2011-08-06 
19:09:40 UTC (rev 16411)
+++ gnunet/src/transport/gnunet-service-transport_validation.c  2011-08-06 
19:39:49 UTC (rev 16412)
@@ -29,6 +29,7 @@
 #include "gnunet-service-transport.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_peerinfo_service.h"
+#include "gnunet_signatures.h"
 
 
 /**
@@ -81,6 +82,12 @@
 #define PING_PRIORITY 1
 
 /**
+ * Priority to use for PINGs and PONGs
+ */ 
+#define PONG_PRIORITY 1
+
+
+/**
  * Message used to ask a peer to validate receipt (to check an address
  * from a HELLO).  Followed by the address we are trying to validate,
  * or an empty address if we are just sending a PING to confirm that a
@@ -475,10 +482,54 @@
 
 
 /**
+ * Send the given PONG to the given address.
+ *
+ * @param cls the PONG message
+ * @param target peer this change is about, never NULL
+ * @param valid_until is ZERO if we never validated the address,
+ *                    otherwise a time up to when we consider it (or was) valid
+ * @param validation_block  is FOREVER if the address is for an unsupported 
plugin (from PEERINFO)
+ *                          is ZERO if the address is considered valid (no 
validation needed)
+ *                          otherwise a time in the future if we're currently 
denying re-validation
+ * @param plugin_name name of the plugin
+ * @param plugin_address binary address
+ * @param plugin_address_len length of address
+ */
+static void
+multicast_pong (void *cls,
+               const struct GNUNET_PeerIdentity *target,
+               struct GNUNET_TIME_Absolute valid_until,
+               struct GNUNET_TIME_Absolute validation_block,
+               const char *plugin_name,
+               const void *plugin_address,
+               size_t plugin_address_len)
+{
+  struct TransportPongMessage *pong = cls;
+  struct GNUNET_TRANSPORT_PluginFunctions *papi;
+
+  papi = GST_plugins_find (plugin_name);
+  if (papi == NULL)
+    return;
+  (void) papi->send (papi->cls,
+                    target,
+                    (const char*) pong,
+                    ntohs (pong->header.size),
+                    PONG_PRIORITY,
+                    HELLO_VERIFICATION_TIMEOUT,
+                    NULL,
+                    plugin_address,
+                    plugin_address_len,
+                    GNUNET_YES,
+                    NULL, NULL);
+}
+
+
+/**
  * We've received a PING.  If appropriate, generate a PONG.
  *
  * @param sender peer sending the PING
  * @param hdr the PING
+ * @param session session we got the PING from
  * @param plugin_name name of plugin that received the PING
  * @param sender_address address of the sender as known to the plugin, NULL
  *                       if we did not initiate the connection
@@ -488,9 +539,253 @@
 GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr,
                            const char *plugin_name,
+                           struct Session *session,
                            const void *sender_address,
                            size_t sender_address_len)
 {
+
+  const struct TransportPingMessage *ping;
+  struct TransportPongMessage *pong;
+  struct GNUNET_TRANSPORT_PluginFunctions *papi;
+  const char *addr;
+  const char *addrend;
+  size_t alen;
+  size_t slen;
+  ssize_t ret;
+
+  if (ntohs (hdr->size) < sizeof (struct TransportPingMessage))
+    {
+      GNUNET_break_op (0);
+      return;
+    }
+  ping = (const struct TransportPingMessage *) hdr;
+  if (0 != memcmp (&ping->target,
+                   &GST_my_identity,
+                   sizeof (struct GNUNET_PeerIdentity)))
+    {
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  _("Received `%s' message from `%s' destined for `%s' which 
is not me!\n"),
+                 "PING",
+                 (sender_address != NULL)
+                 ? GST_plugin_a2s (plugin_name,
+                                   sender_address,
+                                   sender_address_len)
+                 : "<inbound>",
+                 GNUNET_i2s (&ping->target));
+#endif
+      return;
+    }
+#if DEBUG_TRANSPORT
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+             "Processing `%s' from `%s'\n",
+             "PING",
+             (sender_address != NULL)
+             ? GST_plugin_a2s (plugin_name,
+                               sender_address,
+                               sender_address_len)
+             : "<inbound>");
+#endif
+  GNUNET_STATISTICS_update (GST_stats,
+                           gettext_noop ("# PING messages received"),
+                           1,
+                           GNUNET_NO);
+  addr = (const char*) &ping[1];
+  alen = ntohs (hdr->size) - sizeof (struct TransportPingMessage);
+  if (alen == 0)
+    {
+      /* peer wants to confirm that we have an outbound connection to him */
+      if (sender_address == NULL)
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                     _("Refusing to create PONG since I do initiate the 
session with `%s'.\n"),
+                     GNUNET_i2s (sender));
+         return;
+       }
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Creating PONG indicating that we initiated a connection to 
peer `%s' using address `%s' \n",
+                 GNUNET_i2s (peer),
+                 GST_plugin_a2s (plugin_name,
+                                 sender_address,
+                                 sender_address_len));
+#endif
+      slen = strlen (plugin_name) + 1;
+      pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + 
sender_address_len + slen);
+      pong->header.size = htons (sizeof (struct TransportPongMessage) + 
sender_address_len + slen);
+      pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
+      pong->purpose.size =
+       htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+              sizeof (uint32_t) +
+              sizeof (struct GNUNET_TIME_AbsoluteNBO) +
+              sizeof (struct GNUNET_PeerIdentity) + sender_address_len + slen);
+      pong->purpose.purpose = htonl 
(GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING);
+      pong->challenge = ping->challenge;
+      pong->addrlen = htonl(sender_address_len + slen);
+      pong->pid = *sender;
+      memcpy (&pong[1],
+             plugin_name,
+             slen);
+      memcpy (&((char*)&pong[1])[slen],
+             sender_address,
+             sender_address_len);
+#if 0
+      /* FIXME: lookup signature! */
+      if (GNUNET_TIME_absolute_get_remaining 
(session_header->pong_sig_expires).rel_value < 
+         PONG_SIGNATURE_LIFETIME.rel_value / 4)
+       {
+         /* create / update cached sig */
+#if DEBUG_TRANSPORT
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Creating PONG signature to indicate active 
connection.\n");
+#endif
+         session_header->pong_sig_expires = GNUNET_TIME_relative_to_absolute 
(PONG_SIGNATURE_LIFETIME);
+         pong->expiration = GNUNET_TIME_absolute_hton 
(session_header->pong_sig_expires);
+         GNUNET_assert (GNUNET_OK ==
+                        GNUNET_CRYPTO_rsa_sign (my_private_key,
+                                                &pong->purpose,
+                                                
&session_header->pong_signature));
+       }
+      else
+       {
+         pong->expiration = GNUNET_TIME_absolute_hton 
(session_header->pong_sig_expires);
+       }
+      memcpy (&pong->signature,
+             &session_header->pong_signature,
+             sizeof (struct GNUNET_CRYPTO_RsaSignature));
+#else
+      pong->expiration = GNUNET_TIME_absolute_hton 
(GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
+      GNUNET_assert (GNUNET_OK ==
+                    GNUNET_CRYPTO_rsa_sign (GST_my_private_key,
+                                            &pong->purpose,
+                                            &pong->signature));
+#endif
+    }
+  else
+    {
+      /* peer wants to confirm that this is one of our addresses */
+      addrend = memchr (addr, '\0', alen);
+      if (NULL == addrend)
+       {
+         GNUNET_break_op (0);
+         return;
+       }
+      addrend++;
+      slen = strlen(addr);
+      alen -= slen;
+      papi = GST_plugins_find (addr);
+      
+      if ( (NULL == papi) ||
+          (GNUNET_OK !=
+           papi->check_address (papi->cls,
+                                addrend,
+                                alen)) )
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                     _("Not confirming PING with address `%s' since I cannot 
confirm having this address.\n"),
+                     GST_plugins_a2s (addr,
+                                      addrend,
+                                      alen));
+         return;
+       }
+
+      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);
+      pong->purpose.size =
+       htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+              sizeof (uint32_t) +
+              sizeof (struct GNUNET_TIME_AbsoluteNBO) +
+              sizeof (struct GNUNET_PeerIdentity) + alen + slen);
+      pong->purpose.purpose = htonl 
(GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
+      pong->challenge = ping->challenge;
+      pong->addrlen = htonl(alen + slen);
+      pong->pid = GST_my_identity;
+      memcpy (&pong[1], addr, slen);
+      memcpy (&((char*)&pong[1])[slen], addrend, alen);
+#if 0
+      if ( (oal != NULL) &&
+          (GNUNET_TIME_absolute_get_remaining 
(oal->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4) )
+       {
+         /* create / update cached sig */
+#if DEBUG_TRANSPORT
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Creating PONG signature to indicate ownership.\n");
+#endif
+         oal->pong_sig_expires = GNUNET_TIME_relative_to_absolute 
(PONG_SIGNATURE_LIFETIME);
+         pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
+         GNUNET_assert (GNUNET_OK ==
+                        GNUNET_CRYPTO_rsa_sign (my_private_key,
+                                                &pong->purpose,
+                                                &oal->pong_signature));
+         memcpy (&pong->signature,
+                 &oal->pong_signature,
+                 sizeof (struct GNUNET_CRYPTO_RsaSignature));
+       }
+      else if (oal == NULL)
+       {
+#else
+         /* 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 (GST_my_private_key,
+                                                &pong->purpose,
+                                                &pong->signature));
+#endif
+#if 0
+       }
+      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));
+       }
+#endif
+    }
+
+  /* first see if the session we got this PING from can be used to transmit
+     a response reliably */
+  papi = GST_plugins_find (plugin_name);
+  if (papi == NULL)
+    ret = -1;
+  else
+    ret = papi->send (papi->cls,
+                     sender,
+                     (const char*) pong,
+                     ntohs (pong->header.size),
+                     PONG_PRIORITY,
+                     HELLO_VERIFICATION_TIMEOUT,
+                     session,
+                     sender_address,
+                     sender_address_len,
+                     GNUNET_SYSERR,
+                     NULL, NULL);
+  if (ret != -1)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Transmitted PONG to `%s' via reliable mechanism\n",
+                 GNUNET_i2s (sender));
+      /* done! */
+      GNUNET_STATISTICS_update (GST_stats,
+                               gettext_noop ("# PONGs unicast via reliable 
transport"),
+                               1,
+                               GNUNET_NO);
+      GNUNET_free (pong);
+      return;
+    }
+  
+  /* no reliable method found, try transmission via all known addresses */
+  GNUNET_STATISTICS_update (GST_stats,
+                           gettext_noop ("# PONGs multicast to all available 
addresses"),
+                           1,
+                           GNUNET_NO);
+  (void) GST_validation_get_addresses (sender,
+                                      GNUNET_YES,
+                                      &multicast_pong,
+                                      pong);
+  GNUNET_free (pong);
 }
 
 
@@ -571,17 +866,20 @@
           ve->addr,
           ve->addrlen);
     papi = GST_plugins_find (ve->transport_name);
-    ret = papi->send (papi->cls,
-                     pid,
-                     message_buf,
-                     tsize,
-                     PING_PRIORITY,
-                     HELLO_VERIFICATION_TIMEOUT,
-                     NULL /* no session */,
-                     ve->addr,
-                     ve->addrlen,
-                     GNUNET_YES,
-                     NULL, NULL);
+    if (papi == NULL)
+      ret = -1;
+    else
+      ret = papi->send (papi->cls,
+                       pid,
+                       message_buf,
+                       tsize,
+                       PING_PRIORITY,
+                       HELLO_VERIFICATION_TIMEOUT,
+                       NULL /* no session */,
+                       ve->addr,
+                       ve->addrlen,
+                       GNUNET_YES,
+                       NULL, NULL);
   }
   if (-1 != ret)
     {
@@ -595,7 +893,6 @@
 }
 
 
-
 /**
  * We've received a HELLO, check which addresses are new and trigger
  * validation.

Modified: gnunet/src/transport/gnunet-service-transport_validation.h
===================================================================
--- gnunet/src/transport/gnunet-service-transport_validation.h  2011-08-06 
19:09:40 UTC (rev 16411)
+++ gnunet/src/transport/gnunet-service-transport_validation.h  2011-08-06 
19:39:49 UTC (rev 16412)
@@ -27,6 +27,7 @@
 #define GNUNET_SERVICE_TRANSPORT_VALIDATION_H
 
 #include "gnunet_statistics_service.h"
+#include "gnunet_transport_plugin.h"
 #include "gnunet_util_lib.h"
 
 
@@ -50,6 +51,7 @@
  * @param sender peer sending the PING
  * @param hdr the PING
  * @param plugin_name name of plugin that received the PING
+ * @param session session we got the PING from
  * @param sender_address address of the sender as known to the plugin, NULL
  *                       if we did not initiate the connection
  * @param sender_address_len number of bytes in sender_address
@@ -58,6 +60,7 @@
 GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr,
                            const char *plugin_name,
+                           struct Session *session,
                            const void *sender_address,
                            size_t sender_address_len);
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]