gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] 14/40: NEWS: Added api to store hellos with peerstore service.


From: gnunet
Subject: [gnunet] 14/40: NEWS: Added api to store hellos with peerstore service.
Date: Thu, 05 Oct 2023 08:57:17 +0200

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

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

commit 0f8b71280614e9a69d7703d88cc35108e6cec052
Author: t3sserakt <t3ss@posteo.de>
AuthorDate: Thu Aug 3 10:48:39 2023 +0200

    NEWS: Added api to store hellos with peerstore service.
---
 src/hello/hello-uri.c                  | 121 +++++++++++++++++
 src/include/gnunet_hello_uri_lib.h     |  17 +++
 src/include/gnunet_peerstore_service.h |  31 +++++
 src/peerstore/peerstore_api.c          | 238 +++++++++++++++++++++++++++++++++
 4 files changed, 407 insertions(+)

diff --git a/src/hello/hello-uri.c b/src/hello/hello-uri.c
index 8f8f699e9..9e8d6909d 100644
--- a/src/hello/hello-uri.c
+++ b/src/hello/hello-uri.c
@@ -204,6 +204,32 @@ struct GNUNET_HELLO_Builder
 
 };
 
+/**
+ * Struct to wrap data to do the merge of to hello uris.
+ */
+struct AddressUriMergeResult
+{
+  /**
+   * The builder of the hello uri we merge with.
+   */
+  struct GNUNET_HELLO_Builder *builder;
+
+  /**
+   * The actual address to check, if it is allready in the hello uri we merge 
with.
+   */
+  const char *address_uri;
+
+  /**
+   * Did we found the actual address to check.
+   */
+  unsigned int found;
+
+  /**
+   * Did we found at least one address to merge.
+   */
+  unsigned int merged;
+};
+
 
 /**
  * Compute @a hash over addresses in @a builder.
@@ -315,6 +341,13 @@ GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity 
*pid)
 }
 
 
+struct GNUNET_PeerIdentity *
+GNUNET_HELLO_builder_get_id (struct GNUNET_HELLO_Builder *builder)
+{
+  return &builder->pid;
+}
+
+
 void
 GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder)
 {
@@ -412,6 +445,94 @@ GNUNET_HELLO_builder_from_block (const void *block,
 }
 
 
+static void
+merge_hellos2 (void *cls, const char *address_uri2)
+{
+  struct AddressUriMergeResult *aumr = cls;
+  const char *address_uri1 = aumr->address_uri;
+
+  if (GNUNET_NO == aumr->found && 0 != GNUNET_memcmp (address_uri1,
+                                                      address_uri2))
+  {
+    aumr->found = GNUNET_YES;
+  }
+}
+
+
+static void
+merge_hellos1 (void *cls, const char *address_uri1)
+{
+  struct AddressUriMergeResult *aumr = cls;
+  struct GNUNET_HELLO_Builder *builder2 = aumr->builder;
+  struct GNUNET_PeerIdentity *peer2 = GNUNET_HELLO_builder_get_id (builder2);
+
+  aumr->address_uri = address_uri1;
+  GNUNET_HELLO_builder_iterate (builder2, peer2, &merge_hellos2, aumr);
+  if (GNUNET_YES == aumr->found)
+  {
+    GNUNET_HELLO_builder_add_address (builder2, address_uri1);
+    aumr->merged = GNUNET_YES;
+  }
+  aumr->found = GNUNET_NO;
+}
+
+
+struct GNUNET_MQ_Envelope *
+GNUNET_HELLO_builder_merge_hellos (const struct GNUNET_MessageHeader *msg1,
+                                   const struct GNUNET_MessageHeader *msg2,
+                                   const struct
+                                   GNUNET_CRYPTO_EddsaPrivateKey *priv)
+{
+  struct HelloUriMessage *hum1 = (struct HelloUriMessage *) msg1;
+  struct BlockHeader *bh1 = (struct BlockHeader *) &msg1[1];
+  struct GNUNET_TIME_Absolute expiration_time1 = GNUNET_TIME_absolute_ntoh (
+    bh1->expiration_time);
+  struct HelloUriMessage *hum2 = (struct HelloUriMessage *) msg2;
+  struct BlockHeader *bh2 = (struct BlockHeader *) &msg2[1];
+  struct GNUNET_TIME_Absolute expiration_time2 = GNUNET_TIME_absolute_ntoh (
+    bh1->expiration_time);
+  struct GNUNET_HELLO_Builder *builder1 = GNUNET_HELLO_builder_from_msg (msg1);
+  struct GNUNET_HELLO_Builder *builder2 = GNUNET_HELLO_builder_from_msg (msg2);
+  struct AddressUriMergeResult *aumr = GNUNET_new (struct
+                                                   AddressUriMergeResult);
+  struct GNUNET_PeerIdentity *peer1 = GNUNET_HELLO_builder_get_id (builder1);
+  struct GNUNET_MQ_Envelope *env;
+  struct GNUNET_TIME_Absolute expiration_time;
+
+  aumr->builder = builder2;
+  GNUNET_HELLO_builder_iterate (builder1, peer1, &merge_hellos1, aumr);
+
+  if (GNUNET_YES == aumr->merged)
+  {
+    if (expiration_time1.abs_value_us < expiration_time2.abs_value_us)
+      expiration_time = expiration_time1;
+    else
+      expiration_time = expiration_time2;
+    env = GNUNET_HELLO_builder_to_env (builder2,
+                                       priv,
+                                       GNUNET_TIME_absolute_get_remaining (
+                                         expiration_time));
+  }
+  else if (expiration_time1.abs_value_us != expiration_time2.abs_value_us)
+  {
+    if (expiration_time1.abs_value_us < expiration_time2.abs_value_us)
+      expiration_time = expiration_time2;
+    else
+      expiration_time = expiration_time1;
+    env = GNUNET_HELLO_builder_to_env (builder2,
+                                       priv,
+                                       GNUNET_TIME_absolute_get_remaining (
+                                         expiration_time));
+  }
+
+  GNUNET_HELLO_builder_free (builder1);
+  GNUNET_HELLO_builder_free (builder2);
+  GNUNET_free (aumr);
+
+  return env;
+}
+
+
 struct GNUNET_HELLO_Builder *
 GNUNET_HELLO_builder_from_url (const char *url)
 {
diff --git a/src/include/gnunet_hello_uri_lib.h 
b/src/include/gnunet_hello_uri_lib.h
index 4e48bc1a0..3aa07d760 100644
--- a/src/include/gnunet_hello_uri_lib.h
+++ b/src/include/gnunet_hello_uri_lib.h
@@ -69,6 +69,13 @@ struct GNUNET_HELLO_Builder *
 GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid);
 
 
+/**
+ * Get the PeerIdentity for this builder.
+ */
+struct GNUNET_PeerIdentity *
+GNUNET_HELLO_builder_get_id (struct GNUNET_HELLO_Builder *builder);
+
+
 /**
  * Release resources of a @a builder.
  *
@@ -110,6 +117,16 @@ struct GNUNET_HELLO_Builder *
 GNUNET_HELLO_builder_from_url (const char *url);
 
 
+/**
+ * Merge to hello uris.
+ */
+struct GNUNET_MQ_Envelope *
+GNUNET_HELLO_builder_merge_hellos (const struct GNUNET_MessageHeader *msg1,
+                                   const struct GNUNET_MessageHeader *msg2,
+                                   const struct
+                                   GNUNET_CRYPTO_EddsaPrivateKey *priv);
+
+
 /**
  * Generate envelope with GNUnet HELLO message (including
  * peer ID) from a @a builder
diff --git a/src/include/gnunet_peerstore_service.h 
b/src/include/gnunet_peerstore_service.h
index c4000c680..37d3ca7fe 100644
--- a/src/include/gnunet_peerstore_service.h
+++ b/src/include/gnunet_peerstore_service.h
@@ -46,6 +46,10 @@ extern "C" {
 #endif
 #endif
 
+/**
+ * Key used for storing HELLO in the peerstore
+ */
+#define GNUNET_PEERSTORE_HELLO_KEY "peerstore-peer-hello-uri"
 
 /**
  * Key used for storing addresses in URL format in the peerstore
@@ -182,6 +186,33 @@ typedef void (*GNUNET_PEERSTORE_Processor) (
   const char *emsg);
 
 
+
+/**
+ * Add hello to peerstore.
+ *
+ * @param h handle for peerstore.
+ * @param msg The hello to add.
+ * @param cont The continuation function to execute after storing.
+ * @param cont_cls The continuation function closure.
+ * @return The context for storing.
+ */
+struct GNUNET_PEERSTORE_StoreHelloContext *
+GNUNET_PEERSTORE_hello_add (struct GNUNET_PEERSTORE_Handle *h,
+                            const struct GNUNET_MessageHeader *msg,
+                            const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
+                            GNUNET_PEERSTORE_Continuation cont,
+                            void *cont_cls);
+
+
+/**
+ * Cancel the request to add a hello.
+ *
+ * @param huc The context for storing a hello.
+ */
+void
+GNUNET_PEERSTORE_hello_add_cancel (struct GNUNET_PEERSTORE_StoreHelloContext 
*huc);
+
+
 /**
  * Connect to the PEERSTORE service.
  *
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index 1c13369cf..3905b14e4 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -25,8 +25,10 @@
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
+#include "gnunet_hello_uri_lib.h"
 #include "peerstore.h"
 #include "peerstore_common.h"
+#include "gnunet_peerstore_service.h"
 
 #define LOG(kind, ...) GNUNET_log_from (kind, "peerstore-api", __VA_ARGS__)
 
@@ -156,6 +158,22 @@ struct GNUNET_PEERSTORE_StoreContext
   enum GNUNET_PEERSTORE_StoreOption options;
 };
 
+/**
+ * Closure for store callback when storing hello uris.
+ */
+struct StoreHelloCls
+{
+  /**
+   * The corresponding store context.
+   */
+  struct GNUNET_PEERSTORE_StoreContext *sc;
+
+  /**
+   * The corresponding hello uri add request.
+   */
+  struct GNUNET_PEERSTORE_StoreHelloContext *huc;
+};
+
 /**
  * Context for a iterate request
  */
