gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated: add new hello generation su


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: add new hello generation support logic to tng
Date: Thu, 22 Nov 2018 17:29:03 +0100

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 ca9031349 add new hello generation support logic to tng
ca9031349 is described below

commit ca90313490f4233ce9d209abbdcc2d78d16b8326
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Nov 22 17:29:01 2018 +0100

    add new hello generation support logic to tng
---
 src/hello/Makefile.am                   |   4 +-
 src/hello/hello-ng.c                    | 178 +++++++++++++++++++++++
 src/include/gnunet_hello_lib.h          |  37 +++++
 src/include/gnunet_signatures.h         |   6 +
 src/peerstore/plugin_peerstore_sqlite.c |   2 +-
 src/transport/Makefile.am               |   2 +
 src/transport/gnunet-service-tng.c      | 245 ++++++++++++++++++++++++++------
 7 files changed, 426 insertions(+), 48 deletions(-)

diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am
index 79003301b..00357f9e1 100644
--- a/src/hello/Makefile.am
+++ b/src/hello/Makefile.am
@@ -13,7 +13,9 @@ endif
 lib_LTLIBRARIES = libgnunethello.la
 
 libgnunethello_la_SOURCES = \
-  hello.c address.c
+  hello.c \
+  address.c \
+  hello-ng.c
 libgnunethello_la_LIBADD = \
  $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \
  $(LTLIBINTL)
diff --git a/src/hello/hello-ng.c b/src/hello/hello-ng.c
new file mode 100644
index 000000000..425095f9c
--- /dev/null
+++ b/src/hello/hello-ng.c
@@ -0,0 +1,178 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2018 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file hello/hello-ng.c
+ * @brief helper library for handling HELLOs
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_signatures.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_util_lib.h"
+
+/**
+ * Binary block we sign when we sign an address.
+ */
+struct SignedAddress
+{
+  /**
+   * Purpose must be #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When does the address expire.
+   */
+  struct GNUNET_TIME_AbsoluteNBO expiration;
+
+  /**
+   * Hash of the address.
+   */
+  struct GNUNET_HashCode h_addr;
+};
+
+
+/**
+ * Build address record by signing raw information with private key.
+ *
+ * @param address text address at @a communicator to sign
+ * @param expiration how long is @a address valid
+ * @param private_key signing key to use
+ * @param result[out] where to write address record (allocated)
+ * @param result_size[out] set to size of @a result
+ */
+void
+GNUNET_HELLO_sign_address (const char *address,
+                          struct GNUNET_TIME_Absolute expiration,
+                          const struct GNUNET_CRYPTO_EddsaPrivateKey 
*private_key,
+                          void **result,
+                          size_t *result_size)
+{
+  struct SignedAddress sa;
+  struct GNUNET_CRYPTO_EddsaSignature sig;
+  char *sig_str;
+  
+  sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
+  sa.purpose.size = htonl (sizeof (sa));
+  sa.expiration = GNUNET_TIME_absolute_hton (expiration);
+  GNUNET_CRYPTO_hash (address,
+                     strlen (address),
+                     &sa.h_addr);
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CRYPTO_eddsa_sign (private_key,
+                                          &sa.purpose,
+                                          &sig));
+  sig_str = NULL;
+  (void) GNUNET_STRINGS_base64_encode (&sig,
+                                      sizeof (sig),
+                                      &sig_str);
+  *result_size = 1 + GNUNET_asprintf ((char **) result,
+                                     "%s;%llu;%s",
+                                     sig_str,
+                                     (unsigned long long) 
expiration.abs_value_us,
+                                     address);
+  GNUNET_free (sig_str);  
+}
+
+                          
+/**
+ * Check signature and extract address record.
+ *
+ * @param raw raw signed address
+ * @param raw_size size of @a raw
+ * @param public_key public key to use for signature verification
+ * @param expiration[out] how long is the address valid
+ * @return NULL on error, otherwise the address
+ */
+char *
+GNUNET_HELLO_extract_address (const void *raw,
+                             size_t raw_size,
+                             const struct GNUNET_CRYPTO_EddsaPublicKey 
*public_key,
+                             struct GNUNET_TIME_Absolute *expiration)
+{
+  const char *raws = raw;
+  unsigned long long raw_us;
+  const char *sc;
+  const char *sc2;
+  const char *raw_addr;
+  struct GNUNET_TIME_Absolute raw_expiration;
+  struct SignedAddress sa;
+  struct GNUNET_CRYPTO_EddsaSignature *sig;
+
+  if ('\0' != raws[raw_size])
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  if (NULL == (sc = strchr (raws,
+                           ';')))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  if (NULL == (sc2 = strchr (sc + 1,
+                            ';')))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  if (1 != sscanf (sc + 1,
+                  "%llu;",
+                  &raw_us))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  raw_expiration.abs_value_us = raw_us;
+  if (0 == GNUNET_TIME_absolute_get_remaining (raw_expiration).rel_value_us)
+    return NULL; /* expired */
+  sig = NULL;
+  if (sizeof (struct GNUNET_CRYPTO_EddsaSignature) !=
+      GNUNET_STRINGS_base64_decode (raws,
+                                   sc - raws,
+                                   (void **) &sig))
+  {
+    GNUNET_break_op (0);
+    GNUNET_free_non_null (sig);
+    return NULL;
+  }
+  raw_addr = sc2 + 1;
+  
+  sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
+  sa.purpose.size = htonl (sizeof (sa));
+  sa.expiration = GNUNET_TIME_absolute_hton (raw_expiration);
+  GNUNET_CRYPTO_hash (raw_addr,
+                     strlen (raw_addr),
+                     &sa.h_addr);
+  if (GNUNET_YES !=
+      GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS,
+                                 &sa.purpose,
+                                 sig,
+                                 public_key))
+  {
+    GNUNET_break_op (0);
+    GNUNET_free (sig);
+    return NULL;
+  }
+  GNUNET_free (sig);
+  return GNUNET_strdup (raw_addr);
+}
+
+                          
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index 2a961e524..e19419f25 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -473,6 +473,43 @@ GNUNET_HELLO_parse_uri (const char *uri,
                         GNUNET_HELLO_TransportPluginsFind plugins_find);
 
 
