gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated: implement handle_validation


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: implement handle_validation_response logic
Date: Sun, 14 Apr 2019 11:22:04 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 3378fbc4c implement handle_validation_response logic
3378fbc4c is described below

commit 3378fbc4c59bbc6110a51eba5d9c3a3bf8a0dba8
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Apr 14 11:22:00 2019 +0200

    implement handle_validation_response logic
---
 src/include/gnunet_crypto_lib.h    |  12 +-
 src/transport/gnunet-service-tng.c | 289 ++++++++++++++++++++++++++++---------
 2 files changed, 228 insertions(+), 73 deletions(-)

diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 257fee48d..6822de2f1 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1955,7 +1955,7 @@ GNUNET_CRYPTO_rsa_public_key_encode (const struct 
GNUNET_CRYPTO_RsaPublicKey *ke
  */
 struct GNUNET_CRYPTO_RsaPublicKey *
 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
-                                    size_t len);
+                                     size_t len);
 
 
 /**
@@ -1977,7 +1977,7 @@ GNUNET_CRYPTO_rsa_public_key_dup (const struct 
GNUNET_CRYPTO_RsaPublicKey *key);
  */
 int
 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
-                                struct GNUNET_CRYPTO_RsaSignature *s2);
+                                 struct GNUNET_CRYPTO_RsaSignature *s2);
 
 /**
  * Compare the values of two private keys.
@@ -1988,7 +1988,7 @@ GNUNET_CRYPTO_rsa_signature_cmp (struct 
GNUNET_CRYPTO_RsaSignature *s1,
  */
 int
 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
-                                 struct GNUNET_CRYPTO_RsaPrivateKey *p2);
+                                   struct GNUNET_CRYPTO_RsaPrivateKey *p2);
 
 
 /**
@@ -2000,7 +2000,7 @@ GNUNET_CRYPTO_rsa_private_key_cmp (struct 
GNUNET_CRYPTO_RsaPrivateKey *p1,
  */
 int
 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
-                                 struct GNUNET_CRYPTO_RsaPublicKey *p2);
+                                  struct GNUNET_CRYPTO_RsaPublicKey *p2);
 
 
 /**
@@ -2065,7 +2065,7 @@ GNUNET_CRYPTO_rsa_signature_free (struct 
GNUNET_CRYPTO_RsaSignature *sig);
  */
 size_t
 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature 
*sig,
-                                   char **buffer);
+                                    char **buffer);
 
 
 /**
@@ -2078,7 +2078,7 @@ GNUNET_CRYPTO_rsa_signature_encode (const struct 
GNUNET_CRYPTO_RsaSignature *sig
  */
 struct GNUNET_CRYPTO_RsaSignature *
 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
-                                   size_t len);
+                                    size_t len);
 
 
 /**
diff --git a/src/transport/gnunet-service-tng.c 
b/src/transport/gnunet-service-tng.c
index e685e28a6..ecff6b6e1 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -138,6 +138,10 @@
  * When do we forget an invalid address for sure?
  */
 #define MAX_ADDRESS_VALID_UNTIL GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MONTHS, 1)
+/**
+ * How long do we consider an address valid if we just checked?
+ */
+#define ADDRESS_VALIDATION_LIFETIME GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_HOURS, 4)
 
 /**
  * What is the maximum frequency at which we do address validation?
@@ -147,6 +151,14 @@
  */
 #define MIN_DELAY_ADDRESS_VALIDATION GNUNET_TIME_UNIT_MILLISECONDS
 
