gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: work on provider config init du


From: gnunet
Subject: [taler-anastasis] branch master updated: work on provider config init during backup
Date: Tue, 16 Feb 2021 22:43:22 +0100

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

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 0ad2dc2  work on provider config init during backup
0ad2dc2 is described below

commit 0ad2dc21e764051a69106b2db37da23ccf1e6b78
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Feb 16 22:43:20 2021 +0100

    work on provider config init during backup
---
 src/reducer/anastasis_api_backup_redux.c | 269 +++++++++++++++++++++++++++++--
 src/reducer/anastasis_api_redux.c        | 242 +++++++++++----------------
 src/reducer/anastasis_api_redux.h        |  79 ++++++++-
 3 files changed, 428 insertions(+), 162 deletions(-)

diff --git a/src/reducer/anastasis_api_backup_redux.c 
b/src/reducer/anastasis_api_backup_redux.c
index eaf1bb0..d5afee9 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -1302,8 +1302,6 @@ initialize_policies (json_t *state,
                         index,
                         auth_method)
     {
-      const char *tu_key;
-      json_t *tu_value;
       json_t *provider_id = json_object_get (auth_method,
                                              "provider");
       // initialize policies to upload recovery document just to
@@ -1326,6 +1324,10 @@ initialize_policies (json_t *state,
         if (! provider_match)
           continue;
       }
+
+#if FIXME_LOGIC
+      const char *tu_key;
+      json_t *tu_value;
       unsigned int auth_method_index = json_integer_value (json_object_get (
                                                              auth_method,
                                                              
"authentication_method"));
@@ -1334,7 +1336,6 @@ initialize_policies (json_t *state,
         json_t *json_truth
           = json_array_get (json_object_get (state, "truths"),
                             atoi (tu_key));
-#if FIXME_LOGIC
         if (json_integer_value (
               json_object_get (json_truth, "auth_method_index"))
             == auth_method_index)
@@ -1345,8 +1346,8 @@ initialize_policies (json_t *state,
           truth_index++;
           break;
         }
-#endif
       }
+#endif
       {
         // initialize recovery document uploads array
         bool existing = false;
@@ -1673,8 +1674,6 @@ truth_upload_cb (void *cls,
                  const struct ANASTASIS_UploadDetails *ud)
 {
   struct TruthUploadState *tus = cls;
-  json_t *p;
-  json_t *j;
   json_t *truth_uploads;
 
   tus->tuo = NULL;
@@ -1716,6 +1715,7 @@ truth_upload_cb (void *cls,
   truth_uploads = json_object_get (tus->state,
                                    "truth_uploads");
 #if FIXME_LOGIC
+  json_t *j;
   j = ANASTASIS_truth_to_json (tus->truth);
   GNUNET_assert (NULL != j);
   p = json_pack ("{s:I,s:o}",
@@ -1723,8 +1723,8 @@ truth_upload_cb (void *cls,
                  (json_int_t) MHD_HTTP_NO_CONTENT,
                  "truth",
                  j);
-#endif
   GNUNET_assert (NULL != p);
+#endif
   {
     char buf[13];
 
@@ -1735,7 +1735,7 @@ truth_upload_cb (void *cls,
     GNUNET_assert (0 ==
                    json_object_set (truth_uploads,
                                     buf,
-                                    p));
+                                    /* WAS: p */ NULL));
   }
 
   if (check_uploads (truth_uploads, true) &&
@@ -2095,6 +2095,31 @@ back_finished (json_t *state,
 }
 
 
+/**
+ * DispatchHandler/Callback function which is called for a
+ * "add_provider" action.  Adds another Anastasis provider
+ * to the list of available providers for storing information.
+ *
+ * Returns an #ANASTASIS_ReduxAction if operation is async.
+ *
+ * @param state state to operate on
+ * @param arguments arguments with a provider URL to add
+ * @param cb callback (#DispatchHandler) to call during/after operation
+ * @param cb_cls callback closure
+ * @return NULL
+ */
+static struct ANASTASIS_ReduxAction *
+add_provider (json_t *state,
+              const json_t *arguments,
+              ANASTASIS_ActionCallback cb,
+              void *cb_cls)
+{
+  // FIXME: to be implemented!
+  GNUNET_break (0);
+  return NULL;
+}
+
+
 /**
  * Operates on a backup state depending on given #ANASTASIS_BackupState
  * and #ANASTASIS_BackupAction. The new #ANASTASIS_BackupState is returned
@@ -2120,6 +2145,11 @@ ANASTASIS_backup_action_ (json_t *state,
     const char *backup_action;
     DispatchHandler fun;
   } dispatchers[] = {
+    {
+      ANASTASIS_BACKUP_STATE_AUTHENTICATIONS_EDITING,
+      "add_provider",
+      &add_provider
+    },
     {
       ANASTASIS_BACKUP_STATE_AUTHENTICATIONS_EDITING,
       "add_authentication",
@@ -2186,7 +2216,7 @@ ANASTASIS_backup_action_ (json_t *state,
                                                       "backup_state"));
   enum ANASTASIS_BackupState bs;
 
-  GNUNET_assert (NULL != s);
+  GNUNET_assert (NULL != s); /* holds as per invariant of caller */
   bs = ANASTASIS_backup_state_from_string_ (s);
   if (ANASTASIS_BACKUP_STATE_ERROR == bs)
   {
@@ -2213,3 +2243,224 @@ ANASTASIS_backup_action_ (json_t *state,
                          action);
   return NULL;
 }
+
+
+/**
+ * State for a #ANASTASIS_REDUX_backup_begin_() operation.
+ */
+struct BackupStartState;
+
+
+/**
+ * Entry in the list of all known applicable Anastasis providers.
+ * Used to wait for it to complete downloading /config.
+ */
+struct BackupStartStateProviderEntry
+{
+  /**
+   * Kept in a DLL.
+   */
+  struct BackupStartStateProviderEntry *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct BackupStartStateProviderEntry *prev;
+
+  /**
+   * Main operation this entry is part of.
+   */
+  struct BackupStartState *bss;
+
+  /**
+   * Resulting provider information, NULL if not (yet) available.
+   */
+  json_t *istate;
+
+  /**
+   * Ongoing reducer action to obtain /config, NULL if completed.
+   */
+  struct ANASTASIS_ReduxAction *ra;
+
+  /**
+   * Final result of the operation (once completed).
+   */
+  enum TALER_ErrorCode ec;
+};
+
+
+struct BackupStartState
+{
+  /**
+   * Head of list of provider /config operations we are doing.
+   */
+  struct BackupStartStateProviderEntry *pe_head;
+
+  /**
+   * Tail of list of provider /config operations we are doing.
+   */
+  struct BackupStartStateProviderEntry *pe_tail;
+
+  /**
+   * State we are updating.
+   */
+  json_t *state;
+
+  /**
+   * Function to call when we are done.
+   */
+  ANASTASIS_ActionCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Redux action we returned to our controller.
+   */
+  struct ANASTASIS_ReduxAction ra;
+
+  /**
+   * Number of provider /config operations in @e ba_head that
+   * are still awaiting completion.
+   */
+  unsigned int pending;
+};
+
+
+/**
+ * The backup start operation is being aborted, terminate.
+ *
+ * @param cls a `struct BackupStartState *`
+ */
+static void
+abort_backup_begin_cb (void *cls)
+{
+  struct BackupStartState *bss = cls;
+  struct BackupStartStateProviderEntry *pe;
+
+  while (NULL != (pe = bss->pe_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (bss->pe_head,
+                                 bss->pe_tail,
+                                 pe);
+    if (NULL != pe->ra)
+      pe->ra->cleanup (pe->ra->cleanup_cls);
+    json_decref (pe->istate);
+    GNUNET_free (pe);
+  }
+  json_decref (bss->state);
+  GNUNET_free (bss);
+}
+
+
+/**
+ * We finished downloading /config from all providers, merge
+ * into the main state, trigger the continuation and free our
+ * state.
+ *
+ * @param[in] main state to merge into
+ */
+static void
+providers_complete (struct BackupStartState *bss)
+{
+  struct BackupStartStateProviderEntry *pe;
+
+  while (NULL != (pe = bss->pe_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (bss->pe_head,
+                                 bss->pe_tail,
+                                 pe);
+    // FIXME: merge pe->istate into bss->state!
+    json_decref (pe->istate);
+    GNUNET_free (pe);
+  }
+  bss->cb (bss->cb_cls,
+           TALER_EC_NONE,
+           bss->state);
+  json_decref (bss->state);
+  GNUNET_free (bss);
+}
+
+
+/**
+ * Function called when the complete information about a provider
+ * was added to @a new_state.
+ *
+ * @param cls a `struct BackupStartStateProviderEntry`
+ * @param error error code
+ * @param new_state resulting new state
+ */
+static void
+provider_added_cb (void *cls,
+                   enum TALER_ErrorCode error,
+                   json_t *new_state)
+{
+  struct BackupStartStateProviderEntry *pe = cls;
+
+  pe->ra = NULL;
+  pe->istate = json_incref (new_state);
+  pe->ec = error;
+  pe->bss->pending--;
+  if (0 == pe->bss->pending)
+    providers_complete (pe->bss);
+}
+
+
+struct ANASTASIS_ReduxAction *
+ANASTASIS_REDUX_backup_begin_ (json_t *state,
+                               const json_t *arguments,
+                               ANASTASIS_ActionCallback cb,
+                               void *cb_cls)
+{
+  json_t *provider_list;
+  json_t *prov;
+  const char *url;
+  struct BackupStartState *bss;
+
+  provider_list = json_object_get (state,
+                                   "authentication_providers");
+  if (NULL == provider_list)
+  {
+    GNUNET_break (0);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'authentication_providers' missing");
+    return NULL;
+  }
+  bss = GNUNET_new (struct BackupStartState);
+  bss->state = json_incref (state);
+  bss->cb = cb;
+  bss->cb_cls = cb_cls;
+  bss->ra.cleanup_cls = bss;
+  bss->ra.cleanup = &abort_backup_begin_cb;
+  bss->pending = 1; /* decremented after initialization loop */
+  json_object_foreach (provider_list, url, prov) {
+    struct BackupStartStateProviderEntry *pe;
+    json_t *istate;
+
+    pe = GNUNET_new (struct BackupStartStateProviderEntry);
+    pe->bss = bss;
+    istate = json_object ();
+    GNUNET_assert (NULL != istate);
+    GNUNET_CONTAINER_DLL_insert (bss->pe_head,
+                                 bss->pe_tail,
+                                 pe);
+    pe->ra = ANASTASIS_REDUX_add_provider_to_state_ (url,
+                                                     istate,
+                                                     &provider_added_cb,
+                                                     pe);
+    json_decref (istate);
+    if (NULL != pe->ra)
+      bss->pending++;
+  }
+  bss->pending--;
+  if (0 == bss->pending)
+  {
+    providers_complete (bss);
+    return NULL;
+  }
+  return &bss->ra;
+}
diff --git a/src/reducer/anastasis_api_redux.c 
b/src/reducer/anastasis_api_redux.c
index 25dee20..c9ce3b1 100644
--- a/src/reducer/anastasis_api_redux.c
+++ b/src/reducer/anastasis_api_redux.c
@@ -44,91 +44,6 @@ static const char *generic_strings[] = {
 #undef GENERATE_STRING
 
 
-/**
- * Extract the mode of a state from json
- *
- * @param state the state to operate on
- * @return "backup_state" or "recovery_state"
- */
-static const char *
-get_state_mode (const json_t *state)
-{
-  if (json_object_get (state, "backup_state"))
-    return "backup_state";
-  if (json_object_get (state, "recovery_state"))
-    return "recovery_state";
-  GNUNET_assert (0);
-  return NULL;
-}
-
-
-enum ANASTASIS_GenericState
-ANASTASIS_generic_state_from_string_ (const char *state_string)
-{
-  for (enum ANASTASIS_GenericState i = 0;
-       i < sizeof (generic_strings) / sizeof(*generic_strings);
-       i++)
-    if (0 == strcmp (state_string,
-                     generic_strings[i]))
-      return i;
-  return ANASTASIS_GENERIC_STATE_ERROR;
-}
-
-
-const char *
-ANASTASIS_generic_state_to_string_ (enum ANASTASIS_GenericState gs)
-{
-  if ( (gs < 0) ||
-       (gs >= sizeof (generic_strings) / sizeof(*generic_strings)) )
-  {
-    GNUNET_break_op (0);
-    return NULL;
-  }
-  return generic_strings[gs];
-}
-
-
-void
-ANASTASIS_redux_fail_ (ANASTASIS_ActionCallback cb,
-                       void *cb_cls,
-                       enum TALER_ErrorCode ec,
-                       const char *detail)
-{
-  json_t *estate;
-
-  estate = json_pack ("{s:s?, s:I, s:s}",
-                      "detail", detail,
-                      "code", (json_int_t) ec,
-                      "hint", TALER_ErrorCode_get_hint (ec));
-  cb (cb_cls,
-      ec,
-      estate);
-  json_decref (estate);
-}
-
-
-/**
- * Transition the @a state to @a gs.
- *
- * @param[in,out] state to transition
- * @param gs state to transition to
- */
-static void
-redux_transition (json_t *state,
-                  enum ANASTASIS_GenericState gs)
-{
-  const char *s_mode = get_state_mode (state);
-
-  GNUNET_assert (0 ==
-                 json_object_set_new (
-                   state,
-                   s_mode,
-                   json_string (
-                     ANASTASIS_generic_state_to_string_ (gs))));
-
-}
-
-
 /**
  * #ANASTASIS_REDUX_add_provider_to_state_ waiting for the
  * configuration request to complete or fail.
@@ -327,10 +242,90 @@ static json_t *provider_list;
 
 
 /**
- * Initialize reducer subsystem.
+ * Extract the mode of a state from json
  *
- * @param ctx context to use for CURL requests.
+ * @param state the state to operate on
+ * @return "backup_state" or "recovery_state"
  */
+static const char *
+get_state_mode (const json_t *state)
+{
+  if (json_object_get (state, "backup_state"))
+    return "backup_state";
+  if (json_object_get (state, "recovery_state"))
+    return "recovery_state";
+  GNUNET_assert (0);
+  return NULL;
+}
+
+
+enum ANASTASIS_GenericState
+ANASTASIS_generic_state_from_string_ (const char *state_string)
+{
+  for (enum ANASTASIS_GenericState i = 0;
+       i < sizeof (generic_strings) / sizeof(*generic_strings);
+       i++)
+    if (0 == strcmp (state_string,
+                     generic_strings[i]))
+      return i;
+  return ANASTASIS_GENERIC_STATE_ERROR;
+}
+
+
+const char *
+ANASTASIS_generic_state_to_string_ (enum ANASTASIS_GenericState gs)
+{
+  if ( (gs < 0) ||
+       (gs >= sizeof (generic_strings) / sizeof(*generic_strings)) )
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  return generic_strings[gs];
+}
+
+
+void
+ANASTASIS_redux_fail_ (ANASTASIS_ActionCallback cb,
+                       void *cb_cls,
+                       enum TALER_ErrorCode ec,
+                       const char *detail)
+{
+  json_t *estate;
+
+  estate = json_pack ("{s:s?, s:I, s:s}",
+                      "detail", detail,
+                      "code", (json_int_t) ec,
+                      "hint", TALER_ErrorCode_get_hint (ec));
+  cb (cb_cls,
+      ec,
+      estate);
+  json_decref (estate);
+}
+
+
+/**
+ * Transition the @a state to @a gs.
+ *
+ * @param[in,out] state to transition
+ * @param gs state to transition to
+ */
+static void
+redux_transition (json_t *state,
+                  enum ANASTASIS_GenericState gs)
+{
+  const char *s_mode = get_state_mode (state);
+
+  GNUNET_assert (0 ==
+                 json_object_set_new (
+                   state,
+                   s_mode,
+                   json_string (
+                     ANASTASIS_generic_state_to_string_ (gs))));
+
+}
+
+
 void
 ANASTASIS_redux_init (struct GNUNET_CURL_Context *ctx)
 {
@@ -346,6 +341,7 @@ ANASTASIS_redux_init (struct GNUNET_CURL_Context *ctx)
 static void
 free_config_request (struct ConfigRequest *cr)
 {
+  GNUNET_assert (NULL == cr->w_head);
   if (NULL != cr->co)
     ANASTASIS_config_cancel (cr->co);
   if (NULL != cr->tt)
@@ -360,9 +356,6 @@ free_config_request (struct ConfigRequest *cr)
 }
 
 
-/**
- * Terminate reducer subsystem.
- */
 void
 ANASTASIS_redux_done ()
 {
@@ -394,12 +387,6 @@ ANASTASIS_redux_done ()
 }
 
 
-/**
- * Function to load json containing all countries.
- * Returns the countries.
- *
- * @return json_t *
- */
 const json_t *
 ANASTASIS_redux_countries_init_ (void)
 {
@@ -981,6 +968,8 @@ select_country (json_t *state,
                            "'currency' missing");
     return NULL;
   }
+  /* We now have an idea of the currency, begin fetching
+     provider /configs (we likely need them later) */
   {
     enum TALER_ErrorCode ec;
 
@@ -1083,20 +1072,6 @@ unselect_continent (json_t *state,
 }
 
 
-/**
- * Adds the server configuration of the Anastasis provider
- * at @a url to the json @a state.  Checks if we have
- * the provider information already available. If so,
- * imports it into @a state. If not, queries the provider,
- * generating a success or failure outcome asynchronously.
- *
- * @param cr the config request
- * @param[in,out] state the json state to operate on
- * @param cb callback to call during/after operation
- * @param cb_cls callback closure
- * @return handle to cancel asynchronous operation, NULL if
- *         we completed synchronously
- */
 struct ANASTASIS_ReduxAction *
 ANASTASIS_REDUX_add_provider_to_state_ (const char *url,
                                         json_t *state,
@@ -1256,34 +1231,25 @@ enter_user_attributes (json_t *state,
     {
       redux_transition (state,
                         ANASTASIS_BACKUP_STATE_AUTHENTICATIONS_EDITING);
-      cb (cb_cls,
-          TALER_EC_NONE,
-          state);
-      return NULL;
+
+      return ANASTASIS_REDUX_backup_begin_ (state,
+                                            arguments,
+                                            cb,
+                                            cb_cls);
     }
     else
     {
       redux_transition (state,
                         ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING);
-      return ANASTASIS_REDUX_backup_challenge_begin_ (state,
-                                                      arguments,
-                                                      cb,
-                                                      cb_cls);
+      return ANASTASIS_REDUX_recovery_challenge_begin_ (state,
+                                                        arguments,
+                                                        cb,
+                                                        cb_cls);
     }
   }
 }
 
 
-/**
- * A generic DispatchHandler/Callback function which is called for a
- * "back" action.
- *
- * @param state state to operate on
- * @param arguments arguments to use for operation on state
- * @param cb callback to call during/after operation
- * @param cb_cls callback closure
- * @return NULL (no asynchronous action)
- */
 struct ANASTASIS_ReduxAction *
 ANASTASIS_back_generic_decrement_ (json_t *state,
                                    const json_t *arguments,
@@ -1338,21 +1304,6 @@ typedef struct ANASTASIS_ReduxAction *
                    void *cb_cls);
 
 
-/**
- * Operates on a state depending on given #ANASTASIS_BackupState
- * or #ANASTASIS_RecoveryState and #ANASTASIS_BackupAction or
- * #ANASTASIS_RecoveryAction.
- * The new #ANASTASIS_BackupState or #ANASTASIS_RecoveryState is returned
- * by a callback function.
- * This function can do network access to talk to anastasis service providers.
- *
- * @param state input state
- * @param action what action to perform
- * @param arguments data for the @a action
- * @param cb function to call with the result
- * @param cb_cls closure for @a cb
- * @return handle to cancel async actions, NULL if @a cb was already called
- */
 struct ANASTASIS_ReduxAction *
 ANASTASIS_redux_action (const json_t *state,
                         const char *action,
@@ -1473,11 +1424,6 @@ ANASTASIS_redux_action (const json_t *state,
 }
 
 
-/**
- * Function to cancel an async activity.
- *
- * @param ra generic container for async activities
- */
 void
 ANASTASIS_redux_action_cancel (struct ANASTASIS_ReduxAction *ra)
 {
diff --git a/src/reducer/anastasis_api_redux.h 
b/src/reducer/anastasis_api_redux.h
index 63f72b2..df4fd2f 100644
--- a/src/reducer/anastasis_api_redux.h
+++ b/src/reducer/anastasis_api_redux.h
@@ -74,6 +74,28 @@ enum ANASTASIS_RecoveryState
 #undef GENERATE_RECOVERY_ENUM
 
 
+/**
+ * CURL context to be used by all operations.
+ */
+extern struct GNUNET_CURL_Context *ANASTASIS_REDUX_ctx_;
+
+
+/**
+ * Initialize reducer subsystem.
+ *
+ * @param ctx context to use for CURL requests.
+ */
+void
+ANASTASIS_redux_init (struct GNUNET_CURL_Context *ctx);
+
+
+/**
+ * Terminate reducer subsystem.
+ */
+void
+ANASTASIS_redux_done (void);
+
+
 /**
  * Returns the enum value to a string value of a state.
  *
@@ -149,9 +171,37 @@ ANASTASIS_redux_fail_ (ANASTASIS_ActionCallback cb,
                        const char *detail);
 
 
-extern struct GNUNET_CURL_Context *ANASTASIS_REDUX_ctx_;
+/**
+ * Adds the server configuration of the Anastasis provider
+ * at @a url to the json @a state.  Checks if we have
+ * the provider information already available. If so,
+ * imports it into @a state. If not, queries the provider,
+ * generating a success or failure outcome asynchronously.
+ *
+ * @param cr the config request
+ * @param[in,out] state the json state to operate on
+ * @param cb callback to call during/after operation
+ * @param cb_cls callback closure
+ * @return handle to cancel asynchronous operation, NULL if
+ *         we completed synchronously
+ */
+struct ANASTASIS_ReduxAction *
+ANASTASIS_REDUX_add_provider_to_state_ (const char *url,
+                                        json_t *state,
+                                        ANASTASIS_ActionCallback cb,
+                                        void *cb_cls);
 
 
+/**
+ * A generic DispatchHandler/Callback function which is called for a
+ * "back" action.
+ *
+ * @param state state to operate on
+ * @param arguments arguments to use for operation on state
+ * @param cb callback to call during/after operation
+ * @param cb_cls callback closure
+ * @return NULL (no asynchronous action)
+ */
 struct ANASTASIS_ReduxAction *
 ANASTASIS_back_generic_decrement_ (json_t *state,
                                    const json_t *arguments,
@@ -204,10 +254,29 @@ ANASTASIS_recovery_action_ (json_t *state,
  * @return NULL
  */
 struct ANASTASIS_ReduxAction *
-ANASTASIS_REDUX_backup_challenge_begin_ (json_t *state,
-                                         const json_t *arguments,
-                                         ANASTASIS_ActionCallback cb,
-                                         void *cb_cls);
+ANASTASIS_REDUX_recovery_challenge_begin_ (json_t *state,
+                                           const json_t *arguments,
+                                           ANASTASIS_ActionCallback cb,
+                                           void *cb_cls);
+
+
+/**
+ * DispatchHandler/Callback function which is called for a
+ * "enter_user_attributes" action after verifying that the
+ * arguments provided were OK and the state transition was
+ * initiated.  Begins the actual backup logic.
+ *
+ * Returns an #ANASTASIS_ReduxAction.
+ *
+ * @param state state to operate on
+ * @param cb callback to call during/after operation
+ * @param cb_cls callback closure
+ */
+struct ANASTASIS_ReduxAction *
+ANASTASIS_REDUX_backup_begin_ (json_t *state,
+                               const json_t *arguments,
+                               ANASTASIS_ActionCallback cb,
+                               void *cb_cls);
 
 
 /**

-- 
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]