@@ -243,6 +261,62 @@ struct GNUNET_PEERSTORE_WatchContext
   struct GNUNET_HashCode keyhash;
 };
 
+/**
+ * Context for a add hello uri request.
+ */
+struct GNUNET_PEERSTORE_StoreHelloContext
+{
+  /**
+   * Peerstore handle.
+   */
+  struct GNUNET_PEERSTORE_Handle *h;
+
+  /**
+   * Function to call with information.
+   */
+  GNUNET_PEERSTORE_Continuation cont;
+
+  /**
+   * Closure for @e callback.
+   */
+  void *cont_cls;
+
+  /**
+   * Head of active STORE requests.
+   */
+  struct GNUNET_PEERSTORE_StoreContext *sc_head;
+
+  /**
+   * Tail of active STORE requests.
+   */
+  struct GNUNET_PEERSTORE_StoreContext *sc_tail;
+
+  /**
+   * Iteration context to iterate through all the stored hellos.
+   */
+  struct GNUNET_PEERSTORE_IterateContext *ic;
+
+  /**
+   * Active watch to be notified about conflicting hello uri add requests.
+   */
+  struct GNUNET_PEERSTORE_WatchContext *wc;
+
+  /**
+   * Hello uri which was request for storing.
+   */
+  const struct GNUNET_MessageHeader *hello;
+
+  /**
+   * Key to sign merged hello.
+   */
+  const struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+
+  /**
+   * Was this request successful.
+   */
+  int success;
+};
+
 