+/**
+ * How many network RTTs before an address validation expires should we begin
+ * trying to revalidate? (Note that the RTT used here is the one that we
+ * experienced during the last validation, not necessarily the latest RTT
+ * observed).
+ */
+#define VALIDATION_RTT_BUFFER_FACTOR 3
+
 /**
  * How many messages can we have pending for a given communicator
  * process before we start to throttle that communicator?
@@ -1597,8 +1609,8 @@ struct ValidationState
    * Next time we will send the @e challenge to the peer, if this time is past
    * @e valid_until, this validation state is released at this time.  If the
    * address is valid, @e next_challenge is set to @e validated_until MINUS @e
-   * validation_delay * 3, such that we will try to re-validate before the
-   * validity actually expires.
+   * validation_delay * #VALIDATION_RTT_BUFFER_FACTOR, such that we will try
+   * to re-validate before the validity actually expires.
    */
   struct GNUNET_TIME_Absolute next_challenge;
 
@@ -3051,10 +3063,13 @@ store_pi (void *cls);
 
 /**
  * Function called when peerstore is done storing our address.
+ *
+ * @param cls a `struct AddressListEntry`
+ * @param success #GNUNET_YES if peerstore was successful
  */
 static void
-peerstore_store_cb (void *cls,
-                    int success)
+peerstore_store_own_cb (void *cls,
+                        int success)
 {
   struct AddressListEntry *ale = cls;
 
@@ -3081,29 +3096,20 @@ static void
 store_pi (void *cls)
 {
   struct AddressListEntry *ale = cls;
-  void *addr;
-  size_t addr_len;
   struct GNUNET_TIME_Absolute expiration;
 
   ale->st = NULL;
   expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
-  GNUNET_HELLO_sign_address (ale->address,
-                             ale->nt,
-                             expiration,
-                             GST_my_private_key,
-                             &addr,
-                             &addr_len);
   ale->sc = GNUNET_PEERSTORE_store (peerstore,
                                     "transport",
                                     &GST_my_identity,
                                     GNUNET_HELLO_PEERSTORE_KEY,
-                                    addr,
-                                    addr_len,
+                                    ale->address,
+                                    strlen (ale->address) + 1,
                                     expiration,
                                     GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
-                                    &peerstore_store_cb,
+                                    &peerstore_store_own_cb,
                                     ale);
-  GNUNET_free (addr);
   if (NULL == ale->sc)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -3846,6 +3852,120 @@ handle_validation_challenge (void *cls,
 }
 
 
+/**
+ * Closure for #check_known_challenge.
+ */
+struct CheckKnownChallengeContext
+{
+  /**
+   * Set to the challenge we are looking for.
+   */
+  const struct GNUNET_ShortHashCode *challenge;
+
+  /**
+   * Set to a matching validation state, if one was found.
+   */
+  struct ValidationState *vs;
+};
+
+
+/**
+ * Test if the validation state in @a value matches the
+ * challenge from @a cls.
+ *
+ * @param cls a `struct CheckKnownChallengeContext`
+ * @param pid unused (must match though)
+ * @param value a `struct ValidationState`
+ * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
+ */
+static int
+check_known_challenge (void *cls,
+                       const struct GNUNET_PeerIdentity *pid,
+                       void *value)
+{
+  struct CheckKnownChallengeContext *ckac = cls;
+  struct ValidationState *vs = value;
+
+  (void) pid;
+  if (0 != GNUNET_memcmp (&vs->challenge,
+                          ckac->challenge))
+    return GNUNET_OK;
+  ckac->vs = vs;
+  return GNUNET_NO;
+}
+
+
+/**
+ * Function called when peerstore is done storing a
+ * validated address.
+ *
+ * @param cls a `struct ValidationState`
+ * @param success #GNUNET_YES on success
+ */
+static void
+peerstore_store_validation_cb (void *cls,
+                               int success)
+{
+  struct ValidationState *vs = cls;
+
+  vs->sc = NULL;
+  if (GNUNET_YES == success)
+    return;
+  GNUNET_STATISTICS_update (GST_stats,
+                            "# Peerstore failed to store foreign address",
+                            1,
+                            GNUNET_NO);
+}
+
+
+/**
+ * Task run periodically to validate some address based on #validation_heap.
+ *
+ * @param cls NULL
+ */
+static void
+validation_start_cb (void *cls);
+
+
+/**
+ * Set the time for next_challenge of @a vs to @a new_time.
+ * Updates the heap and if necessary reschedules the job.
+ *
+ * @param vs validation state to update
+ * @param new_time new time for revalidation
+ */
+static void
+update_next_challenge_time (struct ValidationState *vs,
+                            struct GNUNET_TIME_Absolute new_time)
+{
+  struct GNUNET_TIME_Relative delta;
+
+  if (new_time.abs_value_us == vs->next_challenge.abs_value_us)
+    return; /* be lazy */
+  vs->next_challenge = new_time;
+  if (NULL == vs->hn)
+    vs->hn = GNUNET_CONTAINER_heap_insert (validation_heap,
+                                           vs,
+                                           new_time.abs_value_us);
+  else
+    GNUNET_CONTAINER_heap_update_cost (vs->hn,
+                                       new_time.abs_value_us);
+  if ( (vs != GNUNET_CONTAINER_heap_peek (validation_heap)) &&
+       (NULL != validation_task) )
+    return;
+  if (NULL != validation_task)
+    GNUNET_SCHEDULER_cancel (validation_task);
+  /* randomize a bit */
+  delta.rel_value_us = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
+                                                 
MIN_DELAY_ADDRESS_VALIDATION.rel_value_us);
+  new_time = GNUNET_TIME_absolute_add (new_time,
+                                       delta);
+  validation_task = GNUNET_SCHEDULER_add_at (new_time,
+                                             &validation_start_cb,
+                                             NULL);
+}
+
+
 /**
  * Communicator gave us a transport address validation response.  Process the 
request.
  *
@@ -3857,9 +3977,92 @@ handle_validation_response (void *cls,
                             const struct TransportValidationResponse *tvr)
 {
   struct CommunicatorMessageContext *cmc = cls;
+  struct ValidationState *vs;
+  struct CheckKnownChallengeContext ckac = {
+    .challenge = &tvr->challenge,
+    .vs = NULL
+  };
+  struct GNUNET_TIME_Absolute origin_time;
 
-  // FIXME: check for matching pending challenge and mark address
-  // as valid if applicable (passing to PEERSTORE as well!)
+  /* check this is one of our challenges */
+  (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
+                                                     &cmc->im.sender,
+                                                     &check_known_challenge,
+                                                     &ckac);
+  if (NULL == (vs = ckac.vs))
+  {
+    /* This can happen simply if we 'forgot' the challenge by now,
+       i.e. because we received the validation response twice */
+    GNUNET_STATISTICS_update (GST_stats,
+                              "# Validations dropped, challenge unknown",
+                              1,
+                              GNUNET_NO);
+    finish_cmc_handling (cmc);
+    return;
+  }
+
+  /* sanity check on origin time */
+  origin_time = GNUNET_TIME_absolute_ntoh (tvr->origin_time);
+  if ( (origin_time.abs_value_us < vs->first_challenge_use.abs_value_us) ||
+       (origin_time.abs_value_us > vs->last_challenge_use.abs_value_us) )
+  {
+    GNUNET_break_op (0);
+    finish_cmc_handling (cmc);
+    return;
+  }
+
+  {
+    /* check signature */
+    struct TransportValidationPS tvp = {
+      .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
+      .purpose.size = htonl (sizeof (tvp)),
+      .validity_duration = tvr->validity_duration,
+      .challenge = tvr->challenge
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_CRYPTO_eddsa_verify 
(GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE,
+                                    &tvp.purpose,
+                                    &tvr->signature,
+                                    &cmc->im.sender.public_key))
+    {
+      GNUNET_break_op (0);
+      finish_cmc_handling (cmc);
+      return;
+    }
+  }
+
+  /* validity is capped by our willingness to keep track of the
+     validation entry and the maximum the other peer allows */
+  vs->valid_until
+    = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_min 
(GNUNET_TIME_relative_ntoh (tvr->validity_duration),
+                                                                  
MAX_ADDRESS_VALID_UNTIL));
+  vs->validated_until
+    = GNUNET_TIME_absolute_min (vs->valid_until,
+                                GNUNET_TIME_relative_to_absolute 
(ADDRESS_VALIDATION_LIFETIME));
+  vs->validation_rtt = GNUNET_TIME_absolute_get_duration (origin_time);
+  vs->challenge_backoff = GNUNET_TIME_UNIT_ZERO;
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                              &vs->challenge,
+                              sizeof (vs->challenge));
+  vs->first_challenge_use = GNUNET_TIME_absolute_subtract (vs->validated_until,
+                                                           
GNUNET_TIME_relative_multiply (vs->validation_rtt,
+                                                                               
           VALIDATION_RTT_BUFFER_FACTOR));