+
+/* NG API */
+
+/**
+ * Build address record by signing raw information with private key.
+ *
+ * @param address text address to sign
+ * @param expiration how long is @a address valid
+ * @param private_key signing key to use
+ * @param result[out] where to write address record (allocated)
+ * @param result_size[out] set to size of @a result
+ */
+void
+GNUNET_HELLO_sign_address (const char *address,
+                          struct GNUNET_TIME_Absolute expiration,
+                          const struct GNUNET_CRYPTO_EddsaPrivateKey 
*private_key,
+                          void **result,
+                          size_t *result_size);
+
+
+/**
+ * Check signature and extract address record.
+ *
+ * @param raw raw signed address
+ * @param raw_size size of @a raw
+ * @param public_key public key to use for signature verification
+ * @param expiration[out] how long is the address valid
+ * @return NULL on error, otherwise the address
+ */
+char *
+GNUNET_HELLO_extract_address (const void *raw,
+                             size_t raw_size,
+                             const struct GNUNET_CRYPTO_EddsaPublicKey 
*public_key,
+                             struct GNUNET_TIME_Absolute *expiration);
+
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index 829f8be7e..03c97f199 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -188,6 +188,12 @@ extern "C"
  */
 #define GNUNET_SIGNATURE_PURPOSE_CREDENTIAL 28
 
+/**
+ * Signature by a peer affirming that this is one of its
+ * addresses (for the given time period).
+ */
+#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS 29
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif
diff --git a/src/peerstore/plugin_peerstore_sqlite.c 
b/src/peerstore/plugin_peerstore_sqlite.c
index 7ecb7bacd..e09274989 100644
--- a/src/peerstore/plugin_peerstore_sqlite.c
+++ b/src/peerstore/plugin_peerstore_sqlite.c
@@ -496,7 +496,7 @@ sql_prepare (sqlite3 *dbh,
  * as needed as well).
  *
  * @param plugin the plugin context (state for this module)
- * @return GNUNET_OK on success
+ * @return #GNUNET_OK on success
  */
 static int
 database_setup (struct Plugin *plugin)
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index deeb39b48..0693a0b9f 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -328,6 +328,8 @@ gnunet_service_tng_SOURCES = \
  gnunet-service-tng.c
 gnunet_service_tng_LDADD = \
   $(top_builddir)/src/ats/libgnunetats.la \
+  $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
+  $(top_builddir)/src/hello/libgnunethello.la \
   $(top_builddir)/src/statistics/libgnunetstatistics.la \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(GN_LIBINTL)
diff --git a/src/transport/gnunet-service-tng.c 
b/src/transport/gnunet-service-tng.c
index c7bdfd77c..e5fb51bd2 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -21,8 +21,6 @@
  * @author Christian Grothoff
  *
  * TODO:
- * - make *our* collected addresses available somehow somewhere
- *   => Choices: in peerstore or revive/keep peerinfo?
  * - MTU information is missing for queues!
  * - start supporting monitor logic (add functions to signal monitors!)
  * - manage fragmentation/defragmentation, retransmission, track RTT, loss, 
etc.
@@ -33,7 +31,7 @@
 #include "gnunet_util_lib.h"
 #include "gnunet_statistics_service.h"
 #include "gnunet_transport_service.h"
