[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [gnunet] branch master updated: more work on #5385
From: |
gnunet |
Subject: |
[GNUnet-SVN] [gnunet] branch master updated: more work on #5385 |
Date: |
Sun, 27 Jan 2019 00:36:52 +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 65b339b7c more work on #5385
65b339b7c is described below
commit 65b339b7ce68fcbaec9df6f66e8ed45e60b39ce1
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Jan 27 00:36:47 2019 +0100
more work on #5385
---
src/cadet/Makefile.am | 2 +
src/cadet/cadet_api_get_channel.c | 98 +++++++++++++++++++-
src/cadet/cadet_api_get_peer.c | 101 ++++++++++++++++-----
src/cadet/cadet_api_list_peers.c | 179 +++++++++++++++++++++++--------------
src/cadet/cadet_api_list_tunnels.c | 26 +++++-
src/include/gnunet_cadet_service.h | 28 +++---
6 files changed, 328 insertions(+), 106 deletions(-)
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index bccaf2cd9..62eaad38c 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -34,6 +34,8 @@ lib_LTLIBRARIES = \
libgnunetcadet_la_SOURCES = \
cadet_api.c \
+ cadet_api_get_peer.c \
+ cadet_api_list_peers.c \
cadet_api_helper.c
libgnunetcadet_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/cadet/cadet_api_get_channel.c
b/src/cadet/cadet_api_get_channel.c
index cd90f5b78..d41337522 100644
--- a/src/cadet/cadet_api_get_channel.c
+++ b/src/cadet/cadet_api_get_channel.c
@@ -31,9 +31,8 @@
#include "cadet_protocol.h"
-
/**
- * Ugly legacy hack.
+ * Operation handle.
*/
struct GNUNET_CADET_ChannelMonitor
{
@@ -48,23 +47,81 @@ struct GNUNET_CADET_ChannelMonitor
*/
void *channel_cb_cls;
+ /**
+ * Configuration we use.
+ */
const struct GNUNET_CONFIGURATION_Handle *cfg;
+ /**
+ * Message queue to talk to CADET service.
+ */
struct GNUNET_MQ_Handle *mq;
+ /**
+ * Task to reconnect.
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * Backoff for reconnect attempts.
+ */
+ struct GNUNET_TIME_Relative backoff;
+
+ /**
+ * Peer we want information about.
+ */
struct GNUNET_PeerIdentity peer;
-
+
+ /**
+ * Channel we want information about.
+ */
uint32_t /* UGH */ channel_number;
};
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_ChannelMonitor` operation
+ */
+static void
+reconnect (void *cls);
+
+
+/**
+ * Function called on connection trouble. Reconnects.
+ *
+ * @param cls a `struct GNUNET_CADET_ChannelMonitor``
+ * @param error error code from MQ
+ */
+static void
+error_handler (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct GNUNET_CADET_ChannelMonitor *cm = cls;
+
+ GNUNET_MQ_destroy (cm->mq);
+ cm->mq = NULL;
+ cm->backoff = GNUNET_TIME_randomized_backoff (cm->backoff,
+ GNUNET_TIME_UNIT_MINUTES);
+ cm->reconnect_task = GNUNET_SCHEDULER_add_delayed (cm->backoff,
+ &reconnect,
+ cm);
+}
+
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_ChannelMonitor` operation
+ */
static void
reconnect (void *cls)
{
struct GNUNET_CADET_ChannelMonitor *cm = cls;
struct GNUNET_MQ_MessageHandler *handlers[] = {
+ FIXME
}
struct GNUNET_MessageHeader *msg;
struct GNUNET_MQ_Envelope *env;
@@ -100,10 +157,45 @@ GNUNET_CADET_get_channel (const struct
GNUNET_CONFIGURATION_Handle *cfg,
GNUNET_CADET_ChannelCB callback,
void *callback_cls)
{
+ struct GNUNET_CADET_ChannelMonitor *cm;
+
+ if (NULL == callback)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ cm = GNUNET_new (struct GNUNET_CADET_ChannelMonitor);
+ cm->peer_cb = callback;
+ cm->peer_cb_cls = callback_cls;
+ cm->cfg = cfg;
+ cm->id = *id;
+ reconnect (cm);
+ if (NULL == cm->mq)
+ {
+ GNUNET_free (cm);
+ return NULL;
+ }
+ return cm;
}
+/**
+ * Cancel a channel monitor request. The callback will not be called (anymore).
+ *
+ * @param h Cadet handle.
+ * @return Closure that was given to #GNUNET_CADET_get_channel().
+ */
void *
GNUNET_CADET_get_channel_cancel (struct GNUNET_CADET_ChannelMonitor *cm)
{
+ void *ret = cm->peer_cb_cls;
+
+ if (NULL != cm->mq)
+ GNUNET_MQ_destroy (cm->mq);
+ if (NULL != cm->reconnect_task)
+ GNUNET_SCHEDULER_cancel (cm->reconnect_task);
+ GNUNET_free (cm);
+ return ret;
}
+
+/* end of cadet_api_get_channel.c */
diff --git a/src/cadet/cadet_api_get_peer.c b/src/cadet/cadet_api_get_peer.c
index c7d6e324b..e86c1567c 100644
--- a/src/cadet/cadet_api_get_peer.c
+++ b/src/cadet/cadet_api_get_peer.c
@@ -32,7 +32,7 @@
/**
- *
+ * Operation handle.
*/
struct GNUNET_CADET_GetPeer
{
@@ -43,15 +43,35 @@ struct GNUNET_CADET_GetPeer
GNUNET_CADET_PeerCB peer_cb;
/**
- * Info callback closure for @c info_cb.
+ * Closure for @c peer_cb.
*/
void *peer_cb_cls;
- struct GNUNET_PeerIdentity id;
-
+ /**
+ * Message queue to talk to CADET service.
+ */
struct GNUNET_MQ_Handle *mq;
+ /**
+ * Configuration we use.
+ */
const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Task to reconnect.
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * Backoff for reconnect attempts.
+ */
+ struct GNUNET_TIME_Relative backoff;
+
+ /**
+ * Peer we want information about.
+ */
+ struct GNUNET_PeerIdentity id;
+
};
@@ -103,11 +123,6 @@ handle_get_peer (void *cls,
int neighbor;
unsigned int peers;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "number of paths %u\n",
- ntohs (message->paths));
-
paths = ntohs (message->paths);
paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
peers = (ntohs (message->header.size) - sizeof (*message))
@@ -117,11 +132,9 @@ handle_get_peer (void *cls,
for (unsigned int i = 0; i < peers; i++)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " %s\n",
- GNUNET_i2s (&paths_array[i]));
path_length++;
- if (0 == memcmp (&paths_array[i], &message->destination,
+ if (0 == memcmp (&paths_array[i],
+ &message->destination,
sizeof (struct GNUNET_PeerIdentity)))
{
if (1 == path_length)
@@ -130,7 +143,7 @@ handle_get_peer (void *cls,
}
}
- /* Call Callback with tunnel info. */
+ /* Call Callback with tunnel info */
paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
gp->peer_cb (gp->peer_cb_cls,
&message->destination,
@@ -144,20 +157,57 @@ handle_get_peer (void *cls,
}
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_GetPeer` operation
+ */
+static void
+reconnect (void *cls);
+
+
+/**
+ * Function called on connection trouble. Reconnects.
+ *
+ * @param cls a `struct GNUNET_CADET_GetPeer`
+ * @param error error code from MQ
+ */
+static void
+error_handler (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct GNUNET_CADET_GetPeer *gp = cls;
+
+ GNUNET_MQ_destroy (gp->mq);
+ gp->mq = NULL;
+ gp->backoff = GNUNET_TIME_randomized_backoff (gp->backoff,
+ GNUNET_TIME_UNIT_MINUTES);
+ gp->reconnect_task = GNUNET_SCHEDULER_add_delayed (gp->backoff,
+ &reconnect,
+ gp);
+}
+
+
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_GetPeer` operation
+ */
static void
reconnect (void *cls)
{
struct GNUNET_CADET_GetPeer *gp = cls;
- struct GNUNET_MQ_MessageHandler *handlers[] = {
+ struct GNUNET_MQ_MessageHandler handlers[] = {
GNUNET_MQ_hd_var_size (get_peer,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
struct GNUNET_CADET_LocalInfoPeer,
- h),
+ gp),
GNUNET_MQ_handler_end ()
- }
+ };
struct GNUNET_CADET_LocalInfo *msg;
struct GNUNET_MQ_Envelope *env;
+ gp->reconnect_task = NULL;
gp->mq = GNUNET_CLIENT_connect (gp->cfg,
"cadet",
handlers,
@@ -168,7 +218,7 @@ reconnect (void *cls)
env = GNUNET_MQ_msg (msg,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
msg->peer = gp->id;
- GNUNET_MQ_send (lt->mq,
+ GNUNET_MQ_send (gp->mq,
env);
}
@@ -211,15 +261,24 @@ GNUNET_CADET_get_peer (const struct
GNUNET_CONFIGURATION_Handle *cfg,
}
-
+/**
+ * Cancel @a gp operation.
+ *
+ * @param gp operation to cancel
+ * @return closure from #GNUNET_CADET_get_peer().
+ */
void *
GNUNET_CADET_get_peer_cancel (struct GNUNET_CADET_GetPeer *gp)
{
void *ret = gp->peer_cb_cls;
-
- GNUNET_MQ_disconnect (gp->mq);
+
+ if (NULL != gp->mq)
+ GNUNET_MQ_destroy (gp->mq);
+ if (NULL != gp->reconnect_task)
+ GNUNET_SCHEDULER_cancel (gp->reconnect_task);
GNUNET_free (gp);
return ret;
}
+/* end of cadet_api_get_peer.c */
diff --git a/src/cadet/cadet_api_list_peers.c b/src/cadet/cadet_api_list_peers.c
index f6563a290..d53bcf65d 100644
--- a/src/cadet/cadet_api_list_peers.c
+++ b/src/cadet/cadet_api_list_peers.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2011, 2017 GNUnet e.V.
+ Copyright (C) 2011, 2017, 2019 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
@@ -18,7 +18,7 @@
SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
- * @file cadet/cadet_api.c
+ * @file cadet/cadet_api_list_peers.c
* @brief cadet api: client implementation of cadet service
* @author Bartlomiej Polot
* @author Christian Grothoff
@@ -31,9 +31,8 @@
#include "cadet_protocol.h"
-
/**
- * Ugly legacy hack.
+ * Operation handle.
*/
struct GNUNET_CADET_PeersLister
{
@@ -47,33 +46,34 @@ struct GNUNET_CADET_PeersLister
* Info callback closure for @c info_cb.
*/
void *peers_cb_cls;
-};
+ /**
+ * Message queue to talk to CADET service.
+ */
+ struct GNUNET_MQ_Handle *mq;
-/**
- * Send message of @a type to CADET service of @a h
- *
- * @param h handle to CADET service
- * @param type message type of trivial information request to send
- */
-static void
-send_info_request (struct GNUNET_CADET_Handle *h,
- uint16_t type)
-{
- struct GNUNET_MessageHeader *msg;
- struct GNUNET_MQ_Envelope *env;
+ /**
+ * Configuration we use.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
- env = GNUNET_MQ_msg (msg,
- type);
- GNUNET_MQ_send (h->mq,
- env);
-}
+ /**
+ * Task to reconnect.
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * Backoff for reconnect attempts.
+ */
+ struct GNUNET_TIME_Relative backoff;
+
+};
/**
* Check that message received from CADET service is well-formed.
*
- * @param cls the `struct GNUNET_CADET_Handle`
+ * @param cls the `struct GNUNET_CADET_PeersLister`
* @param message the message we got
* @return #GNUNET_OK if the message is well-formed,
* #GNUNET_SYSERR otherwise
@@ -94,60 +94,97 @@ check_get_peers (void *cls,
}
+// FIXME: use two different message types instead of this mess!
/**
* Process a local reply about info on all tunnels, pass info to the user.
*
- * @param cls Closure (Cadet handle).
+ * @param cls a `struct GNUNET_CADET_PeersLister`
* @param msg Message itself.
*/
static void
handle_get_peers (void *cls,
const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_CADET_Handle *h = cls;
+ struct GNUNET_CADET_PeersLister *pl = cls;
const struct GNUNET_CADET_LocalInfoPeer *info =
(const struct GNUNET_CADET_LocalInfoPeer *) msg;
- if (NULL == h->info_cb.peers_cb)
- return;
if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == ntohs (msg->size))
- h->info_cb.peers_cb (h->info_cls,
- &info->destination,
- (int) ntohs (info->tunnel),
- (unsigned int) ntohs (info->paths),
- 0);
+ pl->peers_cb (pl->peers_cb_cls,
+ &info->destination,
+ (int) ntohs (info->tunnel),
+ (unsigned int) ntohs (info->paths),
+ 0);
else
- h->info_cb.peers_cb (h->info_cls,
- NULL,
- 0,
- 0,
- 0);
+ {
+ pl->peers_cb (pl->peers_cb_cls,
+ NULL,
+ 0,
+ 0,
+ 0);
+ GNUNET_CADET_list_peers_cancel (pl);
+ }
+}
+
+
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_PeersLister` operation
+ */
+static void
+reconnect (void *cls);
+
+
+/**
+ * Function called on connection trouble. Reconnects.
+ *
+ * @param cls a `struct GNUNET_CADET_PeersLister`
+ * @param error error code from MQ
+ */
+static void
+error_handler (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct GNUNET_CADET_PeersLister *pl = cls;
+
+ GNUNET_MQ_destroy (pl->mq);
+ pl->mq = NULL;
+ pl->backoff = GNUNET_TIME_randomized_backoff (pl->backoff,
+ GNUNET_TIME_UNIT_MINUTES);
+ pl->reconnect_task = GNUNET_SCHEDULER_add_delayed (pl->backoff,
+ &reconnect,
+ pl);
}
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_PeersLister` operation
+ */
static void
reconnect (void *cls)
{
- struct GNUNET_CADET_ListTunnels *lt = cls;
- struct GNUNET_MQ_MessageHandler *handlers[] = {
- GNUNET_MQ_hd_var_size (get_peers,
+ struct GNUNET_CADET_PeersLister *pl = cls;
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (get_peers,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
struct GNUNET_MessageHeader,
- h),
+ pl),
GNUNET_MQ_handler_end ()
- }
+ };
struct GNUNET_MessageHeader *msg;
struct GNUNET_MQ_Envelope *env;
- cm->mq = GNUNET_CLIENT_connect (cm->cfg,
+ pl->mq = GNUNET_CLIENT_connect (pl->cfg,
"cadet",
handlers,
&error_handler,
- cm);
-
+ pl);
env = GNUNET_MQ_msg (msg,
- type);
- GNUNET_MQ_send (cm->mq,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
+ GNUNET_MQ_send (pl->mq,
env);
}
@@ -157,50 +194,54 @@ reconnect (void *cls)
* The callback will be called for every peer known to the service.
* Only one info request (of any kind) can be active at once.
*
- * WARNING: unstable API, likely to change in the future!
- *
* @param h Handle to the cadet peer.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- * @return #GNUNET_OK / #GNUNET_SYSERR
+ * @return NULL on error
*/
struct GNUNET_CADET_PeersLister *
GNUNET_CADET_list_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
GNUNET_CADET_PeersCB callback,
void *callback_cls)
{
- if (NULL != h->info_cb.peers_cb)
+ struct GNUNET_CADET_PeersLister *pl;
+
+ if (NULL == callback)
{
GNUNET_break (0);
- return GNUNET_SYSERR;
+ return NULL;
+ }
+ pl = GNUNET_new (struct GNUNET_CADET_PeersLister);
+ pl->peers_cb = callback;
+ pl->peers_cb_cls = callback_cls;
+ pl->cfg = cfg;
+ reconnect (pl);
+ if (NULL == pl->mq)
+ {
+ GNUNET_free (pl);
+ return NULL;
}
- send_info_request (h,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
- h->info_cb.peers_cb = callback;
- h->info_cls = callback_cls;
- return GNUNET_OK;
+ return pl;
}
/**
* Cancel a peer info request. The callback will not be called (anymore).
*
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Cadet handle.
+ * @param pl operation handle
* @return Closure given to GNUNET_CADET_get_peers().
*/
void *
GNUNET_CADET_list_peers_cancel (struct GNUNET_CADET_PeersLister *pl)
{
- void *cls = h->info_cls;
-
- h->info_cb.peers_cb = NULL;
- h->info_cls = NULL;
- return cls;
+ void *ret = pl->peers_cb_cls;
+
+ if (NULL != pl->mq)
+ GNUNET_MQ_destroy (pl->mq);
+ if (NULL != pl->reconnect_task)
+ GNUNET_SCHEDULER_cancel (pl->reconnect_task);
+ GNUNET_free (pl);
+ return ret;
}
-
-
-
-
+/* end of cadet_api_list_peers.c */
diff --git a/src/cadet/cadet_api_list_tunnels.c
b/src/cadet/cadet_api_list_tunnels.c
index 96343bf4d..7d0534e41 100644
--- a/src/cadet/cadet_api_list_tunnels.c
+++ b/src/cadet/cadet_api_list_tunnels.c
@@ -18,7 +18,7 @@
SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
- * @file cadet/cadet_api.c
+ * @file cadet/cadet_api_list_tunnels.c
* @brief cadet api: client implementation of cadet service
* @author Bartlomiej Polot
* @author Christian Grothoff
@@ -31,9 +31,8 @@
#include "cadet_protocol.h"
-
/**
- * Ugly legacy hack.
+ * Operation handle.
*/
struct GNUNET_CADET_ListTunnels
{
@@ -47,6 +46,27 @@ struct GNUNET_CADET_ListTunnels
* Info callback closure for @c tunnels_cb.
*/
void *tunnels_cb_cls;
+
+ /**
+ * Message queue to talk to CADET service.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Configuration we use.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Task to reconnect.
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * Backoff for reconnect attempts.
+ */
+ struct GNUNET_TIME_Relative backoff;
+
};
diff --git a/src/include/gnunet_cadet_service.h
b/src/include/gnunet_cadet_service.h
index fb4499db0..2ac98e621 100644
--- a/src/include/gnunet_cadet_service.h
+++ b/src/include/gnunet_cadet_service.h
@@ -411,6 +411,12 @@ GNUNET_CADET_get_channel (const struct
GNUNET_CONFIGURATION_Handle *cfg,
void *callback_cls);
+/**
+ * Cancel a channel monitor request. The callback will not be called (anymore).
+ *
+ * @param h Cadet handle.
+ * @return Closure that was given to #GNUNET_CADET_get_channel().
+ */
void *
GNUNET_CADET_get_channel_cancel (struct GNUNET_CADET_ChannelMonitor *cm);
@@ -444,13 +450,10 @@ struct GNUNET_CADET_PeersLister;
* The callback will be called for every peer known to the service.
* Only one info request (of any kind) can be active at once.
*
- * WARNING: unstable API, likely to change in the future!
- *
* @param h Handle to the cadet peer.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- *
- * @return #GNUNET_OK / #GNUNET_SYSERR
+ * @return NULL on error
*/
struct GNUNET_CADET_PeersLister *
GNUNET_CADET_list_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -461,14 +464,13 @@ GNUNET_CADET_list_peers (const struct
GNUNET_CONFIGURATION_Handle *cfg,
/**
* Cancel a peer info request. The callback will not be called (anymore).
*
- * @param h Cadet handle.
+ * @param pl operation handle
* @return Closure that was given to #GNUNET_CADET_list_peers().
*/
void *
GNUNET_CADET_list_peers_cancel (struct GNUNET_CADET_PeersLister *pl);
-
/**
* Method called to retrieve information about a specific peer
* known to the service.
@@ -493,6 +495,9 @@ typedef void
int finished_with_paths);
+/**
+ * Handle to cancel #GNUNET_CADET_get_peer() operation.
+ */
struct GNUNET_CADET_GetPeer;
/**
@@ -500,14 +505,11 @@ struct GNUNET_CADET_GetPeer;
* The callback will be called for the tunnel once.
* Only one info request (of any kind) can be active at once.
*
- * WARNING: unstable API, likely to change in the future!
- *
* @param h Handle to the cadet peer.
* @param id Peer whose tunnel to examine.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- *
- * @return #GNUNET_OK / #GNUNET_SYSERR
+ * @return NULL on error
*/
struct GNUNET_CADET_GetPeer *
GNUNET_CADET_get_peer (const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -516,6 +518,12 @@ GNUNET_CADET_get_peer (const struct
GNUNET_CONFIGURATION_Handle *cfg,
void *callback_cls);
+/**
+ * Cancel @a gp operation.
+ *
+ * @param gp operation to cancel
+ * @return closure from #GNUNET_CADET_get_peer().
+ */
void *
GNUNET_CADET_get_peer_cancel (struct GNUNET_CADET_GetPeer *gp);
--
To stop receiving notification emails like this one, please contact
address@hidden
- [GNUnet-SVN] [gnunet] branch master updated: more work on #5385,
gnunet <=