+  vs->last_challenge_use = GNUNET_TIME_UNIT_ZERO_ABS; /* challenge was not yet 
used */
+  update_next_challenge_time (vs,
+                              vs->first_challenge_use);
+  vs->sc = GNUNET_PEERSTORE_store (peerstore,
+                                   "transport",
+                                   &cmc->im.sender,
+                                   GNUNET_HELLO_PEERSTORE_KEY,
+                                   vs->address,
+                                   strlen (vs->address) + 1,
+                                   vs->valid_until,
+                                   GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
+                                   &peerstore_store_validation_cb,
+                                   vs);
+  // FIXME: now that we know that the address is *valid*,
+  // do we need to trigger _using_ it for something?
   finish_cmc_handling (cmc);
 }
 
@@ -4707,54 +4910,6 @@ suggest_to_connect (const struct GNUNET_PeerIdentity 
*pid,
 }
 
 
-/**
- * Task run periodically to validate some address based on #validation_heap.
- *
- * @param cls NULL
- */
-static void
-validation_start_cb (void *cls);
-
-
-/**
- * Set the time for next_challenge of @a vs to @a new_time.
- * Updates the heap and if necessary reschedules the job.
- *
- * @param vs validation state to update
- * @param new_time new time for revalidation
- */
-static void
-update_next_challenge_time (struct ValidationState *vs,
-                            struct GNUNET_TIME_Absolute new_time)
-{
-  struct GNUNET_TIME_Relative delta;
-
-  if (new_time.abs_value_us == vs->next_challenge.abs_value_us)
-    return; /* be lazy */
-  vs->next_challenge = new_time;
-  if (NULL == vs->hn)
-    vs->hn = GNUNET_CONTAINER_heap_insert (validation_heap,
-                                           vs,
-                                           new_time.abs_value_us);
-  else
-    GNUNET_CONTAINER_heap_update_cost (vs->hn,
-                                       new_time.abs_value_us);
-  if ( (vs != GNUNET_CONTAINER_heap_peek (validation_heap)) &&
-       (NULL != validation_task) )
-    return;
-  if (NULL != validation_task)
-    GNUNET_SCHEDULER_cancel (validation_task);
-  /* randomize a bit */
-  delta.rel_value_us = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
-                                                 
MIN_DELAY_ADDRESS_VALIDATION.rel_value_us);
-  new_time = GNUNET_TIME_absolute_add (new_time,
-                                       delta);
-  validation_task = GNUNET_SCHEDULER_add_at (new_time,
-                                             &validation_start_cb,
-                                             NULL);
-}
-
-
 /**
  * The queue @a q (which matches the peer and address in @a vs) is
  * ready for queueing. We should now queue the validation request.
@@ -5468,7 +5623,7 @@ do_shutdown (void *cls)
   if (NULL != peerstore)
   {
     GNUNET_PEERSTORE_disconnect (peerstore,
-                                GNUNET_NO);
+                                 GNUNET_NO);
     peerstore = NULL;
   }
   if (NULL != GST_stats)

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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