-#include "gnunet_peerinfo_service.h"
+#include "gnunet_peerstore_service.h"
 #include "gnunet_ats_service.h"
 #include "gnunet-service-transport.h"
 #include "transport.h"
@@ -263,6 +261,16 @@ struct AddressListEntry
   const char *address;
 
   /**
+   * Current context for storing this address in the peerstore.
+   */
+  struct GNUNET_PEERSTORE_StoreContext *sc;
+
+  /**
+   * Task to periodically do @e st operation.
+   */
+  struct GNUNET_SCHEDULER_Task *st;
+
+  /**
    * What is a typical lifetime the communicator expects this
    * address to have? (Always from now.)
    */
@@ -425,6 +433,11 @@ struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
  */
 static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
 
+/**
+ * Database for peer's HELLOs.
+ */
+static struct GNUNET_PEERSTORE_Handle *peerstore;
+
 
 /**
  * Lookup neighbour record for peer @a pid.
@@ -470,6 +483,78 @@ client_connect_cb (void *cls,
 
 
 /**
+ * Release memory used by @a neighbour.
+ *
+ * @param neighbour neighbour entry to free
+ */
+static void
+free_neighbour (struct Neighbour *neighbour)
+{
+  GNUNET_assert (NULL == neighbour->queue_head);
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multipeermap_remove (neighbours,
+                                                      &neighbour->pid,
+                                                      neighbour));
+  GNUNET_free (neighbour);
+}
+
+
+/**
+ * Free @a queue.
+ *
+ * @param queue the queue to free
+ */
+static void
+free_queue (struct Queue *queue)
+{
+  struct Neighbour *neighbour = queue->neighbour;
+  struct TransportClient *tc = queue->tc;
+
+  GNUNET_CONTAINER_MDLL_remove (neighbour,
+                               neighbour->queue_head,
+                               neighbour->queue_tail,
+                               queue);
+  GNUNET_CONTAINER_MDLL_remove (client,
+                               tc->details.communicator.queue_head,
+                               tc->details.communicator.queue_tail,
+                               queue);
+  GNUNET_free (queue);
+  if (NULL == neighbour->queue_head)
+    {
+      // FIXME: notify cores/monitors!
+      free_neighbour (neighbour);
+    }
+}
+
+
+/**
+ * Free @a ale
+ * 
+ * @param ale address list entry to free
+ */
+static void
+free_address_list_entry (struct AddressListEntry *ale)
+{
+  struct TransportClient *tc = ale->tc;
+  
+  GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
+                              tc->details.communicator.addr_tail,
+                              ale);
+  if (NULL != ale->sc)
+  {
+    GNUNET_PEERSTORE_store_cancel (ale->sc);
+    ale->sc = NULL;
+  }
+  if (NULL != ale->st)
+  {
+    GNUNET_SCHEDULER_cancel (ale->st);
+    ale->st = NULL;
+  }
+  GNUNET_free (ale);
+}
+
+
+/**
  * Called whenever a client is disconnected.  Frees our
  * resources associated with that client.
  *
@@ -511,7 +596,16 @@ client_disconnect_cb (void *cls,
   case CT_MONITOR:
     break;
   case CT_COMMUNICATOR:
-    GNUNET_free (tc->details.communicator.address_prefix);
+    {
+      struct Queue *q;
+      struct AddressListEntry *ale;
+
+      while (NULL != (q = tc->details.communicator.queue_head))
+       free_queue (q);
+      while (NULL != (ale = tc->details.communicator.addr_head))
+       free_address_list_entry (ale);
+      GNUNET_free (tc->details.communicator.address_prefix);
+    }
     break;
   }
   GNUNET_free (tc);
@@ -789,6 +883,81 @@ check_add_address (void *cls,
 
 
 /**
+ * Ask peerstore to store our address.
+ *
+ * @param cls an `struct AddressListEntry *`
+ */
+static void
+store_pi (void *cls);
+
+
+/**
+ * Function called when peerstore is done storing our address.
+ */
+static void
+peerstore_store_cb (void *cls,
+                   int success)
+{
+  struct AddressListEntry *ale = cls;
+
+  ale->sc = NULL;
+  if (GNUNET_YES != success)
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               "Failed to store our own address `%s' in peerstore!\n",
+               ale->address);
+  /* refresh period is 1/4 of expiration time, that should be plenty 
+     without being excessive. */
+  ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide 
(ale->expiration,
+                                                                      4ULL),
+                                         &store_pi,
+                                         ale);
+}
+
+
+/**
+ * Ask peerstore to store our address.
+ *
+ * @param cls an `struct AddressListEntry *`
+ */
+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,
+                            expiration,
+                            GST_my_private_key,
+                            &addr,
+                            &addr_len);  
+  ale->sc = GNUNET_PEERSTORE_store (peerstore,
+                                   "transport",
+                                   &GST_my_identity,
+                                   "hello",
+                                   addr,
+                                   addr_len,
+                                   expiration,
+                                   GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
+                                   &peerstore_store_cb,
+                                   ale);
+  GNUNET_free (addr);
+  if (NULL == ale->sc)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               "Failed to store our address `%s' with peerstore\n",
+               ale->address);
+    ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+                                           &store_pi,
+                                           ale);
+  }
+}
+
+
+/**
  * Address of our peer added.  Process the request.
  *
  * @param cls the client
@@ -815,7 +984,8 @@ handle_add_address (void *cls,
   GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
                                tc->details.communicator.addr_tail,
                                ale);
-  // FIXME: notify somebody?!
+  ale->st = GNUNET_SCHEDULER_add_now (&store_pi,
+                                     ale);
   GNUNET_SERVICE_client_continue (tc->client);
 }
 
@@ -845,11 +1015,7 @@ handle_del_address (void *cls,
     if (dam->aid != ale->aid)
       continue;
     GNUNET_assert (ale->tc == tc);
-    GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
-                                 tc->details.communicator.addr_tail,
-                                 ale);
-    // FIXME: notify somebody?
-    GNUNET_free (ale);
+    free_address_list_entry (ale);
     GNUNET_SERVICE_client_continue (tc->client);
   }
   GNUNET_break (0);
@@ -997,23 +1163,6 @@ handle_add_queue_message (void *cls,
 
 
 /**
- * Release memory used by @a neighbour.
- *
- * @param neighbour neighbour entry to free
- */
-static void
-free_neighbour (struct Neighbour *neighbour)
-{
-  GNUNET_assert (NULL == neighbour->queue_head);
-  GNUNET_assert (GNUNET_YES ==
-                GNUNET_CONTAINER_multipeermap_remove (neighbours,
-                                                      &neighbour->pid,
-                                                      neighbour));
-  GNUNET_free (neighbour);
-}
-
-
-/**
  * Queue to a peer went down.  Process the request.
  *
  * @param cls the client
@@ -1042,20 +1191,7 @@ handle_del_queue_message (void *cls,
                       &neighbour->pid,
                       sizeof (struct GNUNET_PeerIdentity))) )
       continue;
-    GNUNET_CONTAINER_MDLL_remove (neighbour,
-                                 neighbour->queue_head,
-                                 neighbour->queue_tail,
-                                 queue);
-    GNUNET_CONTAINER_MDLL_remove (client,
-                                 tc->details.communicator.queue_head,
-                                 tc->details.communicator.queue_tail,
-                                 queue);
-    GNUNET_free (queue);
-    if (NULL == neighbour->queue_head)
-    {
-      // FIXME: notify cores/monitors!
-      free_neighbour (neighbour);
-    }
+    free_queue (queue);
     GNUNET_SERVICE_client_continue (tc->client);
     return;
   }
@@ -1094,7 +1230,7 @@ handle_send_message_ack (void *cls,
  */
 static void
 handle_monitor_start (void *cls,
-                    const struct GNUNET_TRANSPORT_MonitorStart *start)
+                     const struct GNUNET_TRANSPORT_MonitorStart *start)
 {
   struct TransportClient *tc = cls;
 
@@ -1147,20 +1283,30 @@ do_shutdown (void *cls)
 {
   (void) cls;
 
+  GNUNET_CONTAINER_multipeermap_iterate (neighbours,
+                                        &free_neighbour_cb,
+                                        NULL);
+  /* FIXME: if this assertion fails (likely!), make sure we
+     clean up clients *before* doing the rest of the
+     shutdown! (i.e. by scheduling rest asynchronously!) */
+  GNUNET_assert (NULL == clients_head);
+  if (NULL != peerstore)
+  {
+    GNUNET_PEERSTORE_disconnect (peerstore,
+                                GNUNET_NO);
+    peerstore = NULL;
+  }
   if (NULL != GST_stats)
   {
     GNUNET_STATISTICS_destroy (GST_stats,
                                GNUNET_NO);
     GST_stats = NULL;
-  }
+  }  
   if (NULL != GST_my_private_key)
   {
     GNUNET_free (GST_my_private_key);
     GST_my_private_key = NULL;
   }
-  GNUNET_CONTAINER_multipeermap_iterate (neighbours,
-                                        &free_neighbour_cb,
-                                        NULL);
   GNUNET_CONTAINER_multipeermap_destroy (neighbours);
 }
 
@@ -1200,6 +1346,13 @@ run (void *cls,
                                         GST_cfg);
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
                                 NULL);
+  peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
+  if (NULL == peerstore)
+    {
+      GNUNET_break (0);
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
   /* start subsystems */
 }
 

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



reply via email to

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