/******************************************************************************/
 /*******************             DECLARATIONS             
*********************/
 
/******************************************************************************/
@@ -935,4 +1009,168 @@ GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle 
*h,
 }
 
 
+
+
+static void
+merge_success (void *cls, int success)
+{
+  struct StoreHelloCls *shu_cls = cls;
+  struct GNUNET_PEERSTORE_StoreHelloContext *huc = shu_cls->huc;
+  struct GNUNET_PEERSTORE_Handle *h = huc->h;
+
+  if (GNUNET_OK != success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Storing hello uri failed\n");
+    huc->cont (huc->cont_cls, success);
+    return;
+  }
+  GNUNET_CONTAINER_DLL_remove (huc->sc_head, huc->sc_tail, shu_cls->sc);
+  if (NULL == huc->sc_head)
+  {
+    GNUNET_PEERSTORE_watch_cancel (huc->wc);
+    huc->wc = NULL;
+    huc->cont (huc->cont_cls, GNUNET_OK);
+    huc->success = GNUNET_OK;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Storing hello uri succeeded!\n");
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Got notified during storing hello uri!\n");
+}
+
+
+static void
+store_hello (struct GNUNET_PEERSTORE_StoreHelloContext *huc,
+             const struct GNUNET_MessageHeader *hello)
+{
+  struct GNUNET_PEERSTORE_Handle *h = huc->h;
+  struct GNUNET_HELLO_Builder *builder;
+  struct GNUNET_PeerIdentity *pid;
+  struct GNUNET_PEERSTORE_StoreContext *sc;
+  struct StoreHelloCls *shu_cls = GNUNET_new (struct StoreHelloCls);
+
+  shu_cls->huc = huc;
+  builder = GNUNET_HELLO_builder_from_msg (hello);
+  pid = GNUNET_HELLO_builder_get_id (builder);
+  sc = GNUNET_PEERSTORE_store (h,
+                               "peerstore",
+                               pid,
+                               GNUNET_PEERSTORE_HELLO_KEY,
+                               hello,
+                               sizeof(hello),
+                               GNUNET_TIME_UNIT_FOREVER_ABS,
+                               GNUNET_PEERSTORE_STOREOPTION_REPLACE,
+                               merge_success,
+                               shu_cls);
+  shu_cls->sc = sc;
+  GNUNET_CONTAINER_DLL_insert (huc->sc_head, huc->sc_tail, sc);
+  GNUNET_HELLO_builder_free (builder);
+}
+
+
+static void
+merge_uri  (void *cls,
+           const struct GNUNET_PEERSTORE_Record *record,
+           const char *emsg)
+{
+  struct GNUNET_PEERSTORE_StoreHelloContext *huc = cls;
+  struct GNUNET_PEERSTORE_Handle *h = huc->h;
+  struct GNUNET_PEERSTORE_WatchContext *wc;
+  struct GNUNET_MessageHeader *hello;
+  const struct GNUNET_MessageHeader *merged_hello;
+  struct GNUNET_MQ_Envelope *env;
+  const char *val;
+
+  if (NULL != emsg)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Got failure from PEERSTORE: %s\n",
+                emsg);
+    return;
+  }
+  if (NULL == record)
+    return;
+
+  if (NULL == huc->wc && GNUNET_NO == huc->success)
+  {
+    wc = GNUNET_PEERSTORE_watch (h,
+                                 "peerstore",
+                                 &record->peer,
+                                 GNUNET_PEERSTORE_HELLO_KEY,
+                                 &merge_uri,
+                                 huc);
+    huc->wc = wc;
+  }
+
+  if (NULL != record)
+  {
+    hello = record->value;
+    if ((0 == record->value_size) || ('\0' != val[record->value_size - 1]))
+    {
+      GNUNET_break (0);
+      return;
+    }
+
+    env = GNUNET_HELLO_builder_merge_hellos (huc->hello, hello, huc->priv);
+    merged_hello = GNUNET_MQ_env_get_msg (env);
+    if (NULL != merged_hello)
+      store_hello (huc, merged_hello);
+
+    GNUNET_free (env);
+
+  }
+  else
+  {
+    store_hello (huc, huc->hello);
+  }
+}
+
+
+struct GNUNET_PEERSTORE_StoreHelloContext *
+GNUNET_PEERSTORE_hello_add (struct GNUNET_PEERSTORE_Handle *h,
+                            const struct GNUNET_MessageHeader *msg,
+                            const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
+                            GNUNET_PEERSTORE_Continuation cont,
+                            void *cont_cls)
+{
+  struct GNUNET_HELLO_Builder *builder;
+  struct GNUNET_PEERSTORE_StoreHelloContext *huc;
+  struct GNUNET_PEERSTORE_IterateContext *ic;
+  struct GNUNET_PeerIdentity *pid;
+
+  huc = GNUNET_new (struct GNUNET_PEERSTORE_StoreHelloContext);
+  huc->h = h;
+  huc->cont = cont;
+  huc->cont_cls = cont_cls;
+  huc->hello = msg;
+  huc->priv = priv;
+
+  builder = GNUNET_HELLO_builder_from_msg (msg);
+  pid = GNUNET_HELLO_builder_get_id (builder);
+  ic = GNUNET_PEERSTORE_iterate (h,
+                         "peerstore",
+                         pid,
+                         GNUNET_PEERSTORE_HELLO_KEY,
+                         &merge_uri,
+                         huc);
+  GNUNET_HELLO_builder_free (builder);
+  huc->ic = ic;
+
+  return huc;
+}
+
+void
+GNUNET_PEERSTORE_hello_add_cancel (struct GNUNET_PEERSTORE_StoreHelloContext 
*huc)
+{
+  struct GNUNET_PEERSTORE_StoreContext *sc;
+
+  GNUNET_PEERSTORE_iterate_cancel (huc->ic);
+  GNUNET_PEERSTORE_watch_cancel (huc->wc);
+  while (NULL != (sc = huc->sc_head))
+      GNUNET_PEERSTORE_store_cancel (sc);
+  GNUNET_free (huc);
+}
+
 /* end of peerstore_api.c */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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