[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [gnunet] 58/64: fixing the place leave logic after protocol
From: |
gnunet |
Subject: |
[GNUnet-SVN] [gnunet] 58/64: fixing the place leave logic after protocol change |
Date: |
Sat, 30 Dec 2017 20:58:43 +0100 |
This is an automated email from the git hooks/post-receive script.
lurchi pushed a commit to branch master
in repository gnunet.
commit ad24a2edfbae7aa37bc4cd74704d05a397e14d9b
Author: lurchi <address@hidden>
AuthorDate: Sat Dec 30 18:27:09 2017 +0100
fixing the place leave logic after protocol change
---
src/social/gnunet-service-social.c | 165 +++++++++++++++++++++++++------------
src/social/social_api.c | 67 +++++++++++++--
2 files changed, 172 insertions(+), 60 deletions(-)
diff --git a/src/social/gnunet-service-social.c
b/src/social/gnunet-service-social.c
index 7396efef5..5b2a8ba9b 100644
--- a/src/social/gnunet-service-social.c
+++ b/src/social/gnunet-service-social.c
@@ -255,10 +255,10 @@ struct Place
uint8_t is_ready;
/**
- * Is the client disconnected?
+ * Is the client disconnecting?
* #GNUNET_YES or #GNUNET_NO
*/
- uint8_t is_disconnected;
+ uint8_t is_disconnecting;
/**
* Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)?
@@ -348,7 +348,7 @@ struct Guest
/**
* Join request to be transmitted to the master on join.
*/
- struct GNUNET_MessageHeader *join_req;
+ struct GNUNET_MessageHeader *join_req; // FIXME: not used!
/**
* Join decision received from PSYC.
@@ -487,8 +487,6 @@ cleanup_host (struct Host *hst)
{
struct Place *plc = &hst->place;
- if (NULL != hst->master)
- GNUNET_PSYC_master_stop (hst->master, GNUNET_NO, NULL, NULL); // FIXME
GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs);
GNUNET_CONTAINER_multihashmap_destroy (hst->relay_msgs);
GNUNET_CONTAINER_multihashmap_remove (hosts, &plc->pub_key_hash, plc);
@@ -505,7 +503,7 @@ cleanup_guest (struct Guest *gst)
struct GNUNET_CONTAINER_MultiHashMap *
plc_gst = GNUNET_CONTAINER_multihashmap_get (place_guests,
&plc->pub_key_hash);
- GNUNET_assert (NULL != plc_gst); // FIXME
+ GNUNET_assert (NULL != plc_gst);
GNUNET_CONTAINER_multihashmap_remove (plc_gst, &plc->ego_pub_hash, gst);
if (0 == GNUNET_CONTAINER_multihashmap_size (plc_gst))
@@ -520,8 +518,6 @@ cleanup_guest (struct Guest *gst)
GNUNET_free (gst->join_req);
if (NULL != gst->relays)
GNUNET_free (gst->relays);
- if (NULL != gst->slave)
- GNUNET_PSYC_slave_part (gst->slave, GNUNET_NO, NULL, NULL); // FIXME
GNUNET_CONTAINER_multihashmap_remove (guests, &plc->pub_key_hash, plc);
}
@@ -536,6 +532,10 @@ cleanup_place (void *cls)
{
struct Place *plc = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "cleaning up place %s\n",
+ GNUNET_h2s (&plc->pub_key_hash));
+
(GNUNET_YES == plc->is_host)
? cleanup_host ((struct Host *) plc)
: cleanup_guest ((struct Guest *) plc);
@@ -563,6 +563,7 @@ client_notify_disconnect (void *cls,
if (NULL != c->app_id)
GNUNET_free (c->app_id);
+
GNUNET_free (c);
if (NULL == plc)
@@ -573,8 +574,6 @@ client_notify_disconnect (void *cls,
plc, (GNUNET_YES == plc->is_host) ? "host" : "guest",
GNUNET_h2s (&plc->pub_key_hash));
- // FIXME (due to protocol change): here we must not remove all clients,
- // only the one we were notified about!
struct ClientListItem *cli = plc->clients_head;
while (NULL != cli)
{
@@ -588,6 +587,11 @@ client_notify_disconnect (void *cls,
}
cli = cli->next;
}
+ if (GNUNET_YES == plc->is_disconnecting)
+ {
+ GNUNET_PSYC_slicer_destroy (plc->slicer);
+ GNUNET_free (plc);
+ }
}
@@ -629,6 +633,9 @@ place_send_msg (const struct Place *plc,
"%p Sending message to clients of place.\n", plc);
while (NULL != cli)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending message to client %p\n",
+ cli);
GNUNET_MQ_send_copy (GNUNET_SERVICE_client_get_mq (cli->client),
env);
cli = cli->next;
@@ -638,7 +645,7 @@ place_send_msg (const struct Place *plc,
static void
-place_send_leave_ack (const struct Place *plc)
+place_send_leave_ack (struct Place *plc)
{
struct GNUNET_MQ_Envelope *env;
@@ -756,17 +763,28 @@ psyc_slave_connected (void *cls, int result, uint64_t
max_message_id)
struct GNUNET_MQ_Envelope *env;
struct Guest *gst = cls;
struct Place *plc = &gst->place;
-
+
plc->max_message_id = max_message_id;
plc->is_ready = GNUNET_YES;
env = GNUNET_MQ_msg (res,
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
- res->result_code = htonl (result);
+ res->result_code =
+ (result != GNUNET_SYSERR) ? htonl (GNUNET_OK) : htonl (GNUNET_SYSERR);
res->max_message_id = GNUNET_htonll (plc->max_message_id);
place_send_msg (plc, env);
}
+static void
+slave_parted_after_join_decision (void *cls)
+{
+ struct Guest *gst = cls;
+
+ GNUNET_assert (NULL != gst->join_dcsn);
+ place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&gst->join_dcsn->header));
+}
+
+
/**
* Called when a PSYC slave receives a join decision.
*/
@@ -777,7 +795,21 @@ psyc_recv_join_dcsn (void *cls,
const struct GNUNET_PSYC_Message *join_msg)
{
struct Guest *gst = cls;
- place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&dcsn->header));
+
+ gst->join_dcsn = GNUNET_malloc (dcsn->header.size);
+ GNUNET_memcpy (gst->join_dcsn,
+ dcsn,
+ dcsn->header.size);
+ if (GNUNET_NO == is_admitted)
+ {
+ GNUNET_PSYC_slave_part (gst->slave,
+ GNUNET_NO,
+ &slave_parted_after_join_decision,
+ gst);
+ gst->slave = NULL;
+ return;
+ }
+ place_send_msg (&gst->place, GNUNET_MQ_msg_copy (&gst->join_dcsn->header));
}
@@ -1102,9 +1134,6 @@ place_init (struct Place *plc)
static int
place_add (const struct PlaceEnterRequest *ereq)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Adding place to hashmap:\n");
-
struct EgoPlacePublicKey ego_place_pub_key = {
.ego_pub_key = ereq->ego_pub_key,
.place_pub_key = ereq->place_pub_key,
@@ -1717,6 +1746,8 @@ guest_enter (const struct GuestEnterRequest *greq, struct
Guest **ret_gst)
return GNUNET_SYSERR;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "entering as guest\n");
struct GNUNET_HashCode place_pub_hash;
GNUNET_CRYPTO_hash (&greq->place_pub_key, sizeof (greq->place_pub_key),
&place_pub_hash);
@@ -1728,9 +1759,16 @@ guest_enter (const struct GuestEnterRequest *greq,
struct Guest **ret_gst)
if (NULL != plc_gst)
gst = GNUNET_CONTAINER_multihashmap_get (plc_gst, &ego_pub_hash);
- if (NULL == gst || NULL == gst->slave)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "plc_gst = %p, gst = %p\n",
+ plc_gst,
+ gst);
+ if (NULL == gst)
{
gst = GNUNET_new (struct Guest);
+ }
+ if (NULL == gst->slave)
+ {
gst->origin = greq->origin;
gst->relay_count = ntohl (greq->relay_count);
@@ -1803,11 +1841,12 @@ guest_enter (const struct GuestEnterRequest *greq,
struct Guest **ret_gst)
plc_gst = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
(void) GNUNET_CONTAINER_multihashmap_put (place_guests,
&plc->pub_key_hash, plc_gst,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- }
- (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash, gst,
-
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash, gst,
+ (void) GNUNET_CONTAINER_multihashmap_put (plc_gst, &plc->ego_pub_hash,
gst,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ (void) GNUNET_CONTAINER_multihashmap_put (guests, &plc->pub_key_hash,
gst,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+
+ }
gst->slave
= GNUNET_PSYC_slave_join (cfg, &plc->pub_key, &plc->ego_key,
gst->join_flags, &gst->origin,
@@ -1817,6 +1856,9 @@ guest_enter (const struct GuestEnterRequest *greq, struct
Guest **ret_gst)
&psyc_recv_join_dcsn,
gst, join_msg);
plc->channel = GNUNET_PSYC_slave_get_channel (gst->slave);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "slave entered channel %p\n",
+ plc->channel);
ret = GNUNET_YES;
}
@@ -1830,6 +1872,8 @@ static int
client_guest_enter (struct Client *c,
const struct GuestEnterRequest *greq)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "client_guest_enter\n");
struct GNUNET_PSYC_CountersResultMessage *result_msg;
struct GNUNET_MQ_Envelope *env;
struct GNUNET_SERVICE_Client *client = c->client;
@@ -1847,15 +1891,22 @@ client_guest_enter (struct Client *c,
switch (guest_enter (greq, &gst))
{
case GNUNET_YES:
+ {
plc = c->place = &gst->place;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "guest entered successfully to local place %s\n",
+ GNUNET_h2s (&plc->pub_key_hash));
plc->guest = gst;
app_place_save (app_id, (const struct PlaceEnterRequest *) greq);
app_notify_place (&greq->header, client);
break;
-
+ }
case GNUNET_NO:
{
plc = c->place = &gst->place;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "guest re-entered successfully to local place %s\n",
+ GNUNET_h2s (&plc->pub_key_hash));
plc->guest = gst;
env = GNUNET_MQ_msg (result_msg,
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
@@ -1872,12 +1923,10 @@ client_guest_enter (struct Client *c,
break;
}
case GNUNET_SYSERR:
+ {
return GNUNET_SYSERR;
}
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%p Client connected as guest to place %s.\n",
- gst, GNUNET_h2s (&plc->pub_key_hash));
+ }
struct ClientListItem *cli = GNUNET_new (struct ClientListItem);
cli->client = client;
@@ -2147,6 +2196,18 @@ handle_client_app_detach (void *cls,
}
+static void
+place_leave_cb (void *cls)
+{
+ struct Place *plc = cls;
+
+ place_send_leave_ack (plc);
+ (GNUNET_YES == plc->is_host)
+ ? cleanup_host ((struct Host *) plc)
+ : cleanup_guest ((struct Guest *) plc);
+}
+
+
/**
* Handle application leave request.
*/
@@ -2158,6 +2219,10 @@ handle_client_place_leave (void *cls,
struct GNUNET_SERVICE_Client *client = c->client;
struct Place *plc = c->place;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "got leave request from %s for place %s",
+ plc->is_host? "host" : "slave",
+ GNUNET_h2s (&plc->pub_key_hash));
if (NULL == plc)
{
GNUNET_break (0);
@@ -2165,26 +2230,27 @@ handle_client_place_leave (void *cls,
return;
}
- if (GNUNET_YES != plc->is_disconnected)
+ if (GNUNET_YES != plc->is_disconnecting)
{
- plc->is_disconnected = GNUNET_YES;
- if (NULL != plc->tmit_msgs_head)
- { /* Send pending messages to PSYC before cleanup. */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "not cleaning up place of client %p\n",
- client);
- psyc_transmit_message (plc);
+ plc->is_disconnecting = GNUNET_YES;
+ if (plc->is_host)
+ {
+ struct Host *host = plc->host;
+ GNUNET_assert (NULL != host);
+ GNUNET_PSYC_master_stop (host->master, GNUNET_NO, &place_leave_cb, plc);
}
else
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "cleaning up place of client %p\n",
- client);
- place_send_leave_ack (plc);
- cleanup_place (plc);
- c->place = NULL;
+ struct Guest *guest = plc->guest;
+ GNUNET_assert (NULL != guest);
+ GNUNET_PSYC_slave_part (guest->slave, GNUNET_NO, &place_leave_cb, plc);
}
}
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "got leave request but place is already leaving\n");
+ }
GNUNET_SERVICE_client_continue (client);
}
@@ -2244,6 +2310,9 @@ handle_client_join_decision (void *cls,
? (struct GNUNET_PSYC_Message *) &dcsn[1]
: NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "jcls.msg = %p\n",
+ jcls.msg);
struct GNUNET_HashCode slave_pub_hash;
GNUNET_CRYPTO_hash (&dcsn->slave_pub_key, sizeof (dcsn->slave_pub_key),
&slave_pub_hash);
@@ -2276,10 +2345,6 @@ send_message_ack (struct Place *plc, struct
GNUNET_SERVICE_Client *client)
struct GNUNET_MQ_Envelope *env;
env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "sending psyc message ack to client %p, mq = %p\n",
- client,
- GNUNET_SERVICE_client_get_mq (client));
GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
env);
}
@@ -2413,7 +2478,6 @@ psyc_transmit_notify_data (void *cls, uint16_t
*data_size, void *data)
{
*data_size = 0;
tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg);
- plc->is_disconnected = GNUNET_YES;
GNUNET_SERVICE_client_drop (tmit_frag->client);
GNUNET_SCHEDULER_add_now (&cleanup_place, plc);
return ret;
@@ -2455,11 +2519,7 @@ psyc_transmit_notify_data (void *cls, uint16_t
*data_size, void *data)
{
psyc_transmit_message (plc);
}
- else if (GNUNET_YES == plc->is_disconnected)
- {
- /* FIXME: handle partial message (when still in_transmit) */
- cleanup_place (plc);
- }
+ /* FIXME: handle partial message (when still in_transmit) */
}
return ret;
}
@@ -2573,7 +2633,6 @@ psyc_transmit_notify_mod (void *cls, uint16_t *data_size,
void *data,
*data_size = 0;
ret = GNUNET_SYSERR;
tmit_msg = psyc_transmit_queue_next_msg (plc, tmit_msg);
- plc->is_disconnected = GNUNET_YES;
GNUNET_SERVICE_client_drop (tmit_frag->client);
GNUNET_SCHEDULER_add_now (&cleanup_place, plc);
}
@@ -2890,7 +2949,7 @@ handle_client_psyc_message (void *cls,
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%p Received message from client.\n", plc);
+ "%p Received message of type %d from client.\n", plc, ntohs
(msg->type));
GNUNET_PSYC_log_message (GNUNET_ERROR_TYPE_DEBUG, msg);
if (GNUNET_YES != plc->is_ready)
diff --git a/src/social/social_api.c b/src/social/social_api.c
index db2a59674..4e305b867 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -1516,7 +1516,8 @@ GNUNET_SOCIAL_host_announce (struct GNUNET_SOCIAL_Host
*hst,
enum GNUNET_SOCIAL_AnnounceFlags flags)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "PSYC_transmit_message for host\n");
+ "PSYC_transmit_message for host, method: %s\n",
+ method_name);
if (GNUNET_OK ==
GNUNET_PSYC_transmit_message (hst->plc.tmit, method_name, env,
NULL, notify_data, notify_data_cls, flags))
@@ -1614,8 +1615,6 @@ GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host *hst,
{
struct GNUNET_MQ_Envelope *envelope;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "sending _notice_place_closing\n");
GNUNET_SOCIAL_host_announce (hst, "_notice_place_closing", env, NULL, NULL,
GNUNET_SOCIAL_ANNOUNCE_NONE);
hst->plc.disconnect_cb = disconnect_cb;
@@ -1912,6 +1911,64 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct
GNUNET_SOCIAL_App *app,
}
+struct ReconnectContext
+{
+ struct GNUNET_SOCIAL_Guest *guest;
+ int *result;
+ int64_t *max_message_id;
+ GNUNET_SOCIAL_GuestEnterCallback enter_cb;
+ void *enter_cls;
+};
+
+
+//static void
+//guest_enter_reconnect_cb (void *cls,
+// int result,
+// const struct GNUNET_CRYPTO_EddsaPublicKey
*place_pub_key,
+// uint64_t max_message_id)
+//{
+// struct ReconnectContext *reconnect_ctx = cls;
+//
+// GNUNET_assert (NULL != reconnect_ctx);
+// reconnect_ctx->result = GNUNET_new (int);
+// *(reconnect_ctx->result) = result;
+// reconnect_ctx->max_message_id = GNUNET_new (int64_t);
+// *(reconnect_ctx->max_message_id) = max_message_id;
+//}
+//
+//
+//static void
+//guest_entry_dcsn_reconnect_cb (void *cls,
+// int is_admitted,
+// const struct GNUNET_PSYC_Message *entry_resp)
+//{
+// struct ReconnectContext *reconnect_ctx = cls;
+// struct GNUNET_SOCIAL_Guest *gst = reconnect_ctx->guest;
+//
+// GNUNET_assert (NULL != reconnect_ctx);
+// GNUNET_assert (NULL != reconnect_ctx->result);
+// GNUNET_assert (NULL != reconnect_ctx->max_message_id);
+// if (GNUNET_YES != is_admitted)
+// {
+// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+// "Guest was rejected after calling "
+// "GNUNET_SOCIAL_guest_enter_reconnect ()\n");
+// }
+// else if (NULL != reconnect_ctx->enter_cb)
+// {
+// GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+// "guest reconnected!\n");
+// reconnect_ctx->enter_cb (reconnect_ctx->enter_cls,
+// *(reconnect_ctx->result),
+// &gst->plc.pub_key,
+// *(reconnect_ctx->max_message_id));
+// }
+// GNUNET_free (reconnect_ctx->result);
+// GNUNET_free (reconnect_ctx->max_message_id);
+// GNUNET_free (reconnect_ctx);
+//}
+
+
/**
* Reconnect to an already entered place as guest.
*
@@ -1957,7 +2014,6 @@ GNUNET_SOCIAL_guest_enter_reconnect (struct
GNUNET_SOCIAL_GuestConnection *gconn
plc->ego_pub_key = gconn->plc_msg.ego_pub_key;
plc->op = GNUNET_OP_create ();
-
gst->enter_cb = local_enter_cb;
gst->cb_cls = cls;
@@ -1993,9 +2049,6 @@ GNUNET_SOCIAL_guest_talk (struct GNUNET_SOCIAL_Guest *gst,
void *notify_data_cls,
enum GNUNET_SOCIAL_TalkFlags flags)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "PSYC_transmit_message for guest\n");
-
struct GNUNET_SOCIAL_Place *plc = &gst->plc;
GNUNET_assert (NULL != plc->tmit);
--
To stop receiving notification emails like this one, please contact
address@hidden
- [GNUnet-SVN] [gnunet] 42/64: added logging, (continued)
- [GNUnet-SVN] [gnunet] 42/64: added logging, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 54/64: test_social: less services and less noise in the output, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 34/64: introduce part request / part ack messages (for leaving multicast groups) and related fixes, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 43/64: fixed compile error, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 29/64: use comfort functions of MQ API, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 30/64: Introduce PART/PART_ACK messages (tests will fail until multicast module is adapted, too), gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 22/64: protocol change: add ack message for guests/hosts leaving a place, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 44/64: tried to print out stacktrace, not working. removed., gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 50/64: remove debug assertion; add debug output, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 59/64: master/slave pointers must not be NULL immediatly after sending leave request, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 58/64: fixing the place leave logic after protocol change,
gnunet <=
- [GNUnet-SVN] [gnunet] 55/64: test_psyc: less services and less noise in the output, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 60/64: actually test reconnecting; result in enter callback must always be GNUNET_OK, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 56/64: result is a boolean; stylistic changes, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 52/64: stylistic fix, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 61/64: consider entry decision while re-entering a place, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 27/64: Use MQ API instead of manually allocating messages; simplify logic in handle_client_psyc_message; cleanup, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 45/64: actually use the is_disconnecting flag; debug output; remove dead code, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 46/64: don't shutdown before all members and origin have disconnected, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 38/64: Merge branch 'fix_social' of gnunet.org:gnunet into fix_social, gnunet, 2017/12/30
- [GNUnet-SVN] [gnunet] 48/64: we have to destroy channels to the origin when cleaning up a member, gnunet, 2017/12/30