gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated (d01f1bd83 -> 5c8feda7f)


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated (d01f1bd83 -> 5c8feda7f)
Date: Sat, 30 Dec 2017 20:57:45 +0100

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

lurchi pushed a change to branch master
in repository gnunet.

    from d01f1bd83 doc fix: not ie peers but sometimes called peers
     new 6d067bc95 trying to fix test_social and social service with a lot of 
debug outputs
     new e3d4e018b start social service before running the test (not sure if 
needed)
     new 7478bbf75 don't call GNUNET_SERVICE_client_continue twice; maybe fix 
bug resulting from destroying MQ too early
     new 7ca96c1ce we were on the wood way
     new b829c5817 -we no enter to place
     new 2af1f1b81 Merge branch 'fix_social' of ssh://gnunet.org/gnunet into 
fix_social
     new 6490b5f31 added mq logging
     new b822e98f7 added logging
     new e429bb239 misc social hacking with Lurchi
     new 42dc7e7b6 fix wrong condition, do only drop if it has not been 
dropped, instead of causing double-drop
     new 059e364e5 clarify use of client_drop
     new da376896f handle service disconnect without crashing if reconnect fails
     new e1e838cdb better logging of message processing errors in mq handling
     new cfd5e9d74 do handle CTRL-C properly in test_social
     new ca7839267 logging, cosmetic fixes
     new d10108c80 minor style fix
     new 17f5db6f7 allow MST callback to distinguish between disconnect and 
parse error situations, and only log for the hard errors
     new 7c1ce9a71 Fix tcp on exit crash -- could have sworn I fixed this one 
before
     new c9e414861 protocol change: add ack message for guests/hosts leaving a 
place
     new 2b9f858b1 improve documentation
     new 5d2fadf53 finalize protocol change (fixes message loss when leaving a 
place)
     new 6599b4d49 Use MQ API instead of manually allocating messages; simplify 
logic in handle_client_psyc_message; cleanup
     new 51a27f583 use comfort functions of MQ API
     new 08d1fb4ad Introduce PART/PART_ACK messages (tests will fail until 
multicast module is adapted, too)
     new c030c80e4 commented out wrong message type
     new 9cf0e753f introduce part request / part ack messages (for leaving 
multicast groups) and related fixes
     new 525a60f69 added FIXMEs
     new fc1b64c4c added FIXME
     new 130d7e66a mark channel as disconnectin when a part request is sent; 
cleanup
     new 71e1a09e3 WARNING -> DEBUG
     new b31af32af revert commit 6490b5f31e58e9ec008f8c5ceda28f6054f1bbba
     new f2f8d311f actually use the is_disconnecting flag; debug output; remove 
dead code
     new cbb68b43b don't shutdown before all members and origin have 
disconnected
     new 2eb28778d added logging
     new ea5102e5e Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new bf2169967 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new 12997f914 changed log levels
     new d2fad46f2 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new 7399d1024 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new e38ec7081 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new 95385d9d2 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new e0eb3c8ba Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new 3cde37cf7 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new 7d957ddfa added logging
     new 4341c875c fixed compile error
     new 1522bb784 tried to print out stacktrace, not working. removed.
     new a768af6e3 Merge branch 'fix_social' of gnunet.org:gnunet into 
fix_social
     new 2668ec4f8 we have to destroy channels to the origin when cleaning up a 
member
     new 28c941178 forgot to call GNUNET_SERVICE_client_continue
     new 804c40112 remove debug assertion; add debug output
     new 1e0f7ee75 be more clear about test procedure (use self-explanatory 
function names)
     new 1bffe9cbd stylistic fix
     new 58c53e5c8 unified debug output (allows grep OP ID)
     new 843ab25fb test_social: less services and less noise in the output
     new d5698902c test_psyc: less services and less noise in the output
     new aef12de46 result is a boolean; stylistic changes
     new 56c5769e1 test_social runs into the case GNUNET_YES == 
grp->is_disconnected
     new ad24a2edf fixing the place leave logic after protocol change
     new af9ae1f37 master/slave pointers must not be NULL immediatly after 
sending leave request
     new cc77132e6 actually test reconnecting; result in enter callback must 
always be GNUNET_OK
     new 682bf4377 consider entry decision while re-entering a place
     new 1d6a686cc cleanup
     new 8412625bb Revert "tried to print out stacktrace, not working. removed."
     new 5c8feda7f Merge branch 'fix_social'

The 64 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/cadet/gnunet-service-cadet_tunnels.c           |   4 +-
 .../gnunet-helper-audio-playback-gst.c             |   5 +
 src/conversation/gnunet-helper-audio-playback.c    |   5 +
 src/conversation/gnunet_gst.c                      |   5 +
 src/conversation/microphone.c                      |   4 +-
 src/core/gnunet-service-core.c                     |   3 +
 src/core/gnunet-service-core_kx.c                  |   3 +
 src/fs/fs_dirmetascan.c                            |   3 +
 src/include/gnunet_mst_lib.h                       |   4 +-
 src/include/gnunet_protocols.h                     |  30 +-
 src/include/gnunet_service_lib.h                   |   7 +-
 src/multicast/gnunet-service-multicast.c           | 248 ++++---
 src/multicast/multicast_api.c                      |  51 +-
 src/multicast/test_multicast_multipeer.c           | 312 +++++----
 src/psyc/gnunet-service-psyc.c                     | 131 ++--
 src/psyc/psyc_api.c                                | 103 ++-
 src/psyc/test_psyc.c                               |  28 +-
 src/psyc/test_psyc.conf                            |  16 +
 src/psycstore/psycstore_api.c                      |  10 +-
 src/social/gnunet-service-social.c                 | 774 +++++++++++----------
 src/social/gnunet-social.c                         |  26 +-
 src/social/social_api.c                            | 292 +++++---
 src/social/test_social.c                           | 268 ++++---
 src/social/test_social.conf                        |  19 +
 src/statistics/gnunet-service-statistics.c         |   4 +-
 src/testbed/gnunet-helper-testbed.c                |   7 +-
 src/transport/gnunet-helper-transport-wlan-dummy.c |   6 +
 src/transport/plugin_transport_http_server.c       |   2 +-
 src/util/client.c                                  |  41 +-
 src/util/mq.c                                      |  22 +
 src/util/mst.c                                     |  27 +-
 src/util/scheduler.c                               |   4 +-
 src/util/service.c                                 |  31 +-
 src/vpn/gnunet-service-vpn.c                       |   3 +
 34 files changed, 1500 insertions(+), 998 deletions(-)

diff --git a/src/cadet/gnunet-service-cadet_tunnels.c 
b/src/cadet/gnunet-service-cadet_tunnels.c
index 22e19ef70..fb91a4a6a 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.c
+++ b/src/cadet/gnunet-service-cadet_tunnels.c
@@ -2856,7 +2856,9 @@ handle_plaintext_channel_destroy (void *cls,
  *
  * @param cls the `struct CadetTunnel` that got the message
  * @param msg the message
- * @return #GNUNET_OK (continue to process)
+ * @return #GNUNET_OK on success (always)
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 handle_decrypted (void *cls,
diff --git a/src/conversation/gnunet-helper-audio-playback-gst.c 
b/src/conversation/gnunet-helper-audio-playback-gst.c
index 264b14e76..002fed6c7 100644
--- a/src/conversation/gnunet-helper-audio-playback-gst.c
+++ b/src/conversation/gnunet-helper-audio-playback-gst.c
@@ -221,6 +221,11 @@ feed_buffer_to_gst (const char *audio, size_t b_len)
 
 /**
  * Message callback
+ *
+ * @param msg message we received.
+ * @return #GNUNET_OK on success,
+ *     #GNUNET_NO to stop further processing due to disconnect (no error)
+ *     #GNUNET_SYSERR to stop further processing due to error
  */
 static int
 stdin_receiver (void *cls,
diff --git a/src/conversation/gnunet-helper-audio-playback.c 
b/src/conversation/gnunet-helper-audio-playback.c
index 4344e1d41..18f63ad18 100644
--- a/src/conversation/gnunet-helper-audio-playback.c
+++ b/src/conversation/gnunet-helper-audio-playback.c
@@ -546,6 +546,11 @@ ogg_demux_and_decode ()
 
 /**
  * Message callback
+ *
+ * @param msg message we received.
+ * @return #GNUNET_OK on success,
+ *     #GNUNET_NO to stop further processing due to disconnect (no error)
+ *     #GNUNET_SYSERR to stop further processing due to error
  */
 static int
 stdin_receiver (void *cls,
diff --git a/src/conversation/gnunet_gst.c b/src/conversation/gnunet_gst.c
index 52cb2ccbc..828b35077 100644
--- a/src/conversation/gnunet_gst.c
+++ b/src/conversation/gnunet_gst.c
@@ -649,6 +649,11 @@ gnunet_read (GNUNET_gstData * d)
 
 /**
  * Message callback
+ *
+ * @param msg message we received.
+ * @return #GNUNET_OK on success,
+ *     #GNUNET_NO to stop further processing due to disconnect (no error)
+ *     #GNUNET_SYSERR to stop further processing due to error
  */
 static int
 stdin_receiver (void *cls,
diff --git a/src/conversation/microphone.c b/src/conversation/microphone.c
index 7871433a3..11468fc59 100644
--- a/src/conversation/microphone.c
+++ b/src/conversation/microphone.c
@@ -65,7 +65,9 @@ struct Microphone
  *
  * @param cls clsoure with our `struct Microphone`
  * @param msg the message from the helper
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 process_record_messages (void *cls,
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 625bf9655..214f72904 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -426,6 +426,9 @@ struct TokenizerContext
  *
  * @param cls reservation request (`struct TokenizerContext`)
  * @param message the actual message
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 tokenized_cb (void *cls,
diff --git a/src/core/gnunet-service-core_kx.c 
b/src/core/gnunet-service-core_kx.c
index c80fbb322..944d1e692 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -708,6 +708,9 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
  *
  * @param cls the `struct GSC_KeyExchangeInfo`
  * @param m the message
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 deliver_message (void *cls,
diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c
index 7b9f178fd..8a3e37b49 100644
--- a/src/fs/fs_dirmetascan.c
+++ b/src/fs/fs_dirmetascan.c
@@ -246,6 +246,9 @@ finish_scan (void *cls)
  *
  * @param cls the closure (directory scanner object)
  * @param msg message from the helper process
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 process_helper_msgs (void *cls,
diff --git a/src/include/gnunet_mst_lib.h b/src/include/gnunet_mst_lib.h
index 7a1ca7a55..fe6524eb3 100644
--- a/src/include/gnunet_mst_lib.h
+++ b/src/include/gnunet_mst_lib.h
@@ -61,7 +61,9 @@ struct GNUNET_MessageStreamTokenizer;
  *
  * @param cls closure
  * @param message the actual message
- * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success,
+ *     #GNUNET_NO to stop further processing due to disconnect (no error)
+ *     #GNUNET_SYSERR to stop further processing due to error
  */
 typedef int
 (*GNUNET_MessageTokenizerCallback) (void *cls,
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 72054913f..9cfd00e39 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2067,7 +2067,11 @@ extern "C"
 /** S->C: slave join acknowledgement */
 #define GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK 684
 
-/* 685-686 */
+/** C->S: request to part from a channel */
+#define GNUNET_MESSAGE_TYPE_PSYC_PART_REQUEST 685
+
+/** S->C: acknowledgement that a slave of master parted from a channel */
+#define GNUNET_MESSAGE_TYPE_PSYC_PART_ACK 686
 
 /** M->S->C: incoming join request from multicast */
 #define GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST 687
@@ -2258,6 +2262,7 @@ extern "C"
  */
 #define GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK 755
 
+// FIXME: this is never used!
 /**
  * Group terminated.
  */
@@ -2398,35 +2403,38 @@ extern "C"
 /** C->S: request to leave a place */
 #define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE 848
 
+/** S->C: place leave acknowledgement */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK 849
+
 /** C->S: add place to GNS zone */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE 849
+#define GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE 850
 
 /** C->S: add nym to GNS zone */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM 850
+#define GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM 851
 
 /** C->S: connect application */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT 851
+#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT 852
 
 /** C->S: detach a place from application */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH 852
+#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH 853
 
 /** S->C: notify about an existing ego */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO 853
+#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO 854
 
 /** S->C: end of ego list */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END 854
+#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END 855
 
 /** S->C: notify about an existing place */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE 855
+#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE 856
 
 /** S->C: end of place list */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END 856
+#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END 857
 
 /** C->S: set message processing flags */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET 860
+#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET 858
 
 /** C->S: clear message processing flags */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR 861
+#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR 859
 
 
/*******************************************************************************
  * X-VINE DHT messages
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h
index aacafe956..dda827c95 100644
--- a/src/include/gnunet_service_lib.h
+++ b/src/include/gnunet_service_lib.h
@@ -366,11 +366,16 @@ GNUNET_SERVICE_client_disable_continue_warning (struct 
GNUNET_SERVICE_Client *c)
 /**
  * Ask the server to disconnect from the given client.  This is the
  * same as returning #GNUNET_SYSERR within the check procedure when
- * handling a message, wexcept that it allows dropping of a client even
+ * handling a message, except that it allows dropping of a client even
  * when not handling a message from that client.  The `disconnect_cb`
  * will be called on @a c even if the application closes the connection
  * using this function.
  *
+ * This function should be called (outside of util's internal logic)
+ * if (and usually only if) the client has violated the
+ * protocol. Otherwise, we should leave it to the client to disconnect
+ * from the service.
+ *
  * @param c client to disconnect now
  */
 void
diff --git a/src/multicast/gnunet-service-multicast.c 
b/src/multicast/gnunet-service-multicast.c
index 2f4dc8a14..ba1086cc5 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -137,6 +137,7 @@ struct Channel
    */
   struct GNUNET_CADET_Channel *channel;
 
+  // FIXME: not used
   /**
    * CADET transmission handle.
    */
@@ -228,7 +229,7 @@ struct Group
   /**
    * Is the client disconnected? #GNUNET_YES or #GNUNET_NO
    */
-  uint8_t disconnected;
+  uint8_t is_disconnected;
 
   /**
    * Is this an origin (#GNUNET_YES), or member (#GNUNET_NO)?
@@ -365,6 +366,8 @@ client_send_join_decision (struct Member *mem,
 static void
 shutdown_task (void *cls)
 {
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "shutting down\n");
   if (NULL != cadet)
   {
     GNUNET_CADET_disconnect (cadet);
@@ -420,6 +423,11 @@ cleanup_member (struct Member *mem)
     GNUNET_free (mem->join_dcsn);
     mem->join_dcsn = NULL;
   }
+  if (NULL != mem->origin_channel)
+  {
+    GNUNET_CADET_channel_destroy (mem->origin_channel->channel);
+    mem->origin_channel = NULL;
+  }
   GNUNET_CONTAINER_multihashmap_remove (members, &grp->pub_key_hash, mem);
   GNUNET_free (mem);
 }
@@ -553,36 +561,47 @@ client_send (struct GNUNET_SERVICE_Client *client,
  * Send message to all clients connected to the group.
  */
 static void
-client_send_group (const struct Group *grp,
-                   const struct GNUNET_MessageHeader *msg)
+client_send_group_keep_envelope (const struct Group *grp,
+                                 struct GNUNET_MQ_Envelope *env)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "%p Sending message to all clients of the group.\n", grp);
+  struct ClientList *cli = grp->clients_head;
 
-  struct ClientList *cl = grp->clients_head;
-  while (NULL != cl)
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "%p Sending message to all clients of the group.\n",
+              grp);
+  while (NULL != cli)
   {
-    struct GNUNET_MQ_Envelope *
-      env = GNUNET_MQ_msg_copy (msg);
-
-    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cl->client),
-                    env);
-    cl = cl->next;
+    GNUNET_MQ_send_copy (GNUNET_SERVICE_client_get_mq (cli->client),
+                         env);
+    cli = cli->next;
   }
 }
 
 
 /**
+ * Send message to all clients connected to the group and
+ * takes care of freeing @env.
+ */
+static void
+client_send_group (const struct Group *grp,
+                   struct GNUNET_MQ_Envelope *env)
+{
+  client_send_group_keep_envelope (grp, env);
+  GNUNET_MQ_discard (env);
+}
+
+
+/**
  * Iterator callback for sending a message to origin clients.
  */
 static int
 client_send_origin_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
                        void *origin)
 {
-  const struct GNUNET_MessageHeader *msg = cls;
+  struct GNUNET_MQ_Envelope *env = cls;
   struct Member *orig = origin;
 
-  client_send_group (&orig->group, msg);
+  client_send_group_keep_envelope (&orig->group, env);
   return GNUNET_YES;
 }
 
@@ -594,12 +613,12 @@ static int
 client_send_member_cb (void *cls, const struct GNUNET_HashCode *pub_key_hash,
                        void *member)
 {
-  const struct GNUNET_MessageHeader *msg = cls;
+  struct GNUNET_MQ_Envelope *env = cls;
   struct Member *mem = member;
 
   if (NULL != mem->join_dcsn)
   { /* Only send message to admitted members */
-    client_send_group (&mem->group, msg);
+    client_send_group_keep_envelope (&mem->group, env);
   }
   return GNUNET_YES;
 }
@@ -615,15 +634,16 @@ client_send_member_cb (void *cls, const struct 
GNUNET_HashCode *pub_key_hash,
  */
 static int
 client_send_all (struct GNUNET_HashCode *pub_key_hash,
-                 const struct GNUNET_MessageHeader *msg)
+                 struct GNUNET_MQ_Envelope *env)
 {
   int n = 0;
   n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
                                                    client_send_origin_cb,
-                                                   (void *) msg);
+                                                   (void *) env);
   n += GNUNET_CONTAINER_multihashmap_get_multiple (members, pub_key_hash,
                                                    client_send_member_cb,
-                                                   (void *) msg);
+                                                   (void *) env);
+  GNUNET_MQ_discard (env);
   return n;
 }
 
@@ -636,14 +656,14 @@ client_send_all (struct GNUNET_HashCode *pub_key_hash,
  */
 static int
 client_send_random (struct GNUNET_HashCode *pub_key_hash,
-                    const struct GNUNET_MessageHeader *msg)
+                    struct GNUNET_MQ_Envelope *env)
 {
   int n = 0;
   n = GNUNET_CONTAINER_multihashmap_get_random (origins, client_send_origin_cb,
-                                                 (void *) msg);
+                                                 (void *) env);
   if (n <= 0)
     n = GNUNET_CONTAINER_multihashmap_get_random (members, 
client_send_member_cb,
-                                                   (void *) msg);
+                                                   (void *) env);
   return n;
 }
 
@@ -658,12 +678,12 @@ client_send_random (struct GNUNET_HashCode *pub_key_hash,
  */
 static int
 client_send_origin (struct GNUNET_HashCode *pub_key_hash,
-                    const struct GNUNET_MessageHeader *msg)
+                    struct GNUNET_MQ_Envelope *env)
 {
   int n = 0;
   n += GNUNET_CONTAINER_multihashmap_get_multiple (origins, pub_key_hash,
                                                    client_send_origin_cb,
-                                                   (void *) msg);
+                                                   (void *) env);
   return n;
 }
 
@@ -677,17 +697,12 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash,
 static void
 client_send_ack (struct GNUNET_HashCode *pub_key_hash)
 {
+  struct GNUNET_MQ_Envelope *env;
+
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Sending message ACK to client.\n");
-
-  static struct GNUNET_MessageHeader *msg = NULL;
-  if (NULL == msg)
-  {
-    msg = GNUNET_malloc (sizeof (*msg));
-    msg->type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_FRAGMENT_ACK);
-    msg->size = htons (sizeof (*msg));
-  }
-  client_send_all (pub_key_hash, msg);
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_FRAGMENT_ACK);
+  client_send_all (pub_key_hash, env);
 }
 
 
@@ -983,7 +998,8 @@ handle_cadet_join_request (void *cls,
   chn->peer = req->peer;
   chn->join_status = JOIN_WAITING;
 
-  client_send_all (&group_pub_hash, &req->header);
+  client_send_all (&group_pub_hash,
+                   GNUNET_MQ_msg_copy (&req->header));
 }
 
 
@@ -1102,7 +1118,8 @@ handle_cadet_message (void *cls,
 {
   struct Channel *chn = cls;
   GNUNET_CADET_receive_done (chn->channel);
-  client_send_all (&chn->group_pub_hash, &msg->header);
+  client_send_all (&chn->group_pub_hash,
+                   GNUNET_MQ_msg_copy (&msg->header));
 }
 
 
@@ -1153,30 +1170,32 @@ handle_cadet_request (void *cls,
 {
   struct Channel *chn = cls;
   GNUNET_CADET_receive_done (chn->channel);
-  client_send_origin (&chn->group_pub_hash, &req->header);
+  client_send_origin (&chn->group_pub_hash,
+                      GNUNET_MQ_msg_copy (&req->header));
 }
 
 
-static int
-check_cadet_replay_request (void *cls,
-                            const struct MulticastReplayRequestMessage *req)
-{
-  uint16_t size = ntohs (req->header.size);
-  if (size < sizeof (*req))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-
-  struct Channel *chn = cls;
-  if (NULL == chn)
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-
-  return GNUNET_OK;
-}
+// FIXME: do checks in handle_cadet_replay_request
+//static int
+//check_cadet_replay_request (void *cls,
+//                            const struct MulticastReplayRequestMessage *req)
+//{
+//  uint16_t size = ntohs (req->header.size);
+//  if (size < sizeof (*req))
+//  {
+//    GNUNET_break_op (0);
+//    return GNUNET_SYSERR;
+//  }
+//
+//  struct Channel *chn = cls;
+//  if (NULL == chn)
+//  {
+//    GNUNET_break_op (0);
+//    return GNUNET_SYSERR;
+//  }
+//
+//  return GNUNET_OK;
+//}
 
 
 /**
@@ -1187,6 +1206,7 @@ handle_cadet_replay_request (void *cls,
                              const struct MulticastReplayRequestMessage *req)
 {
   struct Channel *chn = cls;
+
   GNUNET_CADET_receive_done (chn->channel);
 
   struct MulticastReplayRequestMessage rep = *req;
@@ -1203,12 +1223,16 @@ handle_cadet_replay_request (void *cls,
                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
   }
   struct GNUNET_HashCode key_hash;
-  replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset,
-                   rep.flags, &key_hash);
+  replay_key_hash (rep.fragment_id,
+                   rep.message_id,
+                   rep.fragment_offset,
+                   rep.flags,
+                   &key_hash);
   GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn,
                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 
-  client_send_random (&chn->group_pub_hash, &rep.header);
+  client_send_random (&chn->group_pub_hash,
+                      GNUNET_MQ_msg_copy (&rep.header));
 }
 
 
@@ -1290,10 +1314,10 @@ cadet_channel_create (struct Group *grp, struct 
GNUNET_PeerIdentity *peer)
                            struct MulticastJoinDecisionMessageHeader,
                            chn),
 
-    GNUNET_MQ_hd_var_size (cadet_replay_request,
-                           GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
-                           struct MulticastReplayRequestMessage,
-                           chn),
+    GNUNET_MQ_hd_fixed_size (cadet_replay_request,
+                             GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
+                             struct MulticastReplayRequestMessage,
+                             chn),
 
     GNUNET_MQ_hd_var_size (cadet_replay_response,
                            GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
@@ -1357,6 +1381,7 @@ handle_client_origin_start (void *cls,
     grp->is_origin = GNUNET_YES;
     grp->pub_key = pub_key;
     grp->pub_key_hash = pub_key_hash;
+    grp->is_disconnected = GNUNET_NO;
 
     GNUNET_CONTAINER_multihashmap_put (origins, &grp->pub_key_hash, orig,
                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
@@ -1379,10 +1404,10 @@ handle_client_origin_start (void *cls,
                              struct MulticastJoinRequestMessage,
                              grp),
 
-      GNUNET_MQ_hd_var_size (cadet_replay_request,
-                             GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
-                             struct MulticastReplayRequestMessage,
-                             grp),
+      GNUNET_MQ_hd_fixed_size (cadet_replay_request,
+                               GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
+                               struct MulticastReplayRequestMessage,
+                               grp),
 
       GNUNET_MQ_hd_var_size (cadet_replay_response,
                              GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE,
@@ -1484,6 +1509,7 @@ handle_client_member_join (void *cls,
     grp->is_origin = GNUNET_NO;
     grp->pub_key = msg->group_pub_key;
     grp->pub_key_hash = pub_key_hash;
+    grp->is_disconnected = GNUNET_NO;
     group_set_cadet_port_hash (grp);
   
     if (NULL == grp_mem)
@@ -1494,7 +1520,8 @@ handle_client_member_join (void *cls,
     }
     GNUNET_CONTAINER_multihashmap_put (grp_mem, &mem->pub_key_hash, mem,
                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
-
+   
+    // FIXME: should the members hash map have option UNIQUE_FAST?
     GNUNET_CONTAINER_multihashmap_put (members, &grp->pub_key_hash, mem,
                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
   }
@@ -1509,10 +1536,11 @@ handle_client_member_join (void *cls,
 
   char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&mem->pub_key);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Client connected to group %s as member %s (%s).\n",
+              "Client connected to group %s as member %s (%s). size = %d\n",
               GNUNET_h2s (&grp->pub_key_hash),
               GNUNET_h2s2 (&mem->pub_key_hash),
-              str);
+              str,
+              GNUNET_CONTAINER_multihashmap_size (members));
   GNUNET_free (str);
 
   if (NULL != mem->join_dcsn)
@@ -1567,7 +1595,9 @@ handle_client_member_join (void *cls,
       GNUNET_free (mem->join_req);
     mem->join_req = req;
 
-    if (0 == client_send_origin (&grp->pub_key_hash, &mem->join_req->header))
+    if (0 ==
+        client_send_origin (&grp->pub_key_hash,
+                            GNUNET_MQ_msg_copy (&mem->join_req->header)))
     { /* No local origins, send to remote origin */
       cadet_send_join_request (mem);
     }
@@ -1580,7 +1610,7 @@ static void
 client_send_join_decision (struct Member *mem,
                            const struct MulticastJoinDecisionMessageHeader 
*hdcsn)
 {
-  client_send_group (&mem->group, &hdcsn->header);
+  client_send_group (&mem->group, GNUNET_MQ_msg_copy (&hdcsn->header));
 
   const struct MulticastJoinDecisionMessage *
     dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1];
@@ -1621,8 +1651,9 @@ handle_client_join_decision (void *cls,
     GNUNET_SERVICE_client_drop (client);
     return;
   }
+  GNUNET_assert (GNUNET_NO == grp->is_disconnected);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Got join decision from client for group %s..\n",
+              "%p got join decision from client for group %s..\n",
               grp, GNUNET_h2s (&grp->pub_key_hash));
 
   struct GNUNET_CONTAINER_MultiHashMap *
@@ -1652,6 +1683,32 @@ handle_client_join_decision (void *cls,
 }
 
 
+static void
+handle_client_part_request (void *cls,
+                            const struct GNUNET_MessageHeader *msg)
+{
+  struct Client *c = cls;
+  struct GNUNET_SERVICE_Client *client = c->client;
+  struct Group *grp = c->group;
+  struct GNUNET_MQ_Envelope *env;
+
+  if (NULL == grp)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (client);
+    return;
+  }
+  GNUNET_assert (GNUNET_NO == grp->is_disconnected);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "%p got part request from client for group %s.\n",
+              grp, GNUNET_h2s (&grp->pub_key_hash));
+  grp->is_disconnected = GNUNET_YES;
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK);
+  client_send_group (grp, env);
+  GNUNET_SERVICE_client_continue (client);
+}
+
+
 static int
 check_client_multicast_message (void *cls,
                                 const struct GNUNET_MULTICAST_MessageHeader 
*msg)
@@ -1667,6 +1724,7 @@ static void
 handle_client_multicast_message (void *cls,
                                  const struct GNUNET_MULTICAST_MessageHeader 
*msg)
 {
+  // FIXME: what if GNUNET_YES == grp->is_disconnected? Do we allow sending 
messages?
   struct Client *c = cls;
   struct GNUNET_SERVICE_Client *client = c->client;
   struct Group *grp = c->group;
@@ -1680,6 +1738,7 @@ handle_client_multicast_message (void *cls,
   GNUNET_assert (GNUNET_YES == grp->is_origin);
   struct Origin *orig = grp->origin;
 
+  // FIXME: use GNUNET_MQ_msg_copy
   /* FIXME: yucky, should use separate message structs for P2P and CS! */
   struct GNUNET_MULTICAST_MessageHeader *
     out = (struct GNUNET_MULTICAST_MessageHeader *) GNUNET_copy_message 
(&msg->header);
@@ -1696,7 +1755,7 @@ handle_client_multicast_message (void *cls,
     GNUNET_assert (0);
   }
 
-  client_send_all (&grp->pub_key_hash, &out->header);
+  client_send_all (&grp->pub_key_hash, GNUNET_MQ_msg_copy (&out->header));
   cadet_send_children (&grp->pub_key_hash, &out->header);
   client_send_ack (&grp->pub_key_hash);
   GNUNET_free (out);
@@ -1730,6 +1789,7 @@ handle_client_multicast_request (void *cls,
     GNUNET_SERVICE_client_drop (client);
     return;
   }
+  GNUNET_assert (GNUNET_NO == grp->is_disconnected);
   GNUNET_assert (GNUNET_NO == grp->is_origin);
   struct Member *mem = grp->member;
 
@@ -1751,7 +1811,9 @@ handle_client_multicast_request (void *cls,
   }
 
   uint8_t send_ack = GNUNET_YES;
-  if (0 == client_send_origin (&grp->pub_key_hash, &out->header))
+  if (0 ==
+      client_send_origin (&grp->pub_key_hash,
+                          GNUNET_MQ_msg_copy (&out->header)))
   { /* No local origins, send to remote origin */
     if (NULL != mem->origin_channel)
     {
@@ -1792,6 +1854,7 @@ handle_client_replay_request (void *cls,
     GNUNET_SERVICE_client_drop (client);
     return;
   }
+  GNUNET_assert (GNUNET_NO == grp->is_disconnected);
   GNUNET_assert (GNUNET_NO == grp->is_origin);
   struct Member *mem = grp->member;
 
@@ -1812,7 +1875,9 @@ handle_client_replay_request (void *cls,
   GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, client,
                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 
-  if (0 == client_send_origin (&grp->pub_key_hash, &rep->header))
+  if (0 ==
+      client_send_origin (&grp->pub_key_hash,
+                          GNUNET_MQ_msg_copy (&rep->header)))
   { /* No local origin, replay from remote members / origin. */
     if (NULL != mem->origin_channel)
     {
@@ -1821,6 +1886,7 @@ handle_client_replay_request (void *cls,
     else
     {
       /* FIXME: not yet connected to origin */
+      GNUNET_assert (0);
       GNUNET_SERVICE_client_drop (client);
       return;
     }
@@ -1880,6 +1946,7 @@ handle_client_replay_response_end (void *cls,
     GNUNET_SERVICE_client_drop (client);
     return;
   }
+  GNUNET_assert (GNUNET_NO == grp->is_disconnected);
 
   struct GNUNET_HashCode key_hash;
   replay_key_hash (res->fragment_id, res->message_id, res->fragment_offset,
@@ -1939,6 +2006,7 @@ handle_client_replay_response (void *cls,
     GNUNET_SERVICE_client_drop (client);
     return;
   }
+  GNUNET_assert (GNUNET_NO == grp->is_disconnected);
 
   const struct GNUNET_MessageHeader *msg = &res->header;
   if (GNUNET_MULTICAST_REC_OK == res->error_code)
@@ -2033,9 +2101,14 @@ client_notify_disconnect (void *cls,
               grp, (GNUNET_YES == grp->is_origin) ? "origin" : "member",
               GNUNET_h2s (&grp->pub_key_hash));
 
+  // FIXME (due to protocol change): here we must not remove all clients,
+  // only the one we were notified about!
   struct ClientList *cl = grp->clients_head;
   while (NULL != cl)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "iterating clients for group %p\n",
+                grp);
     if (cl->client == client)
     {
       GNUNET_CONTAINER_DLL_remove (grp->clients_head, grp->clients_tail, cl);
@@ -2049,16 +2122,7 @@ client_notify_disconnect (void *cls,
 
   if (NULL == grp->clients_head)
   { /* Last client disconnected. */
-#if FIXME
-    if (NULL != grp->tmit_head)
-    { /* Send pending messages via CADET before cleanup. */
-      transmit_message (grp);
-    }
-    else
-#endif
-    {
-      cleanup_group (grp);
-    }
+    cleanup_group (grp);
   }
 }
 
@@ -2103,9 +2167,9 @@ run (void *cls,
 GNUNET_SERVICE_MAIN
 ("multicast",
  GNUNET_SERVICE_OPTION_NONE,
- run,
- client_notify_connect,
- client_notify_disconnect,
+ &run,
+ &client_notify_connect,
+ &client_notify_disconnect,
  NULL,
  GNUNET_MQ_hd_fixed_size (client_origin_start,
                           GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START,
@@ -2119,6 +2183,10 @@ GNUNET_SERVICE_MAIN
                         GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
                         struct MulticastJoinDecisionMessageHeader,
                         NULL),
+ GNUNET_MQ_hd_fixed_size (client_part_request,
+                          GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST,
+                          struct GNUNET_MessageHeader,
+                          NULL),
  GNUNET_MQ_hd_var_size (client_multicast_message,
                         GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE,
                         struct GNUNET_MULTICAST_MessageHeader,
diff --git a/src/multicast/multicast_api.c b/src/multicast/multicast_api.c
index a8b1dee40..3c911f48a 100644
--- a/src/multicast/multicast_api.c
+++ b/src/multicast/multicast_api.c
@@ -542,31 +542,12 @@ group_cleanup (struct GNUNET_MULTICAST_Group *grp)
 
 
 static void
-group_disconnect (struct GNUNET_MULTICAST_Group *grp,
-                  GNUNET_ContinuationCallback cb,
-                  void *cls)
+handle_group_part_ack (void *cls,
+                       const struct GNUNET_MessageHeader *msg)
 {
-  grp->is_disconnecting = GNUNET_YES;
-  grp->disconnect_cb = cb;
-  grp->disconnect_cls = cls;
+  struct GNUNET_MULTICAST_Group *grp = cls;
 
-  if (NULL != grp->mq)
-  {
-    struct GNUNET_MQ_Envelope *last = GNUNET_MQ_get_last_envelope (grp->mq);
-    if (NULL != last)
-    {
-      GNUNET_MQ_notify_sent (last,
-                             (GNUNET_SCHEDULER_TaskCallback) group_cleanup, 
grp);
-    }
-    else
-    {
-      group_cleanup (grp);
-    }
-  }
-  else
-  {
-    group_cleanup (grp);
-  }
+  group_cleanup (grp);
 }
 
 
@@ -779,6 +760,10 @@ origin_connect (struct GNUNET_MULTICAST_Origin *orig)
                            GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST,
                            struct MulticastJoinRequestMessage,
                            grp),
+    GNUNET_MQ_hd_fixed_size (group_part_ack,
+                             GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK,
+                             struct GNUNET_MessageHeader,
+                             grp),
     GNUNET_MQ_hd_fixed_size (group_replay_request,
                              GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
                              struct MulticastReplayRequestMessage,
@@ -879,8 +864,13 @@ GNUNET_MULTICAST_origin_stop (struct 
GNUNET_MULTICAST_Origin *orig,
                               void *stop_cls)
 {
   struct GNUNET_MULTICAST_Group *grp = &orig->grp;
+  struct GNUNET_MQ_Envelope *env;
 
-  group_disconnect (grp, stop_cb, stop_cls);
+  grp->is_disconnecting = GNUNET_YES;
+  grp->disconnect_cb = stop_cb;
+  grp->disconnect_cls = stop_cls;
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST);
+  GNUNET_MQ_send (grp->mq, env);
 }
 
 
@@ -1065,6 +1055,10 @@ member_connect (struct GNUNET_MULTICAST_Member *mem)
                            GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION,
                            struct MulticastJoinDecisionMessageHeader,
                            mem),
+    GNUNET_MQ_hd_fixed_size (group_part_ack,
+                             GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK,
+                             struct GNUNET_MessageHeader,
+                             grp),
     GNUNET_MQ_hd_fixed_size (group_replay_request,
                              GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST,
                              struct MulticastReplayRequestMessage,
@@ -1198,16 +1192,19 @@ GNUNET_MULTICAST_member_part (struct 
GNUNET_MULTICAST_Member *mem,
                               GNUNET_ContinuationCallback part_cb,
                               void *part_cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%p Member parting.\n", mem);
   struct GNUNET_MULTICAST_Group *grp = &mem->grp;
+  struct GNUNET_MQ_Envelope *env;
 
   mem->join_dcsn_cb = NULL;
   grp->join_req_cb = NULL;
   grp->message_cb = NULL;
   grp->replay_msg_cb = NULL;
   grp->replay_frag_cb = NULL;
-
-  group_disconnect (grp, part_cb, part_cls);
+  grp->is_disconnecting = GNUNET_YES;
+  grp->disconnect_cb = part_cb;
+  grp->disconnect_cls = part_cls;
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST);
+  GNUNET_MQ_send (grp->mq, env);
 }
 
 
diff --git a/src/multicast/test_multicast_multipeer.c 
b/src/multicast/test_multicast_multipeer.c
index 5f4493993..7df1a8213 100644
--- a/src/multicast/test_multicast_multipeer.c
+++ b/src/multicast/test_multicast_multipeer.c
@@ -35,9 +35,10 @@
 
 #define PEERS_REQUESTED 12
 
-struct multicast_peer
+struct MulticastPeerContext
 {
   int peer; /* peer number */
+  struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
   const struct GNUNET_PeerIdentity *id;
   struct GNUNET_TESTBED_Operation *op; /* not yet in use */
   struct GNUNET_TESTBED_Operation *pi_op; /* not yet in use */
@@ -61,7 +62,7 @@ static void service_connect (void *cls,
                              void *ca_result,
                              const char *emsg);
 
-static struct multicast_peer **mc_peers;
+static struct MulticastPeerContext **multicast_peers;
 static struct GNUNET_TESTBED_Peer **peers;
 
 // FIXME: refactor
@@ -69,18 +70,14 @@ static struct GNUNET_TESTBED_Operation *op[PEERS_REQUESTED];
 static struct GNUNET_TESTBED_Operation *pi_op[PEERS_REQUESTED];
 
 static struct GNUNET_MULTICAST_Origin *origin;
-static struct GNUNET_MULTICAST_Member *member[PEERS_REQUESTED]; /* first 
element always empty */
+static struct GNUNET_MULTICAST_Member *members[PEERS_REQUESTED]; /* first 
element always empty */
 
 static struct GNUNET_SCHEDULER_Task *timeout_tid;
 
-static struct GNUNET_CRYPTO_EddsaPrivateKey group_key;
+//static struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
 static struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
 static struct GNUNET_HashCode group_pub_key_hash;
 
-static struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key[PEERS_REQUESTED];
-static struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key[PEERS_REQUESTED];
-
-
 /**
  * Global result for testcase.
  */
@@ -93,6 +90,8 @@ static int result;
 static void
 shutdown_task (void *cls)
 {
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "shutdown_task!\n");
   for (int i=0;i<PEERS_REQUESTED;i++)
   {
     if (NULL != op[i])
@@ -107,14 +106,16 @@ shutdown_task (void *cls)
     }
   }
 
-  if (NULL != mc_peers)
+  if (NULL != multicast_peers)
   {
     for (int i=0; i < PEERS_REQUESTED; i++)
     {
-      GNUNET_free (mc_peers[i]);
-      mc_peers[i] = NULL;
+      GNUNET_free (multicast_peers[i]->key);
+      GNUNET_free (multicast_peers[i]);
+      multicast_peers[i] = NULL;
     }
-    GNUNET_free (mc_peers);
+    GNUNET_free (multicast_peers);
+    multicast_peers = NULL;
   }
 
   if (NULL != timeout_tid)
@@ -141,11 +142,11 @@ member_join_request (void *cls,
                      const struct GNUNET_MessageHeader *join_msg,
                      struct GNUNET_MULTICAST_JoinHandle *jh)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Peer #%u (%s) sent a join request.\n", 
               mc_peer->peer, 
-              GNUNET_i2s (mc_peers[mc_peer->peer]->id));
+              GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 }
 
 
@@ -154,7 +155,7 @@ notify (void *cls,
         size_t *data_size,
         void *data)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 
   struct pingpong_msg *pp_msg = GNUNET_new (struct pingpong_msg);
   pp_msg->peer = mc_peer->peer;
@@ -178,18 +179,18 @@ member_join_decision (void *cls,
                       const struct GNUNET_PeerIdentity *relays,
                       const struct GNUNET_MessageHeader *join_msg)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
   struct GNUNET_MULTICAST_MemberTransmitHandle *req;
   
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
               "Peer #%u (%s) received a decision from origin: %s\n", 
               mc_peer->peer, 
-              GNUNET_i2s (mc_peers[mc_peer->peer]->id),
+              GNUNET_i2s (multicast_peers[mc_peer->peer]->id),
               (GNUNET_YES == is_admitted)?"accepted":"rejected");
   
   if (GNUNET_YES == is_admitted)
   {
-    req = GNUNET_MULTICAST_member_to_origin (member[mc_peer->peer],
+    req = GNUNET_MULTICAST_member_to_origin (members[mc_peer->peer],
                                              0,
                                              notify,
                                              cls);
@@ -215,10 +216,32 @@ member_replay_msg ()
 
 
 static void
+origin_disconnected_cb (void *cls)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Origin disconnected. Shutting down.\n");
+  result = GNUNET_YES;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+static void
+member_disconnected_cb (void *cls)
+{
+  for (int i = 1; i < PEERS_REQUESTED; ++i)
+    if (GNUNET_NO == multicast_peers[i]->test_ok)
+      return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "All member disconnected. Stopping origin.\n");
+  GNUNET_MULTICAST_origin_stop (origin, origin_disconnected_cb, cls);
+}
+
+
+static void
 member_message (void *cls, 
                 const struct GNUNET_MULTICAST_MessageHeader *msg)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
   struct pingpong_msg *pp_msg = (struct pingpong_msg*) &(msg[1]);
 
   if (PONG == pp_msg->msg && mc_peer->peer == pp_msg->peer)
@@ -226,18 +249,15 @@ member_message (void *cls,
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "peer #%i (%s) receives a pong\n", 
                 mc_peer->peer,
-                GNUNET_i2s (mc_peers[mc_peer->peer]->id));
-
+                GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
     mc_peer->test_ok = GNUNET_OK;
-  }
-
-  // Test for completeness of received PONGs
-  for (int i=1; i<PEERS_REQUESTED; i++)
-    if (GNUNET_NO == mc_peers[i]->test_ok)
-      return;
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "peer #%u (%s) parting from multicast group\n",
+                mc_peer->peer,
+                GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 
-  result = GNUNET_YES;
-  GNUNET_SCHEDULER_shutdown();
+    GNUNET_MULTICAST_member_part (members[mc_peer->peer], 
member_disconnected_cb, cls);
+  }
 }
 
 
@@ -349,81 +369,53 @@ origin_message (void *cls,
 
 
 static void
-multicast_da (void *cls,
-              void *op_result)
+multicast_disconnect (void *cls,
+                      void *op_result)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
 
-  if (0 == mc_peer->peer)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Origin closes multicast group\n");
-
-    GNUNET_MULTICAST_origin_stop (origin, NULL, cls);
-  }
-  else 
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "peer #%u (%s) parting from multicast group\n",
-                mc_peer->peer,
-                GNUNET_i2s (mc_peers[mc_peer->peer]->id));
-
-    GNUNET_MULTICAST_member_part (member[mc_peer->peer], NULL, cls);
-  }
 }
 
 
 static void *
-multicast_ca (void *cls,
-              const struct GNUNET_CONFIGURATION_Handle *cfg)
+multicast_connect (void *cls,
+                   const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *multicast_peer = cls;
   struct GNUNET_MessageHeader *join_msg;
   char data[64];
 
-  if (0 == mc_peer->peer)
+  multicast_peer->key = GNUNET_CRYPTO_ecdsa_key_create ();
+  if (0 == multicast_peer->peer)
   {
-    struct GNUNET_CRYPTO_EddsaPrivateKey *key = GNUNET_CRYPTO_eddsa_key_create 
();
-    GNUNET_CRYPTO_eddsa_key_get_public (key, &group_pub_key);
+    GNUNET_CRYPTO_eddsa_key_get_public (multicast_peer->key, &group_pub_key);
     GNUNET_CRYPTO_hash (&group_pub_key, sizeof (group_pub_key), 
&group_pub_key_hash);
-
-    group_key = *key;
-    
     origin = GNUNET_MULTICAST_origin_start (cfg,
-                                          &group_key,
-                                          0,
-                                          origin_join_request,
-                                          origin_replay_frag,
-                                          origin_replay_msg,
-                                          origin_request,
-                                          origin_message,
-                                          cls);
-
-    if (NULL == origin) {
+                                            multicast_peer->key,
+                                            0,
+                                            origin_join_request,
+                                            origin_replay_frag,
+                                            origin_replay_msg,
+                                            origin_request,
+                                            origin_message,
+                                            cls);
+    if (NULL == origin)
+    {
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                   "Peer #%u could not create a multicast group",
-                  mc_peer->peer);
+                  multicast_peer->peer);
       return NULL;
     }
-
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Peer #%u connected as origin to group %s\n",
-                mc_peer->peer,
+                multicast_peer->peer,
                 GNUNET_h2s (&group_pub_key_hash));
-
     return origin;
   }
   else
   {
-    // Get members keys
-    member_pub_key[mc_peer->peer] = GNUNET_new (struct 
GNUNET_CRYPTO_EcdsaPublicKey);
-    member_key[mc_peer->peer] = GNUNET_CRYPTO_ecdsa_key_create ();
-    GNUNET_CRYPTO_ecdsa_key_get_public (member_key[mc_peer->peer], 
-                                        member_pub_key[mc_peer->peer]);
-    
     sprintf(data, "Hi, I am peer #%u (%s). Can I enter?", 
-            mc_peer->peer,
-            GNUNET_i2s (mc_peers[mc_peer->peer]->id));
+            multicast_peer->peer,
+            GNUNET_i2s (multicast_peers[multicast_peer->peer]->id));
     uint8_t data_size = strlen (data) + 1;
     join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
     join_msg->size = htons (sizeof (join_msg) + data_size);
@@ -432,24 +424,25 @@ multicast_ca (void *cls,
 
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Peer #%u (%s) tries to join multicast group %s\n", 
-                mc_peer->peer,
-                GNUNET_i2s (mc_peers[mc_peer->peer]->id),
+                multicast_peer->peer,
+                GNUNET_i2s (multicast_peers[multicast_peer->peer]->id),
                 GNUNET_h2s (&group_pub_key_hash));
 
-    member[mc_peer->peer] = GNUNET_MULTICAST_member_join (cfg,
-                                                         &group_pub_key,
-                                                         
member_key[mc_peer->peer],
-                                                         mc_peers[0]->id,
-                                                         0,
-                                                         NULL,
-                                                         join_msg, /* join 
message */
-                                                         member_join_request,
-                                                         member_join_decision,
-                                                         member_replay_frag,
-                                                         member_replay_msg,
-                                                         member_message,
-                                                         cls);
-    return member[mc_peer->peer];
+    members[multicast_peer->peer] =
+      GNUNET_MULTICAST_member_join (cfg,
+                                    &group_pub_key,
+                                    multicast_peer->key,
+                                    multicast_peers[0]->id,
+                                    0,
+                                    NULL,
+                                    join_msg, /* join message */
+                                    member_join_request,
+                                    member_join_decision,
+                                    member_replay_frag,
+                                    member_replay_msg,
+                                    member_message,
+                                    cls);
+    return members[multicast_peer->peer];
   }
 }
 
@@ -460,7 +453,7 @@ peer_information_cb (void *cls,
                      const struct GNUNET_TESTBED_PeerInformation *pinfo,
                      const char *emsg)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 
   if (NULL == pinfo) {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got no peer information\n");
@@ -468,7 +461,7 @@ peer_information_cb (void *cls,
     GNUNET_SCHEDULER_shutdown ();
   }
 
-  mc_peers[mc_peer->peer]->id = pinfo->result.id;
+  multicast_peers[mc_peer->peer]->id = pinfo->result.id;
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Got peer information of %s (%s)\n", 
@@ -478,22 +471,28 @@ peer_information_cb (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Create peer #%u (%s)\n", 
               mc_peer->peer,
-              GNUNET_i2s (mc_peers[mc_peer->peer]->id));
+              GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 
   if (0 != mc_peer->peer)
   {
     /* connect to multicast service of members */
-    op[mc_peer->peer] = GNUNET_TESTBED_service_connect (NULL,                  
  /* Closure for operation */
-                                                        peers[mc_peer->peer],  
              /* The peer whose service to connect to */
-                                                        "multicast",           
  /* The name of the service */
-                                                        service_connect,       
  /* callback to call after a handle to service
-                                                                               
     is opened */
-                                                        cls,               /* 
closure for the above callback */
-                                                        multicast_ca,          
  /* callback to call with peer's configuration;
-                                                                               
     this should open the needed service connection */
-                                                        multicast_da,          
  /* callback to be called when closing the
-                                                                               
     opened service connection */
-                                                        cls);              /* 
closure for the above two callbacks */
+    op[mc_peer->peer] =
+      GNUNET_TESTBED_service_connect (/* Closure for operation */
+                                      NULL, 
+                                      /* The peer whose service to connect to 
*/
+                                      peers[mc_peer->peer],
+                                      /* The name of the service */
+                                      "multicast",
+                                      /* called after a handle to service is 
opened */
+                                      service_connect,
+                                      /* closure for the above callback */
+                                      cls,
+                                      /* called when opening the service 
connection */
+                                      multicast_connect,
+                                      /* called when closing the service 
connection */
+                                      multicast_disconnect,
+                                      /* closure for the above two callbacks */
+                                      cls);
   }
 }
 
@@ -504,14 +503,14 @@ service_connect (void *cls,
                  void *ca_result,
                  const char *emsg)
 {
-  struct multicast_peer *mc_peer = (struct multicast_peer*)cls;
+  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 
   if (NULL == ca_result)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
                 "Connection adapter not created for peer #%u (%s)\n", 
                 mc_peer->peer,
-                GNUNET_i2s (mc_peers[mc_peer->peer]->id));
+                GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 
     result = GNUNET_SYSERR;
     GNUNET_SCHEDULER_shutdown();
@@ -525,7 +524,7 @@ service_connect (void *cls,
       pi_op[i] = GNUNET_TESTBED_peer_get_information (peers[i],
                                                       
GNUNET_TESTBED_PIT_IDENTITY,
                                                       peer_information_cb,
-                                                      mc_peers[i]);
+                                                      multicast_peers[i]);
     }
   }
 }
@@ -549,50 +548,51 @@ service_connect (void *cls,
  * @param links_failed number of links testbed was unable to establish
  */ static void
 testbed_master (void *cls,
-     struct GNUNET_TESTBED_RunHandle *h,
-     unsigned int num_peers,
-     struct GNUNET_TESTBED_Peer **p,
-     unsigned int links_succeeded,
-     unsigned int links_failed)
+                struct GNUNET_TESTBED_RunHandle *h,
+                unsigned int num_peers,
+                struct GNUNET_TESTBED_Peer **p,
+                unsigned int links_succeeded,
+                unsigned int links_failed)
 {
   /* Testbed is ready with peers running and connected in a pre-defined overlay
      topology (FIXME)  */
-  
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Connected to testbed_master()\n");
-
   peers = p;
-
-  mc_peers = GNUNET_new_array (PEERS_REQUESTED, struct multicast_peer*);
+  multicast_peers = GNUNET_new_array (PEERS_REQUESTED, struct 
MulticastPeerContext*);
 
   // Create test contexts for members
   for (int i = 0; i<PEERS_REQUESTED; i++) 
   {
-    mc_peers[i] = GNUNET_new (struct multicast_peer);
-    mc_peers[i]->peer = i;
-    mc_peers[i]->test_ok = GNUNET_NO;
+    multicast_peers[i] = GNUNET_new (struct MulticastPeerContext);
+    multicast_peers[i]->peer = i;
+    multicast_peers[i]->test_ok = GNUNET_NO;
   }
-
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Create origin peer\n");
-
-  op[0] = GNUNET_TESTBED_service_connect (NULL,                    /* Closure 
for operation */
-                                          peers[0],                /* The peer 
whose service to connect to */
-                                          "multicast",             /* The name 
of the service */
-                                          service_connect,   /* callback to 
call after a handle to service
-                                                                 is opened */
-                                          mc_peers[0],                    /* 
closure for the above callback */
-                                          multicast_ca,      /* callback to 
call with peer's configuration;
-                                                                 this should 
open the needed service connection */
-                                          multicast_da,     /* callback to be 
called when closing the
-                                                                opened service 
connection */
-                                          mc_peers[0]);                   /* 
closure for the above two callbacks */
-
-  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task 
on shutdown */
-
+  op[0] =
+    GNUNET_TESTBED_service_connect (/* Closure for operation */
+                                    NULL,
+                                    /* The peer whose service to connect to */
+                                    peers[0],
+                                    /* The name of the service */
+                                    "multicast",
+                                    /* called after a handle to service is 
opened */
+                                    service_connect,
+                                    /* closure for the above callback */
+                                    multicast_peers[0],
+                                    /* called when opening the service 
connection */
+                                    multicast_connect,
+                                    /* called when closing the service 
connection */
+                                    multicast_disconnect,
+                                    /* closure for the above two callbacks */
+                                    multicast_peers[0]);
+  /* Schedule a new task on shutdown */
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
   /* Schedule the shutdown task with a delay of a few Seconds */
-  timeout_tid = GNUNET_SCHEDULER_add_delayed 
(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 400),
-                                             &timeout_task, NULL);
+  timeout_tid =
+    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
+                                  (GNUNET_TIME_UNIT_SECONDS, 400),
+                                 &timeout_task,
+                                  NULL);
 }
 
 
@@ -616,15 +616,21 @@ main (int argc, char *argv[])
   }
 
   result = GNUNET_SYSERR;
-  ret = GNUNET_TESTBED_test_run
-      ("test-multicast-multipeer",  /* test case name */
-       config_file, /* template configuration */
-       PEERS_REQUESTED,       /* number of peers to start */
-       0LL, /* Event mask - set to 0 for no event notifications */
-       NULL, /* Controller event callback */
-       NULL, /* Closure for controller event callback */
-       testbed_master, /* continuation callback to be called when testbed 
setup is complete */
-       NULL); /* Closure for the test_master callback */
+  ret =
+    GNUNET_TESTBED_test_run ("test-multicast-multipeer",
+                             config_file, 
+                             /* number of peers to start */
+                             PEERS_REQUESTED, 
+                             /* Event mask - set to 0 for no event 
notifications */
+                             0LL, 
+                             /* Controller event callback */
+                             NULL, 
+                             /* Closure for controller event callback */
+                             NULL, 
+                             /* called when testbed setup is complete */
+                             testbed_master, 
+                             /* Closure for the test_master callback */
+                             NULL); 
   if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
     return 1;
   return 0;
diff --git a/src/psyc/gnunet-service-psyc.c b/src/psyc/gnunet-service-psyc.c
index 73a3ae4ee..cf161435a 100644
--- a/src/psyc/gnunet-service-psyc.c
+++ b/src/psyc/gnunet-service-psyc.c
@@ -279,7 +279,7 @@ struct Channel
    * Is the client disconnected?
    * #GNUNET_YES or #GNUNET_NO
    */
-  uint8_t is_disconnected;
+  uint8_t is_disconnecting;
 
   /**
    * Is this a channel master (#GNUNET_YES), or slave (#GNUNET_NO)?
@@ -508,8 +508,6 @@ cleanup_master (struct Master *mst)
 {
   struct Channel *chn = &mst->channel;
 
-  if (NULL != mst->origin)
-    GNUNET_MULTICAST_origin_stop (mst->origin, NULL, NULL); // FIXME
   GNUNET_CONTAINER_multihashmap_destroy (mst->join_reqs);
   GNUNET_CONTAINER_multihashmap_remove (masters, &chn->pub_key_hash, mst);
 }
@@ -546,11 +544,6 @@ cleanup_slave (struct Slave *slv)
     GNUNET_free (slv->relays);
     slv->relays = NULL;
   }
-  if (NULL != slv->member)
-  {
-    GNUNET_MULTICAST_member_part (slv->member, NULL, NULL); // FIXME
-    slv->member = NULL;
-  }
   GNUNET_CONTAINER_multihashmap_remove (slaves, &chn->pub_key_hash, slv);
 }
 
@@ -603,15 +596,16 @@ client_notify_disconnect (void *cls,
   if (NULL == chn)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "%p User context is NULL in client_disconnect()\n",
+                "%p User context is NULL in client_notify_disconnect ()\n",
                 chn);
     GNUNET_break (0);
     return;
   }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Client (%s) disconnected from channel %s\n",
+              "%p Client %p (%s) disconnected from channel %s\n",
               chn,
+              client,
               (GNUNET_YES == chn->is_master) ? "master" : "slave",
               GNUNET_h2s (&chn->pub_key_hash));
 
@@ -645,15 +639,8 @@ client_notify_disconnect (void *cls,
                 chn,
                 (GNUNET_YES == chn->is_master) ? "master" : "slave",
                 GNUNET_h2s (&chn->pub_key_hash));
-    chn->is_disconnected = GNUNET_YES;
-    if (NULL != chn->tmit_head)
-    { /* Send pending messages to multicast before cleanup. */
-      transmit_message (chn);
-    }
-    else
-    {
-      cleanup_channel (chn);
-    }
+    chn->is_disconnecting = GNUNET_YES;
+    cleanup_channel (chn);
   }
 }
 
@@ -688,7 +675,7 @@ client_send_msg (const struct Channel *chn,
                  const struct GNUNET_MessageHeader *msg)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Sending message to clients.\n",
+              "Sending message to clients of channel %p.\n",
               chn);
 
   struct ClientList *cli = chn->clients_head;
@@ -699,7 +686,6 @@ client_send_msg (const struct Channel *chn,
 
     GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cli->client),
                     env);
-
     cli = cli->next;
   }
 }
@@ -734,7 +720,7 @@ client_send_result (struct GNUNET_SERVICE_Client *client, 
uint64_t op_id,
     GNUNET_memcpy (&res[1], data, data_size);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "%p Sending result to client for operation #%" PRIu64 ": %" 
PRId64 " (size: %u)\n",
+             "%p Sending result to client for OP ID %" PRIu64 ": %" PRId64 " 
(size: %u)\n",
              client,
               GNUNET_ntohll (op_id),
               result_code,
@@ -1202,12 +1188,12 @@ fragment_queue_insert (struct Channel *chn,
     else if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == first_ptype
              || frag_offset == fragq->header_size)
     { /* header is now complete */
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "%p Header of message %" PRIu64 " is complete.\n",
                   chn,
                   GNUNET_ntohll (mmsg->message_id));
 
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "%p Adding message %" PRIu64 " to queue.\n",
                   chn,
                   GNUNET_ntohll (mmsg->message_id));
@@ -1215,7 +1201,7 @@ fragment_queue_insert (struct Channel *chn,
     }
     else
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "%p Header of message %" PRIu64 " is NOT complete yet: %" 
PRIu64 " != %" PRIu64 "\n",
                   chn,
                   GNUNET_ntohll (mmsg->message_id),
@@ -1230,7 +1216,7 @@ fragment_queue_insert (struct Channel *chn,
     if (frag_offset == fragq->size)
       fragq->state = MSG_FRAG_STATE_END;
     else
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "%p Message %" PRIu64 " is NOT complete yet: %" PRIu64 " != 
%" PRIu64 "\n",
                   chn,
                   GNUNET_ntohll (mmsg->message_id),
@@ -1285,7 +1271,7 @@ static void
 fragment_queue_run (struct Channel *chn, uint64_t msg_id,
                     struct FragmentQueue *fragq, uint8_t drop)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%p Running message fragment queue for message %" PRIu64 " 
(state: %u).\n",
               chn,
               msg_id,
@@ -1413,7 +1399,7 @@ store_recv_state_modify_result (void *cls, int64_t result,
 static uint64_t
 message_queue_run (struct Channel *chn)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%p Running message queue.\n", chn);
   uint64_t n = 0;
   uint64_t msg_id;
@@ -1421,7 +1407,7 @@ message_queue_run (struct Channel *chn)
   while (GNUNET_YES == GNUNET_CONTAINER_heap_peek2 (chn->recv_msgs, NULL,
                                                     &msg_id))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "%p Processing message %" PRIu64 " in queue.\n", chn, msg_id);
     struct GNUNET_HashCode msg_id_hash;
     hash_key_from_hll (&msg_id_hash, msg_id);
@@ -1431,7 +1417,7 @@ message_queue_run (struct Channel *chn)
 
     if (NULL == fragq || fragq->state <= MSG_FRAG_STATE_HEADER)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "%p No fragq (%p) or header not complete.\n",
                   chn, fragq);
       break;
@@ -1453,7 +1439,7 @@ message_queue_run (struct Channel *chn)
             && (chn->max_message_id != msg_id - 1
                 && chn->max_message_id != msg_id))
         {
-          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       "%p Out of order message. "
                       "(%" PRIu64 " != %" PRIu64 " - 1)\n",
                       chn, chn->max_message_id, msg_id);
@@ -1469,7 +1455,7 @@ message_queue_run (struct Channel *chn)
         {
           if (msg_id - fragq->state_delta != chn->max_state_message_id)
           {
-            GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+            GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                         "%p Out of order stateful message. "
                         "(%" PRIu64 " - %" PRIu64 " != %" PRIu64 ")\n",
                         chn, msg_id, fragq->state_delta, 
chn->max_state_message_id);
@@ -1515,8 +1501,6 @@ message_queue_run (struct Channel *chn)
 static uint64_t
 message_queue_drop (struct Channel *chn)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "%p Dropping message queue.\n", chn);
   uint64_t n = 0;
   uint64_t msg_id;
   while (GNUNET_YES == GNUNET_CONTAINER_heap_peek2 (chn->recv_msgs, NULL,
@@ -1703,7 +1687,7 @@ store_recv_slave_counters (void *cls, int result, 
uint64_t max_fragment_id,
   res.result_code = htonl (result);
   res.max_message_id = GNUNET_htonll (max_message_id);
 
-  if (GNUNET_OK == result || GNUNET_NO == result)
+  if (GNUNET_YES == result || GNUNET_NO == result)
   {
     chn->max_message_id = max_message_id;
     chn->max_state_message_id = max_state_message_id;
@@ -1831,6 +1815,9 @@ handle_client_slave_join (void *cls,
   struct GNUNET_CRYPTO_EcdsaPublicKey slv_pub_key;
   struct GNUNET_HashCode pub_key_hash, slv_pub_hash;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "got join request from client %p\n",
+              client);
   GNUNET_CRYPTO_ecdsa_key_get_public (&req->slave_key, &slv_pub_key);
   GNUNET_CRYPTO_hash (&slv_pub_key, sizeof (slv_pub_key), &slv_pub_hash);
   GNUNET_CRYPTO_hash (&req->channel_pub_key, sizeof (req->channel_pub_key), 
&pub_key_hash);
@@ -1905,7 +1892,7 @@ handle_client_slave_join (void *cls,
     GNUNET_CONTAINER_multihashmap_put (slaves, &chn->pub_key_hash, chn,
                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
     chn->store_op = GNUNET_PSYCSTORE_counters_get (store, &chn->pub_key,
-                                                  &store_recv_slave_counters, 
slv);
+                                                   &store_recv_slave_counters, 
slv);
   }
   else
   {
@@ -1952,8 +1939,9 @@ handle_client_slave_join (void *cls,
   }
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Client connected as slave to channel %s.\n",
-              slv, GNUNET_h2s (&chn->pub_key_hash));
+              "Client %p connected as slave to channel %s.\n",
+              client,
+              GNUNET_h2s (&chn->pub_key_hash));
 
   struct ClientList *cli = GNUNET_malloc (sizeof (*cli));
   cli->client = client;
@@ -2037,6 +2025,49 @@ handle_client_join_decision (void *cls,
 }
 
 
+static void
+channel_part_cb (void *cls)
+{
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct GNUNET_MQ_Envelope *env;
+
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_PART_ACK);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+}
+
+
+static void
+handle_client_part_request (void *cls,
+                            const struct GNUNET_MessageHeader *msg)
+{
+  struct Client *c = cls;
+
+  c->channel->is_disconnecting = GNUNET_YES;
+  if (GNUNET_YES == c->channel->is_master)
+  {
+    struct Master *mst = (struct Master *) c->channel;
+   
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Got part request from master %p\n",
+                mst);
+    GNUNET_assert (NULL != mst->origin);
+    GNUNET_MULTICAST_origin_stop (mst->origin, channel_part_cb, c->client);
+  }
+  else
+  {
+    struct Slave *slv = (struct Slave *) c->channel;
+
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Got part request from slave %p\n",
+                slv);
+    GNUNET_assert (NULL != slv->member);
+    GNUNET_MULTICAST_member_part (slv->member, channel_part_cb, c->client);
+  }
+  GNUNET_SERVICE_client_continue (c->client);
+}
+
+
 /**
  * Send acknowledgement to a client.
  *
@@ -2096,7 +2127,7 @@ transmit_notify (void *cls, size_t *data_size, void *data)
   {
     GNUNET_SCHEDULER_add_now (&schedule_transmit_message, chn);
   }
-  else if (GNUNET_YES == chn->is_disconnected
+  else if (GNUNET_YES == chn->is_disconnecting
            && tmit_msg->last_ptype < GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END)
   {
     /* FIXME: handle partial message (when still in_transmit) */
@@ -2208,12 +2239,10 @@ transmit_message (struct Channel *chn)
 static void
 master_queue_message (struct Master *mst, struct TransmitMessage *tmit_msg)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%p master_queue_message()\n", mst);
-
   if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == tmit_msg->first_ptype)
   {
     tmit_msg->id = ++mst->max_message_id;
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "%p master_queue_message: message_id=%" PRIu64 "\n",
                 mst, tmit_msg->id);
     struct GNUNET_PSYC_MessageMethod *pmeth
@@ -2225,7 +2254,7 @@ master_queue_message (struct Master *mst, struct 
TransmitMessage *tmit_msg)
     }
     else if (pmeth->flags & GNUNET_PSYC_MASTER_TRANSMIT_STATE_MODIFY)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "%p master_queue_message: state_delta=%" PRIu64 "\n",
                   mst, tmit_msg->id - mst->max_state_message_id);
       pmeth->state_delta = GNUNET_htonll (tmit_msg->id
@@ -2234,7 +2263,7 @@ master_queue_message (struct Master *mst, struct 
TransmitMessage *tmit_msg)
     }
     else
     {
-        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                     "%p master_queue_message: state not modified\n", mst);
       pmeth->state_delta = GNUNET_htonll (GNUNET_PSYC_STATE_NOT_MODIFIED);
     }
@@ -2359,7 +2388,9 @@ handle_client_psyc_message (void *cls,
   if (GNUNET_YES != chn->is_ready)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "%p Channel is not ready yet, disconnecting client.\n", chn);
+                "%p Channel is not ready yet, disconnecting client %p.\n",
+                chn,
+                client);
     GNUNET_break (0);
     GNUNET_SERVICE_client_drop (client);
     return;
@@ -2789,9 +2820,9 @@ run (void *cls,
 GNUNET_SERVICE_MAIN
 ("psyc",
  GNUNET_SERVICE_OPTION_NONE,
- run,
- client_notify_connect,
- client_notify_disconnect,
+ &run,
+ &client_notify_connect,
+ &client_notify_disconnect,
  NULL,
  GNUNET_MQ_hd_fixed_size (client_master_start,
                           GNUNET_MESSAGE_TYPE_PSYC_MASTER_START,
@@ -2805,6 +2836,10 @@ GNUNET_SERVICE_MAIN
                         GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
                         struct GNUNET_PSYC_JoinDecisionMessage,
                         NULL),
+ GNUNET_MQ_hd_fixed_size (client_part_request,
+                          GNUNET_MESSAGE_TYPE_PSYC_PART_REQUEST,
+                          struct GNUNET_MessageHeader,
+                          NULL),
  GNUNET_MQ_hd_var_size (client_psyc_message,
                         GNUNET_MESSAGE_TYPE_PSYC_MESSAGE,
                         struct GNUNET_MessageHeader,
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c
index c93d8b383..d8f4c98bc 100644
--- a/src/psyc/psyc_api.c
+++ b/src/psyc/psyc_api.c
@@ -260,6 +260,10 @@ handle_channel_result (void *cls,
   GNUNET_OP_result (chn->op, GNUNET_ntohll (res->op_id),
                     GNUNET_ntohll (res->result_code),
                     data, data_size, NULL);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "handle_channel_result: Received result message with OP ID %" 
PRIu64 "\n",
+              GNUNET_ntohll (res->op_id));
 }
 
 
@@ -555,6 +559,9 @@ handle_slave_join_decision (void *cls,
 static void
 channel_cleanup (struct GNUNET_PSYC_Channel *chn)
 {
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "cleaning up channel %p\n",
+              chn);
   if (NULL != chn->tmit)
   {
     GNUNET_PSYC_transmit_destroy (chn->tmit);
@@ -562,6 +569,7 @@ channel_cleanup (struct GNUNET_PSYC_Channel *chn)
   }
   if (NULL != chn->recv)
   {
+
     GNUNET_PSYC_receive_destroy (chn->recv);
     chn->recv = NULL;
   }
@@ -585,30 +593,12 @@ channel_cleanup (struct GNUNET_PSYC_Channel *chn)
 
 
 static void
-channel_disconnect (struct GNUNET_PSYC_Channel *chn,
-                    GNUNET_ContinuationCallback cb,
-                    void *cls)
+handle_channel_part_ack (void *cls,
+                         const struct GNUNET_MessageHeader *msg)
 {
-  chn->is_disconnecting = GNUNET_YES;
-  chn->disconnect_cb = cb;
-  chn->disconnect_cls = cls;
+  struct GNUNET_PSYC_Channel *chn = cls;
 
-  if (NULL != chn->mq)
-  {
-    struct GNUNET_MQ_Envelope *env = GNUNET_MQ_get_last_envelope (chn->mq);
-    if (NULL != env)
-    {
-      GNUNET_MQ_notify_sent (env, (GNUNET_SCHEDULER_TaskCallback) 
channel_cleanup, chn);
-    }
-    else
-    {
-      channel_cleanup (chn);
-    }
-  }
-  else
-  {
-    channel_cleanup (chn);
-  }
+  channel_cleanup (chn); 
 }
 
 
@@ -671,6 +661,10 @@ master_connect (struct GNUNET_PSYC_Master *mst)
                            GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
                            struct GNUNET_PSYC_JoinRequestMessage,
                            mst),
+    GNUNET_MQ_hd_fixed_size (channel_part_ack,
+                             GNUNET_MESSAGE_TYPE_PSYC_PART_ACK,
+                             struct GNUNET_MessageHeader,
+                             chn),
     GNUNET_MQ_hd_var_size (channel_message,
                            GNUNET_MESSAGE_TYPE_PSYC_MESSAGE,
                            struct GNUNET_PSYC_MessageHeader,
@@ -694,8 +688,11 @@ master_connect (struct GNUNET_PSYC_Master *mst)
     GNUNET_MQ_handler_end ()
   };
 
-  chn->mq = GNUNET_CLIENT_connect (chn->cfg, "psyc",
-                                   handlers, master_disconnected, mst);
+  chn->mq = GNUNET_CLIENT_connect (chn->cfg,
+                                   "psyc",
+                                   handlers,
+                                   &master_disconnected,
+                                   mst);
   GNUNET_assert (NULL != chn->mq);
   chn->tmit = GNUNET_PSYC_transmit_create (chn->mq);
 
@@ -780,10 +777,13 @@ GNUNET_PSYC_master_stop (struct GNUNET_PSYC_Master *mst,
                          void *stop_cls)
 {
   struct GNUNET_PSYC_Channel *chn = &mst->chn;
+  struct GNUNET_MQ_Envelope *env;
 
-  /* FIXME: send msg to service */
-
-  channel_disconnect (chn, stop_cb, stop_cls);
+  chn->is_disconnecting = GNUNET_YES;
+  chn->disconnect_cb = stop_cb;
+  chn->disconnect_cls = stop_cls;
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_PART_REQUEST);
+  GNUNET_MQ_send (chn->mq, env);
 }
 
 
@@ -931,7 +931,8 @@ slave_reconnect (void *cls)
  * Reconnect after backoff period.
  */
 static void
-slave_disconnected (void *cls, enum GNUNET_MQ_Error error)
+slave_disconnected (void *cls,
+                    enum GNUNET_MQ_Error error)
 {
   struct GNUNET_PSYC_Slave *slv = cls;
   struct GNUNET_PSYC_Channel *chn = &slv->chn;
@@ -950,7 +951,7 @@ slave_disconnected (void *cls, enum GNUNET_MQ_Error error)
     chn->mq = NULL;
   }
   chn->reconnect_task = GNUNET_SCHEDULER_add_delayed (chn->reconnect_delay,
-                                                      slave_reconnect,
+                                                      &slave_reconnect,
                                                       slv);
   chn->reconnect_delay = GNUNET_TIME_STD_BACKOFF (chn->reconnect_delay);
 }
@@ -970,6 +971,10 @@ slave_connect (struct GNUNET_PSYC_Slave *slv)
                            GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
                            struct GNUNET_PSYC_JoinDecisionMessage,
                            slv),
+    GNUNET_MQ_hd_fixed_size (channel_part_ack,
+                             GNUNET_MESSAGE_TYPE_PSYC_PART_ACK,
+                             struct GNUNET_MessageHeader,
+                             chn),
     GNUNET_MQ_hd_var_size (channel_message,
                            GNUNET_MESSAGE_TYPE_PSYC_MESSAGE,
                            struct GNUNET_PSYC_MessageHeader,
@@ -993,9 +998,19 @@ slave_connect (struct GNUNET_PSYC_Slave *slv)
     GNUNET_MQ_handler_end ()
   };
 
-  chn->mq = GNUNET_CLIENT_connect (chn->cfg, "psyc",
-                                   handlers, slave_disconnected, slv);
-  GNUNET_assert (NULL != chn->mq);
+  chn->mq = GNUNET_CLIENT_connect (chn->cfg,
+                                   "psyc",
+                                   handlers,
+                                   &slave_disconnected,
+                                   slv);
+  if (NULL == chn->mq)
+  {
+    chn->reconnect_task = GNUNET_SCHEDULER_add_delayed (chn->reconnect_delay,
+                                                        &slave_reconnect,
+                                                        slv);
+    chn->reconnect_delay = GNUNET_TIME_STD_BACKOFF (chn->reconnect_delay);
+    return;
+  }
   chn->tmit = GNUNET_PSYC_transmit_create (chn->mq);
 
   GNUNET_MQ_send_copy (chn->mq, chn->connect_env);
@@ -1107,10 +1122,13 @@ GNUNET_PSYC_slave_part (struct GNUNET_PSYC_Slave *slv,
                         void *part_cls)
 {
   struct GNUNET_PSYC_Channel *chn = &slv->chn;
+  struct GNUNET_MQ_Envelope *env;
 
-  /* FIXME: send msg to service */
-
-  channel_disconnect (chn, part_cb, part_cls);
+  chn->is_disconnecting = GNUNET_YES;
+  chn->disconnect_cb = part_cb;
+  chn->disconnect_cls = part_cls;
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_PART_REQUEST);
+  GNUNET_MQ_send (chn->mq, env);
 }
 
 
@@ -1233,6 +1251,9 @@ GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel 
*chn,
   req->did_join = GNUNET_YES;
   req->op_id = GNUNET_htonll (GNUNET_OP_add (chn->op, result_cb, cls, NULL));
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "GNUNET_PSYC_channel_slave_add, OP ID: %" PRIu64 "\n",
+              GNUNET_ntohll (req->op_id));
   GNUNET_MQ_send (chn->mq, env);
 }
 
@@ -1283,6 +1304,9 @@ GNUNET_PSYC_channel_slave_remove (struct 
GNUNET_PSYC_Channel *chn,
   req->did_join = GNUNET_NO;
   req->op_id = GNUNET_htonll (GNUNET_OP_add (chn->op, result_cb, cls, NULL));
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "GNUNET_PSYC_channel_slave_remove, OP ID: %" PRIu64 "\n",
+              GNUNET_ntohll (req->op_id));
   GNUNET_MQ_send (chn->mq, env);
 }
 
@@ -1321,6 +1345,10 @@ channel_history_replay (struct GNUNET_PSYC_Channel *chn,
   req->message_limit = GNUNET_htonll (message_limit);
   req->flags = htonl (flags);
   req->op_id = GNUNET_htonll (hist->op_id);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "channel_history_replay, OP ID: %" PRIu64 "\n",
+              GNUNET_ntohll (req->op_id));
   GNUNET_memcpy (&req[1], method_prefix, method_size);
 
   GNUNET_MQ_send (chn->mq, env);
@@ -1459,6 +1487,11 @@ channel_state_get (struct GNUNET_PSYC_Channel *chn,
   struct GNUNET_MQ_Envelope *
     env = GNUNET_MQ_msg_extra (req, name_size, type);
   req->op_id = GNUNET_htonll (sr->op_id);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "channel_state_get, OP ID: %" PRIu64 "\n",
+              GNUNET_ntohll (req->op_id));
+
   GNUNET_memcpy (&req[1], name, name_size);
 
   GNUNET_MQ_send (chn->mq, env);
diff --git a/src/psyc/test_psyc.c b/src/psyc/test_psyc.c
index 03a1890b1..370befb9d 100644
--- a/src/psyc/test_psyc.c
+++ b/src/psyc/test_psyc.c
@@ -755,15 +755,22 @@ slave_add ()
 
 
 static void
+schedule_second_slave_join (void *cls)
+{
+  slave_join (TEST_SLAVE_JOIN_ACCEPT);
+}
+
+
+static void
 first_slave_parted (void *cls)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "First slave parted.\n");
-  slave_join (TEST_SLAVE_JOIN_ACCEPT);
+  GNUNET_SCHEDULER_add_now (&schedule_second_slave_join, NULL);
 }
 
 
 static void
-schedule_slave_part (void *cls)
+schedule_first_slave_part (void *cls)
 {
   GNUNET_PSYC_slave_part (slv, GNUNET_NO, &first_slave_parted, NULL);
 }
@@ -783,7 +790,7 @@ join_decision_cb (void *cls,
   case TEST_SLAVE_JOIN_REJECT:
     GNUNET_assert (0 == is_admitted);
     GNUNET_assert (1 == join_req_count);
-    GNUNET_SCHEDULER_add_now (&schedule_slave_part, NULL);
+    GNUNET_SCHEDULER_add_now (&schedule_first_slave_part, NULL);
     break;
 
   case TEST_SLAVE_JOIN_ACCEPT:
@@ -844,11 +851,18 @@ slave_join (int t)
   struct GNUNET_PSYC_Message *
     join_msg = GNUNET_PSYC_message_create ("_request_join", env, "some data", 
9);
 
-  slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key,
+  slv = GNUNET_PSYC_slave_join (cfg,
+                                &channel_pub_key,
+                                slave_key,
                                 GNUNET_PSYC_SLAVE_JOIN_NONE,
-                                &origin, 0, NULL,
-                                &slave_message_cb, &slave_message_part_cb,
-                                &slave_connect_cb, &join_decision_cb, NULL,
+                                &origin,
+                                0,
+                                NULL,
+                                &slave_message_cb,
+                                &slave_message_part_cb,
+                                &slave_connect_cb,
+                                &join_decision_cb,
+                                NULL,
                                 join_msg);
   GNUNET_free (join_msg);
   slv_chn = GNUNET_PSYC_slave_get_channel (slv);
diff --git a/src/psyc/test_psyc.conf b/src/psyc/test_psyc.conf
index e69de29bb..e00a614d2 100644
--- a/src/psyc/test_psyc.conf
+++ b/src/psyc/test_psyc.conf
@@ -0,0 +1,16 @@
address@hidden@ ../../contrib/no_forcestart.conf
+
+[PATHS]
+GNUNET_TEST_HOME = /tmp/gnunet-test-psyc/
+
+[transport]
+PLUGINS = tcp
+
+[nat]
+DISABLEV6 = YES
+ENABLE_UPNP = NO
+BEHIND_NAT = NO
+ALLOW_NAT = NO
+INTERNAL_ADDRESS = 127.0.0.1
+EXTERNAL_ADDRESS = 127.0.0.1
+
diff --git a/src/psycstore/psycstore_api.c b/src/psycstore/psycstore_api.c
index d79daa357..16f4a1ae9 100644
--- a/src/psycstore/psycstore_api.c
+++ b/src/psycstore/psycstore_api.c
@@ -148,14 +148,14 @@ handle_result_code (void *cls, const struct 
OperationResult *opres)
                                       str, size - sizeof (*opres), (void **) 
&op))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "handle_result_code: Received result message with operation ID: %" 
PRIu64 "\n",
+         "handle_result_code: Received result message with OP ID: %" PRIu64 
"\n",
          GNUNET_ntohll (opres->op_id));
     GNUNET_free (op);
   }
   else
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "handle_result_code: No callback registered for operation with ID %" 
PRIu64 ".\n",
+         "handle_result_code: No callback registered for OP ID %" PRIu64 ".\n",
          GNUNET_ntohll (opres->op_id));
   }
   h->reconnect_delay = GNUNET_TIME_UNIT_MILLISECONDS;
@@ -187,7 +187,7 @@ handle_result_counters (void *cls, const struct 
CountersResult *cres)
   else
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "handle_result_counters: No callback registered for operation with ID 
%" PRIu64 ".\n",
+         "handle_result_counters: No callback registered for OP ID %" PRIu64 
".\n",
          GNUNET_ntohll (cres->op_id));
   }
   h->reconnect_delay = GNUNET_TIME_UNIT_MILLISECONDS;
@@ -233,7 +233,7 @@ handle_result_fragment (void *cls, const struct 
FragmentResult *fres)
   else
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "handle_result_fragment: No callback registered for operation with ID 
%" PRIu64 ".\n",
+         "handle_result_fragment: No callback registered for OP ID %" PRIu64 
".\n",
          GNUNET_ntohll (fres->op_id));
   }
   h->reconnect_delay = GNUNET_TIME_UNIT_MILLISECONDS;
@@ -282,7 +282,7 @@ handle_result_state (void *cls, const struct StateResult 
*sres)
   else
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "handle_result_state: No callback registered for operation with ID %" 
PRIu64 ".\n",
+         "handle_result_state: No callback registered for OP ID %" PRIu64 
".\n",
          GNUNET_ntohll (sres->op_id));
   }
   h->reconnect_delay = GNUNET_TIME_UNIT_MILLISECONDS;
diff --git a/src/social/gnunet-service-social.c 
b/src/social/gnunet-service-social.c
index dee68fdb8..5b2a8ba9b 100644
--- a/src/social/gnunet-service-social.c
+++ b/src/social/gnunet-service-social.c
@@ -96,7 +96,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *apps_places;
  * Application subscriptions per place.
  * H(place_pub_key) -> H(app_id)
  */
-static struct GNUNET_CONTAINER_MultiHashMap *places_apps;
+//static struct GNUNET_CONTAINER_MultiHashMap *places_apps;
 
 /**
  * Connected applications.
@@ -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);
 }
 
@@ -537,8 +533,8 @@ cleanup_place (void *cls)
   struct Place *plc = cls;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Cleaning up place %s\n",
-              plc, GNUNET_h2s (&plc->pub_key_hash));
+              "cleaning up place %s\n",
+              GNUNET_h2s (&plc->pub_key_hash));
 
   (GNUNET_YES == plc->is_host)
     ? cleanup_host ((struct Host *) plc)
@@ -583,12 +579,19 @@ client_notify_disconnect (void *cls,
   {
     if (cli->client == client)
     {
-      GNUNET_CONTAINER_DLL_remove (plc->clients_head, plc->clients_tail, cli);
+      GNUNET_CONTAINER_DLL_remove (plc->clients_head,
+                                   plc->clients_tail,
+                                   cli);
       GNUNET_free (cli);
       break;
     }
     cli = cli->next;
   }
+  if (GNUNET_YES == plc->is_disconnecting)
+  {
+    GNUNET_PSYC_slicer_destroy (plc->slicer);
+    GNUNET_free (plc);
+  }
 }
 
 
@@ -605,46 +608,55 @@ client_notify_connect (void *cls,
                        struct GNUNET_SERVICE_Client *client,
                        struct GNUNET_MQ_Handle *mq)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client);
+  struct Client *c = GNUNET_new (struct Client);
 
-  struct Client *c = GNUNET_malloc (sizeof (*c));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Client %p connected with queue %p\n",
+              client,
+              mq);
   c->client = client;
-
   return c;
 }
 
 
 /**
- * Send message to a client.
- */
-static inline void
-client_send_msg (struct GNUNET_SERVICE_Client *client,
-                 const struct GNUNET_MessageHeader *msg)
-{
-  struct GNUNET_MQ_Envelope *
-    env = GNUNET_MQ_msg_copy (msg);
-
-  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
-                  env);
-}
-
-
-/**
- * Send message to all clients connected to a place.
+ * Send message to all clients connected to a place and
+ * takes care of freeing @env.
  */
 static void
 place_send_msg (const struct Place *plc,
-                 const struct GNUNET_MessageHeader *msg)
+                struct GNUNET_MQ_Envelope *env)
 {
+  struct ClientListItem *cli = plc->clients_head;
+  
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%p Sending message to clients of place.\n", plc);
-
-  struct ClientListItem *cli = plc->clients_head;
   while (NULL != cli)
   {
-    client_send_msg (cli->client, msg);
+    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;
   }
+  GNUNET_MQ_discard (env);
+}
+
+
+static void
+place_send_leave_ack (struct Place *plc)
+{
+  struct GNUNET_MQ_Envelope *env;
+  
+  for (struct ClientListItem *cli = plc->clients_head;
+       NULL != cli;
+       cli = cli->next)
+  {
+    env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK);
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (cli->client),
+                    env); 
+  }
 }
 
 
@@ -666,23 +678,21 @@ static void
 client_send_result (struct GNUNET_SERVICE_Client *client, uint64_t op_id,
                     int64_t result_code, const void *data, uint16_t data_size)
 {
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_OperationResultMessage *res;
 
-  res = GNUNET_malloc (sizeof (*res) + data_size);
-  res->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE);
-  res->header.size = htons (sizeof (*res) + data_size);
+  env = GNUNET_MQ_msg_extra (res,
+                             data_size,
+                             GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE);
   res->result_code = GNUNET_htonll (result_code);
   res->op_id = op_id;
   if (0 < data_size)
     GNUNET_memcpy (&res[1], data, data_size);
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "%p Sending result to client for operation #%" PRIu64 ": "
               "%" PRId64 " (size: %u)\n",
              client, GNUNET_ntohll (op_id), result_code, data_size);
-
-  client_send_msg (client, &res->header);
-  GNUNET_free (res);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env);
 }
 
 
@@ -690,19 +700,21 @@ static void
 client_send_host_enter_ack (struct GNUNET_SERVICE_Client *client,
                             struct Host *hst, uint32_t result)
 {
+  struct GNUNET_MQ_Envelope *env;
+  struct HostEnterAck *hack;
   struct Place *plc = &hst->place;
 
-  struct HostEnterAck hack;
-  hack.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK);
-  hack.header.size = htons (sizeof (hack));
-  hack.result_code = htonl (result);
-  hack.max_message_id = GNUNET_htonll (plc->max_message_id);
-  hack.place_pub_key = plc->pub_key;
+  env = GNUNET_MQ_msg (hack,
+                       GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK); 
+  hack->result_code = htonl (result);
+  hack->max_message_id = GNUNET_htonll (plc->max_message_id);
+  hack->place_pub_key = plc->pub_key;
 
   if (NULL != client)
-    client_send_msg (client, &hack.header);
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                    env);
   else
-    place_send_msg (plc, &hack.header);
+    place_send_msg (plc, env);
 }
 
 
@@ -736,7 +748,8 @@ psyc_recv_join_request (void *cls,
   GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
   GNUNET_CONTAINER_multihashmap_put (hst->join_reqs, &slave_key_hash, jh,
                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-  place_send_msg (&hst->place, &req->header);
+  place_send_msg (&hst->place,
+                  GNUNET_MQ_msg_copy (&req->header));
 }
 
 
@@ -746,18 +759,29 @@ psyc_recv_join_request (void *cls,
 static void
 psyc_slave_connected (void *cls, int result, uint64_t max_message_id)
 {
+  struct GNUNET_PSYC_CountersResultMessage *res;
+  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 =
+    (result != GNUNET_SYSERR) ? htonl (GNUNET_OK) : htonl (GNUNET_SYSERR);
+  res->max_message_id = GNUNET_htonll (plc->max_message_id);
+  place_send_msg (plc, env);
+}
 
-  struct GNUNET_PSYC_CountersResultMessage res;
-  res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
-  res.header.size = htons (sizeof (res));
-  res.result_code = htonl (result);
-  res.max_message_id = GNUNET_htonll (plc->max_message_id);
 
-  place_send_msg (plc, &res.header);
+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));
 }
 
 
@@ -771,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, &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));
 }
 
 
@@ -792,7 +830,7 @@ psyc_recv_message (void *cls,
 
   GNUNET_PSYC_slicer_message (plc->slicer, msg);
 
-  place_send_msg (plc, &msg->header);
+  place_send_msg (plc, GNUNET_MQ_msg_copy (&msg->header));
 }
 
 
@@ -1096,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,
@@ -1173,7 +1208,9 @@ app_place_add (const char *app_id,
     return GNUNET_NO;
 
   if (GNUNET_SYSERR == place_add (ereq))
+  {
     return GNUNET_SYSERR;
+  }
 
   if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (app_places, 
&ego_place_pub_hash, NULL,
                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
@@ -1181,32 +1218,6 @@ app_place_add (const char *app_id,
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-
-  struct GNUNET_HashCode place_pub_hash;
-  GNUNET_CRYPTO_hash (&ereq->place_pub_key, sizeof (ereq->place_pub_key), 
&place_pub_hash);
-
-  struct GNUNET_CONTAINER_MultiHashMap *
-    place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, 
&place_pub_hash);
-  if (NULL == place_apps)
-  {
-    place_apps = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
-    if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (places_apps, 
&place_pub_hash, place_apps,
-                                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
-    {
-      GNUNET_break (0);
-    }
-  }
-
-  size_t app_id_size = strlen (app_id) + 1;
-  void *app_id_value = GNUNET_malloc (app_id_size);
-  GNUNET_memcpy (app_id_value, app_id, app_id_size);
-
-  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (place_apps, 
&app_id_hash, app_id_value,
-                                                      
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
-  {
-    GNUNET_break (0);
-  }
-
   return GNUNET_OK;
 }
 
@@ -1223,7 +1234,10 @@ static int
 app_place_save (const char *app_id,
                 const struct PlaceEnterRequest *ereq)
 {
-  app_place_add (app_id, ereq);
+  if (GNUNET_SYSERR == app_place_add (app_id, ereq))
+  {
+    GNUNET_assert (0);
+  }
 
   if (NULL == dir_places)
     return GNUNET_SYSERR;
@@ -1304,18 +1318,6 @@ app_place_remove (const char *app_id,
   if (NULL != app_places)
     GNUNET_CONTAINER_multihashmap_remove (app_places, &place_pub_hash, NULL);
 
-  struct GNUNET_CONTAINER_MultiHashMap *
-    place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, 
&place_pub_hash);
-  if (NULL != place_apps)
-  {
-    void *app_id_value = GNUNET_CONTAINER_multihashmap_get (place_apps, 
&app_id_hash);
-    if (NULL != app_id_value)
-    {
-      GNUNET_CONTAINER_multihashmap_remove (place_apps, &app_id_hash, 
app_id_value);
-      GNUNET_free (app_id_value);
-    }
-  }
-
   int ret = GNUNET_OK;
 
   if (0 != unlink (app_place_filename))
@@ -1407,6 +1409,124 @@ msg_proc_parse (const struct MsgProcRequest *mpreq,
 }
 
 
+void
+app_notify_place (const struct GNUNET_MessageHeader *msg,
+                  struct GNUNET_SERVICE_Client *client)
+{
+  struct AppPlaceMessage *amsg;
+  struct GNUNET_MQ_Envelope *env;
+  uint16_t msg_size = ntohs (msg->size);
+  
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "%p Sending place notification of type %u to client.\n",
+              client, ntohs (msg->type));
+  switch (ntohs (msg->type))
+  {
+  case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER:
+  {
+    struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg;
+    if (msg_size < sizeof (struct HostEnterRequest))
+      return;
+    env = GNUNET_MQ_msg (amsg,
+                         GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE);
+    // FIXME: also notify about not entered places
+    amsg->place_state = GNUNET_SOCIAL_PLACE_STATE_ENTERED;
+    amsg->is_host = GNUNET_YES;
+    amsg->ego_pub_key = hreq->ego_pub_key;
+    amsg->place_pub_key = hreq->place_pub_key;
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                    env);
+    break;
+  }
+  case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER:
+  {
+    if (msg_size < sizeof (struct GuestEnterRequest))
+      return;
+    struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg;
+    env = GNUNET_MQ_msg (amsg,
+                         GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE);
+    // FIXME: also notify about not entered places
+    amsg->place_state = GNUNET_SOCIAL_PLACE_STATE_ENTERED;
+    amsg->is_host = GNUNET_NO;
+    amsg->ego_pub_key = greq->ego_pub_key;
+    amsg->place_pub_key = greq->place_pub_key;
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                    env);
+    break;
+  }
+  default:
+    return;
+  }
+}
+
+
+void
+app_notify_place_end (struct GNUNET_SERVICE_Client *client)
+{
+  struct GNUNET_MQ_Envelope *env;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "%p Sending end of place list notification to client\n",
+              client);
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+}
+
+
+void
+app_notify_ego (struct Ego *ego, struct GNUNET_SERVICE_Client *client)
+{
+  struct AppEgoMessage *emsg;
+  struct GNUNET_MQ_Envelope *env;
+  size_t name_size = strlen (ego->name) + 1;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "%p Sending ego notification to client: %s\n",
+              client, ego->name);
+  env = GNUNET_MQ_msg_extra (emsg,
+                             name_size,
+                             GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO);
+  GNUNET_CRYPTO_ecdsa_key_get_public (&ego->key, &emsg->ego_pub_key);
+  GNUNET_memcpy (&emsg[1], ego->name, name_size);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+}
+
+
+void
+app_notify_ego_end (struct GNUNET_SERVICE_Client *client)
+{
+  struct GNUNET_MQ_Envelope *env;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "%p Sending end of ego list notification to client\n",
+              client);
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+}
+
+
+int
+app_place_entry_notify (void *cls, const struct GNUNET_HashCode *key, void 
*value)
+{
+  struct GNUNET_MessageHeader *
+    msg = GNUNET_CONTAINER_multihashmap_get (places, key);
+  if (NULL != msg)
+    app_notify_place (msg, cls);
+  return GNUNET_YES;
+}
+
+
+int
+ego_entry (void *cls, const struct GNUNET_HashCode *key, void *value)
+{
+  app_notify_ego (value, cls);
+  return GNUNET_YES;
+}
+
+
 static int
 check_client_msg_proc_set (void *cls,
                            const struct MsgProcRequest *mpreq)
@@ -1518,9 +1638,8 @@ static void
 handle_client_host_enter (void *cls,
                           const struct HostEnterRequest *hr)
 {
-   struct Client *c = cls;
+  struct Client *c = cls;
   struct GNUNET_SERVICE_Client *client = c->client;
-
   struct HostEnterRequest *
     hreq = (struct HostEnterRequest *) GNUNET_copy_message (&hr->header);
 
@@ -1578,7 +1697,7 @@ handle_client_host_enter (void *cls,
   if (ret != GNUNET_SYSERR)
   {
 
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "%p Client connected as host to place %s.\n",
                 hst, GNUNET_h2s (&plc->pub_key_hash));
 
@@ -1586,6 +1705,7 @@ handle_client_host_enter (void *cls,
     cli->client = client;
     GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli);
     c->place = plc;
+    app_notify_place (&hreq->header, client);
   }
 
   GNUNET_CRYPTO_eddsa_key_clear (&hreq->place_key);
@@ -1622,8 +1742,12 @@ guest_enter (const struct GuestEnterRequest *greq, 
struct Guest **ret_gst)
   struct Ego *ego = GNUNET_CONTAINER_multihashmap_get (egos, &ego_pub_hash);
 
   if (NULL == ego)
+  {
     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);
@@ -1635,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);
 
@@ -1710,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,
@@ -1724,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;
   }
 
@@ -1734,78 +1869,96 @@ guest_enter (const struct GuestEnterRequest *greq, 
struct Guest **ret_gst)
 
 
 static int
-check_client_guest_enter (void *cls,
-                          const struct GuestEnterRequest *greq)
-{
-  return GNUNET_OK;
-}
-
-
-/**
- * Handle a connecting client entering a place as guest.
- */
-static void
-handle_client_guest_enter (void *cls,
-                           const struct GuestEnterRequest *greq)
+client_guest_enter (struct Client *c,
+                    const struct GuestEnterRequest *greq)
 {
-  struct Client *c = cls;
+  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;
-
   uint16_t remaining = ntohs (greq->header.size) - sizeof (*greq);
   const char *app_id = NULL;
   uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &greq[1],
                                                     remaining, 1, &app_id);
-  if (0 == offset)
-  {
-    GNUNET_break (0);
-    GNUNET_SERVICE_client_drop (client);
-    return;
-  }
-
   struct Guest *gst = NULL;
   struct Place *plc = NULL;
 
+  if (0 == offset)
+  {
+    return GNUNET_SYSERR;
+  }
   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;
-
-    struct GNUNET_PSYC_CountersResultMessage res;
-    res.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
-    res.header.size = htons (sizeof (res));
-    res.result_code = htonl (GNUNET_OK);
-    res.max_message_id = GNUNET_htonll (plc->max_message_id);
-
-    client_send_msg (client, &res.header);
+    env = GNUNET_MQ_msg (result_msg,
+                         GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK);
+    result_msg->result_code = htonl (GNUNET_OK);
+    result_msg->max_message_id = GNUNET_htonll (plc->max_message_id);
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                    env);
     if (NULL != gst->join_dcsn)
-      client_send_msg (client, &gst->join_dcsn->header);
-
+    { 
+      env = GNUNET_MQ_msg_copy (&gst->join_dcsn->header);
+      GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                      env);
+    }
     break;
   }
   case GNUNET_SYSERR:
-    GNUNET_break (0);
-    GNUNET_SERVICE_client_drop (client);
-    return;
+  {
+    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;
   GNUNET_CONTAINER_DLL_insert (plc->clients_head, plc->clients_tail, cli);
+  return GNUNET_OK;
+}
 
-  c->place = plc;
-  GNUNET_SERVICE_client_continue (client);
+
+static int
+check_client_guest_enter (void *cls,
+                          const struct GuestEnterRequest *greq)
+{
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handle a connecting client entering a place as guest.
+ */
+static void
+handle_client_guest_enter (void *cls,
+                           const struct GuestEnterRequest *greq)
+{
+  struct Client *c = cls;
+
+  if (GNUNET_SYSERR == client_guest_enter (c, greq))
+  {
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (c->client);
+    return;
+  }
+  GNUNET_SERVICE_client_continue (c->client);
 }
 
 
@@ -1830,7 +1983,7 @@ gns_result_guest_enter (void *cls, uint32_t rd_count,
 {
   struct GuestEnterByNameClosure *gcls = cls;
   struct Client *c = gcls->client;
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%p GNS result: %u records.\n",
               c, rd_count);
 
@@ -1882,7 +2035,7 @@ gns_result_guest_enter (void *cls, uint32_t rd_count,
   p += relay_size;
   GNUNET_memcpy (p, gcls->join_msg, join_msg_size);
 
-  handle_client_guest_enter (c, greq);
+  client_guest_enter (c, greq);
 
   GNUNET_free (gcls->app_id);
   if (NULL != gcls->password)
@@ -1960,118 +2113,7 @@ handle_client_guest_enter_by_name (void *cls,
                      GNUNET_GNSRECORD_TYPE_PLACE,
                      GNUNET_GNS_LO_DEFAULT,
                      &gns_result_guest_enter, gcls);
-}
-
-
-void
-app_notify_place (struct GNUNET_MessageHeader *msg,
-                  struct GNUNET_SERVICE_Client *client)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Sending place notification of type %u to client.\n",
-              client, ntohs (msg->type));
-
-  uint16_t msg_size = ntohs (msg->size);
-  struct AppPlaceMessage amsg;
-  amsg.header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE);
-  amsg.header.size = htons (sizeof (amsg));
-  // FIXME: also notify about not entered places
-  amsg.place_state = GNUNET_SOCIAL_PLACE_STATE_ENTERED;
-
-  switch (ntohs (msg->type))
-  {
-  case GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER:
-    if (msg_size < sizeof (struct HostEnterRequest))
-      return;
-    struct HostEnterRequest *hreq = (struct HostEnterRequest *) msg;
-    amsg.is_host = GNUNET_YES;
-    amsg.ego_pub_key = hreq->ego_pub_key;
-    amsg.place_pub_key = hreq->place_pub_key;
-    break;
-
-  case GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER:
-    if (msg_size < sizeof (struct GuestEnterRequest))
-      return;
-    struct GuestEnterRequest *greq = (struct GuestEnterRequest *) msg;
-    amsg.is_host = GNUNET_NO;
-    amsg.ego_pub_key = greq->ego_pub_key;
-    amsg.place_pub_key = greq->place_pub_key;
-    break;
-
-  default:
-    return;
-  }
-
-  client_send_msg (client, &amsg.header);
-}
-
-
-void
-app_notify_place_end (struct GNUNET_SERVICE_Client *client)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Sending end of place list notification to client\n",
-              client);
-
-  struct GNUNET_MessageHeader msg;
-  msg.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END);
-  msg.size = htons (sizeof (msg));
-
-  client_send_msg (client, &msg);
-}
-
-
-void
-app_notify_ego (struct Ego *ego, struct GNUNET_SERVICE_Client *client)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Sending ego notification to client: %s\n",
-              client, ego->name);
-
-  size_t name_size = strlen (ego->name) + 1;
-  struct AppEgoMessage *emsg = GNUNET_malloc (sizeof (*emsg) + name_size);
-  emsg->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO);
-  emsg->header.size = htons (sizeof (*emsg) + name_size);
-
-  GNUNET_CRYPTO_ecdsa_key_get_public (&ego->key, &emsg->ego_pub_key);
-  GNUNET_memcpy (&emsg[1], ego->name, name_size);
-
-  client_send_msg (client, &emsg->header);
-  GNUNET_free (emsg);
-}
-
-
-void
-app_notify_ego_end (struct GNUNET_SERVICE_Client *client)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%p Sending end of ego list notification to client\n",
-              client);
-
-  struct GNUNET_MessageHeader msg;
-  msg.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END);
-  msg.size = htons (sizeof (msg));
-
-  client_send_msg (client, &msg);
-}
-
-
-int
-app_place_entry_notify (void *cls, const struct GNUNET_HashCode *key, void 
*value)
-{
-  struct GNUNET_MessageHeader *
-    msg = GNUNET_CONTAINER_multihashmap_get (places, key);
-  if (NULL != msg)
-    app_notify_place (msg, cls);
-  return GNUNET_YES;
-}
-
-
-int
-ego_entry (void *cls, const struct GNUNET_HashCode *key, void *value)
-{
-  app_notify_ego (value, cls);
-  return GNUNET_YES;
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -2154,13 +2196,15 @@ handle_client_app_detach (void *cls,
 }
 
 
-int
-app_places_entry_remove (void *cls, const struct GNUNET_HashCode *key, void 
*value)
+static void
+place_leave_cb (void *cls)
 {
   struct Place *plc = cls;
-  const char *app_id = value;
-  app_place_remove (app_id, &plc->ego_pub_key, &plc->pub_key);
-  return GNUNET_YES;
+
+  place_send_leave_ack (plc);
+  (GNUNET_YES == plc->is_host)
+    ? cleanup_host ((struct Host *) plc)
+    : cleanup_guest ((struct Guest *) plc);
 }
 
 
@@ -2174,6 +2218,11 @@ handle_client_place_leave (void *cls,
   struct Client *c = 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);
@@ -2181,40 +2230,28 @@ handle_client_place_leave (void *cls,
     return;
   }
 
-  /* FIXME: remove all app subscriptions and leave this place  */
-
-  struct GNUNET_CONTAINER_MultiHashMap *
-    place_apps = GNUNET_CONTAINER_multihashmap_get (places_apps, 
&plc->pub_key_hash);
-  if (NULL != place_apps)
+  if (GNUNET_YES != plc->is_disconnecting)
   {
-    GNUNET_CONTAINER_multihashmap_iterate (place_apps, 
app_places_entry_remove, plc);
-  }
-
-  /* FIXME: disconnect from the network, but keep local connection for history 
access */
-
-  /* Disconnect all clients connected to the place */
-  struct ClientListItem *cli = plc->clients_head, *next;
-  while (NULL != cli)
-  {
-    GNUNET_CONTAINER_DLL_remove (plc->clients_head, plc->clients_tail, cli);
-    GNUNET_SERVICE_client_drop (cli->client);
-    next = cli->next;
-    GNUNET_free (cli);
-    cli = next;
-  }
-
-  if (GNUNET_YES != plc->is_disconnected)
-  {
-    plc->is_disconnected = GNUNET_YES;
-    if (NULL != plc->tmit_msgs_head)
-    { /* Send pending messages to PSYC before cleanup. */
-      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
     {
-      cleanup_place (plc);
+      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);
 }
 
 
@@ -2273,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);
@@ -2302,10 +2342,11 @@ handle_client_join_decision (void *cls,
 static void
 send_message_ack (struct Place *plc, struct GNUNET_SERVICE_Client *client)
 {
-  struct GNUNET_MessageHeader res;
-  res.size = htons (sizeof (res));
-  res.type = htons (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK);
-  client_send_msg (client, &res);
+  struct GNUNET_MQ_Envelope *env;
+
+  env = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
 }
 
 
@@ -2437,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;
@@ -2479,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;
 }
@@ -2597,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);
   }
@@ -2862,26 +2897,26 @@ psyc_transmit_queue_message (struct Place *plc,
 }
 
 
-/**
- * Cancel transmission of current message to PSYC.
- *
- * @param plc    Place to send to.
- * @param client  Client the message originates from.
- */
-static void
-psyc_transmit_cancel (struct Place *plc, struct GNUNET_SERVICE_Client *client)
-{
-  uint16_t type = GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL;
-
-  struct GNUNET_MessageHeader msg;
-  msg.size = htons (sizeof (msg));
-  msg.type = htons (type);
-
-  psyc_transmit_queue_message (plc, client, sizeof (msg), &msg, type, type, 
NULL);
-  psyc_transmit_message (plc);
-
-  /* FIXME: cleanup */
-}
+///**
+// * Cancel transmission of current message to PSYC.
+// *
+// * @param plc          Place to send to.
+// * @param client  Client the message originates from.
+// */
+//static void
+//psyc_transmit_cancel (struct Place *plc, struct GNUNET_SERVICE_Client 
*client)
+//{
+//  uint16_t type = GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL;
+//
+//  struct GNUNET_MessageHeader msg;
+//  msg.size = htons (sizeof (msg));
+//  msg.type = htons (type);
+//
+//  psyc_transmit_queue_message (plc, client, sizeof (msg), &msg, type, type, 
NULL);
+//  psyc_transmit_message (plc);
+//
+//  /* FIXME: cleanup */
+//}
 
 
 static int
@@ -2902,17 +2937,19 @@ handle_client_psyc_message (void *cls,
   struct Client *c = cls;
   struct GNUNET_SERVICE_Client *client = c->client;
   struct Place *plc = c->place;
+  int ret;
+
   if (NULL == plc)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "received PSYC message for non-existing client %p\n",
+                client);
     GNUNET_break (0);
     GNUNET_SERVICE_client_drop (client);
     return;
   }
-
-  int ret = GNUNET_SYSERR;
-
   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)
@@ -2933,20 +2970,19 @@ handle_client_psyc_message (void *cls,
                 "%p Received message with invalid payload size (%u) from 
client.\n",
                 plc, psize);
     GNUNET_break (0);
-    psyc_transmit_cancel (plc, client);
     GNUNET_SERVICE_client_drop (client);
     return;
   }
 
-  uint16_t first_ptype = 0, last_ptype = 0;
-  if (GNUNET_SYSERR
-      == GNUNET_PSYC_receive_check_parts (psize, (const char *) &msg[1],
-                                          &first_ptype, &last_ptype))
+  uint16_t first_ptype = 0;
+  uint16_t last_ptype = 0;
+  if (GNUNET_SYSERR ==
+      GNUNET_PSYC_receive_check_parts (psize, (const char *) &msg[1],
+                                       &first_ptype, &last_ptype))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "%p Received invalid message part from client.\n", plc);
     GNUNET_break (0);
-    psyc_transmit_cancel (plc, client);
     GNUNET_SERVICE_client_drop (client);
     return;
   }
@@ -2963,20 +2999,19 @@ handle_client_psyc_message (void *cls,
       c->tmit_msg = NULL;
     ret = psyc_transmit_message (plc);
   }
-
+  else
+  {
+    ret = GNUNET_SYSERR;
+  }
   if (GNUNET_OK != ret)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "%p Received invalid message part from client.\n", plc);
     GNUNET_break (0);
-    psyc_transmit_cancel (plc, client);
-    ret = GNUNET_SYSERR;
-  }
-
-  if (GNUNET_OK == ret)
-    GNUNET_SERVICE_client_continue (client);
-  else
     GNUNET_SERVICE_client_drop (client);
+    return;
+  }
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -3006,7 +3041,7 @@ psyc_recv_history_message (void *cls, const struct 
GNUNET_PSYC_MessageHeader *ms
   GNUNET_memcpy (&res[1], msg, size);
 
   /** @todo FIXME: send only to requesting client */
-  place_send_msg (plc, &res->header);
+  place_send_msg (plc, GNUNET_MQ_msg_copy (&res->header));
 
   GNUNET_free (res);
 }
@@ -3108,29 +3143,24 @@ psyc_recv_state_var (void *cls,
                      uint32_t value_size,
                      uint32_t full_value_size)
 {
+  struct GNUNET_OperationResultMessage *result_msg;
+  struct GNUNET_MQ_Envelope *env;
   struct OperationClosure *opcls = cls;
   struct Client *c = opcls->client;
   struct Place *plc = c->place;
+  uint16_t size = ntohs (mod->size);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%p Received state variable %s from PSYC\n",
               plc, name);
-
-  uint16_t size = ntohs (mod->size);
-
-  struct GNUNET_OperationResultMessage *
-    res = GNUNET_malloc (sizeof (*res) + size);
-  res->header.size = htons (sizeof (*res) + size);
-  res->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT);
-  res->op_id = opcls->op_id;
-  res->result_code = GNUNET_htonll (GNUNET_OK);
-
-  GNUNET_memcpy (&res[1], mod, size);
-
+  env = GNUNET_MQ_msg_extra (result_msg,
+                             size,
+                             GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT);
+  result_msg->op_id = opcls->op_id;
+  result_msg->result_code = GNUNET_htonll (GNUNET_OK);
+  GNUNET_memcpy (&result_msg[1], mod, size);
   /** @todo FIXME: send only to requesting client */
-  place_send_msg (plc, &res->header);
-
-  GNUNET_free (res);
+  place_send_msg (plc, env);
 }
 
 
@@ -3184,7 +3214,7 @@ handle_client_state_get (void *cls,
   uint16_t size = ntohs (req->header.size);
   const char *name = (const char *) &req[1];
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "%p State get #%" PRIu64 ": %s\n",
               plc, GNUNET_ntohll (req->op_id), name);
 
@@ -3382,7 +3412,7 @@ path_basename (const char *path)
   if (NULL != basename)
     basename++;
 
-  if (NULL == basename || '\0' == basename)
+  if (NULL == basename || '\0' == *basename)
     return NULL;
 
   return basename;
@@ -3468,7 +3498,10 @@ file_place_load (void *cls, const char *place_filename)
     return GNUNET_OK;
   }
 
-  app_place_add (plcls->app_id, ereq);
+  if (GNUNET_SYSERR == app_place_add (plcls->app_id, ereq))
+  {
+    GNUNET_assert (0);
+  }
   GNUNET_free (ereq);
   return GNUNET_OK;
 }
@@ -3523,6 +3556,10 @@ identity_recv_ego (void *cls, struct GNUNET_IDENTITY_Ego 
*id_ego,
   if (NULL == id_ego) // end of initial list of egos
     return;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "social service received ego %s\n",
+              name);
+
   struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub_key;
   GNUNET_IDENTITY_ego_get_public_key (id_ego, &ego_pub_key);
 
@@ -3571,6 +3608,9 @@ run (void *cls,
      const struct GNUNET_CONFIGURATION_Handle *c,
      struct GNUNET_SERVICE_Handle *svc)
 {
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "starting social service\n");
+
   cfg = c;
   service = svc;
   GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
@@ -3583,7 +3623,7 @@ run (void *cls,
   apps = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
   places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
   apps_places = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
-  places_apps = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
+  //places_apps = GNUNET_CONTAINER_multihashmap_create(1, GNUNET_NO);
 
   id = GNUNET_IDENTITY_connect (cfg, &identity_recv_ego, NULL);
   gns = GNUNET_GNS_connect (cfg);
diff --git a/src/social/gnunet-social.c b/src/social/gnunet-social.c
index de680b11c..12c5bf2e1 100644
--- a/src/social/gnunet-social.c
+++ b/src/social/gnunet-social.c
@@ -283,7 +283,7 @@ exit_fail ()
 static void
 host_left (void *cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "The host has left the place.\n");
   exit_success ();
 }
@@ -309,7 +309,7 @@ host_leave ()
 static void
 guest_left (void *cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Guest has left the place.\n");
 }
 
@@ -518,7 +518,7 @@ look_var (void *cls,
           uint32_t value_size,
           uint32_t full_value_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Received var: %s\n%.*s\n",
               name, value_size, (const char *) value);
 }
@@ -558,7 +558,7 @@ slicer_recv_method (void *cls,
                     const char *method_name)
 {
   method_received = method_name;
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Received method for message ID %" PRIu64 ":\n"
               "%s (flags: %x)\n",
               message_id, method_name, ntohl (meth->flags));
@@ -584,7 +584,7 @@ slicer_recv_modifier (void *cls,
                       uint16_t full_value_size)
 {
 #if 0
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Received modifier for message ID %" PRIu64 ":\n"
               "%c%s: %.*s (size: %u)\n",
               message_id, oper, name, value_size, (const char *) value, 
value_size);
@@ -608,7 +608,7 @@ slicer_recv_data (void *cls,
                   uint16_t data_size)
 {
 #if 0
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Received data for message ID %" PRIu64 ":\n"
               "%.*s\n",
               message_id, data_size, (const char *) data);
@@ -631,7 +631,7 @@ slicer_recv_eom (void *cls,
                 uint8_t is_cancelled)
 {
   printf(".\n");
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Received end of message ID %" PRIu64
               ", cancelled: %u\n",
               message_id, is_cancelled);
@@ -668,7 +668,7 @@ guest_recv_entry_decision (void *cls,
                            int is_admitted,
                            const struct GNUNET_PSYC_Message *entry_msg)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Guest received entry decision %d\n",
               is_admitted);
 
@@ -683,7 +683,7 @@ guest_recv_entry_decision (void *cls,
     GNUNET_PSYC_message_parse (pmsg, &method_name, env, &data, &data_size);
     GNUNET_free (pmsg);
 
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                 "%s\n%.*s\n",
                 method_name, data_size, (const char *) data);
   }
@@ -704,7 +704,7 @@ guest_recv_local_enter (void *cls, int result,
                         uint64_t max_message_id)
 {
   char *pub_str = GNUNET_CRYPTO_eddsa_public_key_to_string (pub_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Guest entered local place: %s, max_message_id: %" PRIu64 "\n",
               pub_str, max_message_id);
   GNUNET_free (pub_str);
@@ -802,7 +802,7 @@ host_answer_door (void *cls,
   char *
     nym_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Entry request: %s\n", nym_str);
   GNUNET_free (nym_str);
 
@@ -840,7 +840,7 @@ host_farewell (void *cls,
   char *
     nym_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Farewell: %s\n", nym_str);
   GNUNET_free (nym_str);
 }
@@ -856,7 +856,7 @@ host_entered (void *cls, int result,
 {
   place_pub_key = *pub_key;
   char *pub_str = GNUNET_CRYPTO_eddsa_public_key_to_string (pub_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Host entered: %s, max_message_id: %" PRIu64 "\n",
               pub_str, max_message_id);
   GNUNET_free (pub_str);
diff --git a/src/social/social_api.c b/src/social/social_api.c
index d57d16cfb..89843831b 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -183,6 +183,7 @@ struct GNUNET_SOCIAL_Place
    */
   struct GNUNET_PSYC_Slicer *slicer;
 
+  // FIXME: do we need is_disconnecing like on the psyc and multicast APIs?
   /**
    * Function called after disconnected from the service.
    */
@@ -371,6 +372,68 @@ struct ZoneAddNymHandle
 };
 
 
+/*** CLEANUP / DISCONNECT ***/
+
+
+static void
+host_cleanup (struct GNUNET_SOCIAL_Host *hst)
+{
+  if (NULL != hst->slicer)
+  {
+    GNUNET_PSYC_slicer_destroy (hst->slicer);
+    hst->slicer = NULL;
+  }
+  GNUNET_free (hst);
+}
+
+
+static void
+guest_cleanup (struct GNUNET_SOCIAL_Guest *gst)
+{
+  GNUNET_free (gst);
+}
+
+
+static void
+place_cleanup (struct GNUNET_SOCIAL_Place *plc)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "cleaning up place %p\n",
+              plc);
+  if (NULL != plc->tmit)
+  {
+    GNUNET_PSYC_transmit_destroy (plc->tmit);
+    plc->tmit = NULL;
+  }
+  if (NULL != plc->connect_env)
+  {
+    GNUNET_MQ_discard (plc->connect_env);
+    plc->connect_env = NULL;
+  }
+  if (NULL != plc->mq)
+  {
+    GNUNET_MQ_destroy (plc->mq);
+    plc->mq = NULL;
+  }
+  if (NULL != plc->disconnect_cb)
+  {
+    plc->disconnect_cb (plc->disconnect_cls);
+    plc->disconnect_cb = NULL;
+  }
+
+  (GNUNET_YES == plc->is_host)
+    ? host_cleanup ((struct GNUNET_SOCIAL_Host *) plc)
+    : guest_cleanup ((struct GNUNET_SOCIAL_Guest *) plc);
+}
+
+
+static void
+place_disconnect (struct GNUNET_SOCIAL_Place *plc)
+{
+  place_cleanup (plc);
+}
+
+
 /*** NYM ***/
 
 static struct GNUNET_SOCIAL_Nym *
@@ -428,7 +491,7 @@ host_recv_notice_place_leave_method (void *cls,
 
   struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&msg->slave_pub_key);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Host received method for message ID %" PRIu64 " from nym %s: 
%s\n",
               message_id, GNUNET_h2s (&nym->pub_key_hash), method_name);
 
@@ -436,7 +499,7 @@ host_recv_notice_place_leave_method (void *cls,
   hst->notice_place_leave_env = GNUNET_PSYC_env_create ();
 
   char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string 
(&hst->notice_place_leave_nym->pub_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "_notice_place_leave: got method from nym %s (%s).\n",
               GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str);
   GNUNET_free (str);
@@ -458,7 +521,7 @@ host_recv_notice_place_leave_modifier (void *cls,
   if (NULL == hst->notice_place_leave_env)
     return;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Host received modifier for _notice_place_leave message with ID 
%" PRIu64 ":\n"
               "%c%s: %.*s\n",
               message_id, oper, name, value_size, (const char *) value);
@@ -485,7 +548,7 @@ host_recv_notice_place_leave_eom (void *cls,
     return;
 
   char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string 
(&hst->notice_place_leave_nym->pub_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "_notice_place_leave: got EOM from nym %s (%s).\n",
               GNUNET_h2s (&hst->notice_place_leave_nym->pub_key_hash), str);
   GNUNET_free (str);
@@ -1015,100 +1078,24 @@ handle_app_place_end (void *cls,
 }
 
 
-/*** CLEANUP / DISCONNECT ***/
-
-
-static void
-host_cleanup (struct GNUNET_SOCIAL_Host *hst)
-{
-  if (NULL != hst->slicer)
-  {
-    GNUNET_PSYC_slicer_destroy (hst->slicer);
-    hst->slicer = NULL;
-  }
-  GNUNET_free (hst);
-}
-
-
+/**
+ * Handler for a #GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK message received
+ * from the social service.
+ *
+ * @param cls the place of type `struct GNUNET_SOCIAL_Place`
+ * @param msg the message received from the service
+ */
 static void
-guest_cleanup (struct GNUNET_SOCIAL_Guest *gst)
+handle_place_leave_ack (void *cls,
+                        const struct GNUNET_MessageHeader *msg)
 {
-  GNUNET_free (gst);
-}
-
+  struct GNUNET_SOCIAL_Place *plc = cls;
 
-static void
-place_cleanup (struct GNUNET_SOCIAL_Place *plc)
-{
-  struct GNUNET_HashCode place_pub_hash;
-  GNUNET_CRYPTO_hash (&plc->pub_key, sizeof (plc->pub_key), &place_pub_hash);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "%s place cleanup: %s\n",
-              GNUNET_YES == plc->is_host ? "host" : "guest",
-              GNUNET_h2s (&place_pub_hash));
-
-  if (NULL != plc->tmit)
-  {
-    GNUNET_PSYC_transmit_destroy (plc->tmit);
-    plc->tmit = NULL;
-  }
-  if (NULL != plc->connect_env)
-  {
-    GNUNET_MQ_discard (plc->connect_env);
-    plc->connect_env = NULL;
-  }
-  if (NULL != plc->mq)
-  {
-    GNUNET_MQ_destroy (plc->mq);
-    plc->mq = NULL;
-  }
-  if (NULL != plc->disconnect_cb)
-  {
-    plc->disconnect_cb (plc->disconnect_cls);
-    plc->disconnect_cb = NULL;
-  }
-
-  (GNUNET_YES == plc->is_host)
-    ? host_cleanup ((struct GNUNET_SOCIAL_Host *) plc)
-    : guest_cleanup ((struct GNUNET_SOCIAL_Guest *) plc);
-}
-
-
-void
-place_disconnect (struct GNUNET_SOCIAL_Place *plc,
-                  GNUNET_ContinuationCallback cb,
-                  void *cls)
-{
-  plc->disconnect_cb = cb;
-  plc->disconnect_cls = cls;
-
-  if (NULL != plc->mq)
-  {
-    struct GNUNET_MQ_Envelope *env = GNUNET_MQ_get_last_envelope (plc->mq);
-    if (NULL != env)
-    {
-      GNUNET_MQ_notify_sent (env, (GNUNET_SCHEDULER_TaskCallback) 
place_cleanup, plc);
-    }
-    else
-    {
-      place_cleanup (plc);
-    }
-  }
-  else
-  {
-    place_cleanup (plc);
-  }
-}
-
-
-void
-place_leave (struct GNUNET_SOCIAL_Place *plc)
-{
-  struct GNUNET_MessageHeader *msg;
-  struct GNUNET_MQ_Envelope *
-    env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
-
-  GNUNET_MQ_send (plc->mq, env);
+              "%s left place %p\n",
+              plc->is_host ? "host" : "guest", 
+              plc);
+  place_disconnect (plc);  
 }
 
 
@@ -1168,6 +1155,10 @@ host_connect (struct GNUNET_SOCIAL_Host *hst)
                              GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK,
                              struct HostEnterAck,
                              hst),
+    GNUNET_MQ_hd_fixed_size (place_leave_ack,
+                             GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK,
+                             struct GNUNET_MessageHeader,
+                             plc),
     GNUNET_MQ_hd_var_size (host_enter_request,
                            GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
                            struct GNUNET_PSYC_JoinRequestMessage,
@@ -1516,6 +1507,9 @@ GNUNET_SOCIAL_host_announce (struct GNUNET_SOCIAL_Host 
*hst,
                              void *notify_data_cls,
                              enum GNUNET_SOCIAL_AnnounceFlags flags)
 {
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "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))
@@ -1580,7 +1574,11 @@ GNUNET_SOCIAL_host_disconnect (struct GNUNET_SOCIAL_Host 
*hst,
                                GNUNET_ContinuationCallback disconnect_cb,
                                void *cls)
 {
-  place_disconnect (&hst->plc, disconnect_cb, cls);
+  struct GNUNET_SOCIAL_Place *plc = &hst->plc;
+
+  plc->disconnect_cb = disconnect_cb;
+  plc->disconnect_cls = cls;
+  place_disconnect (plc);
 }
 
 
@@ -1607,10 +1605,15 @@ GNUNET_SOCIAL_host_leave (struct GNUNET_SOCIAL_Host 
*hst,
                           GNUNET_ContinuationCallback disconnect_cb,
                           void *cls)
 {
+  struct GNUNET_MQ_Envelope *envelope;
+
   GNUNET_SOCIAL_host_announce (hst, "_notice_place_closing", env, NULL, NULL,
                                GNUNET_SOCIAL_ANNOUNCE_NONE);
-  place_leave (&hst->plc);
-  GNUNET_SOCIAL_host_disconnect (hst, disconnect_cb, cls);
+  hst->plc.disconnect_cb = disconnect_cb;
+  hst->plc.disconnect_cls = cls;
+  envelope = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
+  GNUNET_MQ_send (hst->plc.mq,
+                  envelope);
 }
 
 
@@ -1670,6 +1673,10 @@ guest_connect (struct GNUNET_SOCIAL_Guest *gst)
                              GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK,
                              struct GNUNET_PSYC_CountersResultMessage,
                              gst),
+    GNUNET_MQ_hd_fixed_size (place_leave_ack,
+                             GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK,
+                             struct GNUNET_MessageHeader,
+                             plc),
     GNUNET_MQ_hd_var_size (guest_enter_decision,
                            GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
                            struct GNUNET_PSYC_JoinDecisionMessage,
@@ -1896,6 +1903,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.
  *
@@ -1906,8 +1971,8 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct 
GNUNET_SOCIAL_App *app,
  *        Flags for the entry.
  * @param slicer
  *        Slicer to use for processing incoming requests from guests.
- * @param local_enter_cb
- *        Called upon connection established to the social service.
+ * @param enter_cb
+ *        Called upon re-entering is complete.
  * @param entry_decision_cb
  *        Called upon receiving entry decision.
  *
@@ -1917,11 +1982,12 @@ struct GNUNET_SOCIAL_Guest *
 GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection 
*gconn,
                                      enum GNUNET_PSYC_SlaveJoinFlags flags,
                                      struct GNUNET_PSYC_Slicer *slicer,
-                                     GNUNET_SOCIAL_GuestEnterCallback 
local_enter_cb,
+                                     GNUNET_SOCIAL_GuestEnterCallback enter_cb,
                                      void *cls)
 {
   struct GNUNET_SOCIAL_Guest *gst = GNUNET_malloc (sizeof (*gst));
   struct GNUNET_SOCIAL_Place *plc = &gst->plc;
+  struct ReconnectContext *reconnect_ctx;
 
   uint16_t app_id_size = strlen (gconn->app->id) + 1;
   struct GuestEnterRequest *greq;
@@ -1940,10 +2006,15 @@ GNUNET_SOCIAL_guest_enter_reconnect (struct 
GNUNET_SOCIAL_GuestConnection *gconn
   plc->pub_key = gconn->plc_msg.place_pub_key;
   plc->ego_pub_key = gconn->plc_msg.ego_pub_key;
 
-  plc->op = GNUNET_OP_create ();
+  reconnect_ctx = GNUNET_new (struct ReconnectContext);
+  reconnect_ctx->guest = gst;
+  reconnect_ctx->enter_cb = enter_cb;
+  reconnect_ctx->enter_cls = cls;
 
-  gst->enter_cb = local_enter_cb;
-  gst->cb_cls = cls;
+  plc->op = GNUNET_OP_create ();
+  gst->enter_cb = &guest_enter_reconnect_cb;
+  gst->entry_dcsn_cb = &guest_entry_dcsn_reconnect_cb;
+  gst->cb_cls = reconnect_ctx;
 
   guest_connect (gst);
   return gst;
@@ -2028,7 +2099,11 @@ GNUNET_SOCIAL_guest_disconnect (struct 
GNUNET_SOCIAL_Guest *gst,
                                 GNUNET_ContinuationCallback disconnect_cb,
                                 void *cls)
 {
-  place_disconnect (&gst->plc, disconnect_cb, cls);
+  struct GNUNET_SOCIAL_Place *plc = &gst->plc;
+
+  plc->disconnect_cb = disconnect_cb;
+  plc->disconnect_cls = cls;
+  place_disconnect (plc);
 }
 
 
@@ -2054,10 +2129,15 @@ GNUNET_SOCIAL_guest_leave (struct GNUNET_SOCIAL_Guest 
*gst,
                            GNUNET_ContinuationCallback disconnect_cb,
                            void *cls)
 {
+  struct GNUNET_MQ_Envelope *envelope;
+
   GNUNET_SOCIAL_guest_talk (gst, "_notice_place_leave", env, NULL, NULL,
                             GNUNET_SOCIAL_TALK_NONE);
-  place_leave (&gst->plc);
-  GNUNET_SOCIAL_guest_disconnect (gst, disconnect_cb, cls);
+  gst->plc.disconnect_cb = disconnect_cb;
+  gst->plc.disconnect_cls = cls;
+  envelope = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE);
+  GNUNET_MQ_send (gst->plc.mq,
+                  envelope);
 }
 
 
diff --git a/src/social/test_social.c b/src/social/test_social.c
index 64ef10125..4d95cf005 100644
--- a/src/social/test_social.c
+++ b/src/social/test_social.c
@@ -129,22 +129,22 @@ enum
   TEST_HOST_ANSWER_DOOR_REFUSE      =  4,
   TEST_GUEST_RECV_ENTRY_DCSN_REFUSE =  5,
   TEST_HOST_ANSWER_DOOR_ADMIT       =  6,
-  TEST_GUEST_RECV_ENTRY_DCSN_ADMIT  =  9,
-  TEST_HOST_ANNOUNCE                       = 10,
-  TEST_HOST_ANNOUNCE_END            = 11,
-  TEST_GUEST_TALK                   = 12,
-  TEST_HOST_ANNOUNCE2                      = 13,
-  TEST_HOST_ANNOUNCE2_END           = 14,
-  TEST_GUEST_HISTORY_REPLAY         = 15,
-  TEST_GUEST_HISTORY_REPLAY_LATEST  = 16,
-  TEST_GUEST_LOOK_AT                = 17,
-  TEST_GUEST_LOOK_FOR               = 18,
-  TEST_GUEST_LEAVE                  = 18,
-  TEST_ZONE_ADD_PLACE               = 20,
-  TEST_GUEST_ENTER_BY_NAME          = 21,
-  TEST_RECONNECT                    = 22,
-  TEST_GUEST_LEAVE2                 = 23,
-  TEST_HOST_LEAVE                   = 24,
+  TEST_GUEST_RECV_ENTRY_DCSN_ADMIT  =  7,
+  TEST_HOST_ANNOUNCE                       =  8,
+  TEST_HOST_ANNOUNCE_END            =  9,
+  TEST_GUEST_TALK                   = 10,
+  TEST_HOST_ANNOUNCE2                      = 11,
+  TEST_HOST_ANNOUNCE2_END           = 12,
+  TEST_GUEST_HISTORY_REPLAY         = 13,
+  TEST_GUEST_HISTORY_REPLAY_LATEST  = 14,
+  TEST_GUEST_LOOK_AT                = 15,
+  TEST_GUEST_LOOK_FOR               = 16,
+  TEST_GUEST_LEAVE                  = 17,
+  TEST_ZONE_ADD_PLACE               = 18,
+  TEST_GUEST_ENTER_BY_NAME          = 19,
+  TEST_RECONNECT                    = 20,
+  TEST_GUEST_LEAVE2                 = 21,
+  TEST_HOST_LEAVE                   = 22,
 } test;
 
 
@@ -180,10 +180,28 @@ host_announce2 ();
 
 
 /**
- * Clean up all resources used.
+ * Terminate the test case (failure).
+ *
+ * @param cls NULL
+ */
+static void
+end_badly (void *cls)
+{
+  end_badly_task = NULL;
+  GNUNET_SCHEDULER_shutdown ();
+  res = 2;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Test FAILED.\n");
+}
+
+
+/**
+ * Terminate the test case (failure).
+ *
+ * @param cls NULL
  */
 static void
-cleanup ()
+end_shutdown (void *cls)
 {
   if (NULL != id)
   {
@@ -202,7 +220,11 @@ cleanup ()
     GNUNET_PSYC_slicer_destroy (host_slicer);
     host_slicer = NULL;
   }
-
+  if (NULL != end_badly_task)
+  {
+    GNUNET_SCHEDULER_cancel (end_badly_task);
+    end_badly_task = NULL;
+  }
   if (NULL != gst)
   {
     GNUNET_SOCIAL_guest_leave (gst, NULL, NULL, NULL);
@@ -216,21 +238,6 @@ cleanup ()
     hst_plc = NULL;
   }
   GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
-  GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/**
- * Terminate the test case (failure).
- *
- * @param cls NULL
- */
-static void
-end_badly (void *cls)
-{
-  res = 1;
-  cleanup ();
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
 }
 
 
@@ -242,9 +249,9 @@ end_badly (void *cls)
 static void
 end_normally (void *cls)
 {
+  GNUNET_SCHEDULER_shutdown ();
   res = 0;
-  cleanup ();
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Test PASSED.\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Test PASSED.\n");
 }
 
 
@@ -254,7 +261,7 @@ end_normally (void *cls)
 static void
 end ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Ending tests.\n", test);
 
   if (end_badly_task != NULL)
@@ -271,7 +278,7 @@ transmit_resume (void *cls)
 {
   struct TransmitClosure *tmit = cls;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
              "Test #%u: Transmission resumed.\n", test);
   if (NULL != tmit->host_ann)
     GNUNET_SOCIAL_host_announce_resume (tmit->host_ann);
@@ -296,7 +303,7 @@ notify_data (void *cls, uint16_t *data_size, void *data)
   }
 
   uint16_t size = strlen (tmit->data[tmit->n]);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Transmit notify data: %u bytes available, "
               "processing fragment %u/%u (size %u).\n",
               test, *data_size, tmit->n + 1, tmit->data_count, size);
@@ -309,7 +316,7 @@ notify_data (void *cls, uint16_t *data_size, void *data)
 
   if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                 "Test #%u: Transmission paused.\n", test);
     tmit->paused = GNUNET_YES;
     GNUNET_SCHEDULER_add_delayed (
@@ -331,7 +338,7 @@ notify_data (void *cls, uint16_t *data_size, void *data)
 static void
 host_left ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: The host has left the place.\n", test);
   end ();
 }
@@ -352,7 +359,7 @@ host_farewell2 (void *cls,
                const struct GNUNET_SOCIAL_Nym *nym,
                struct GNUNET_PSYC_Environment *env)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Nym left the place again.\n");
   GNUNET_SCHEDULER_add_now (&schedule_host_leave, NULL);
 }
@@ -365,13 +372,14 @@ host_reconnected (void *cls, int result,
 {
   place_pub_key = *home_pub_key;
   GNUNET_CRYPTO_hash (&place_pub_key, sizeof (place_pub_key), &place_pub_hash);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host reconnected to place %s\n",
               test, GNUNET_h2s (&place_pub_hash));
 
   is_host_reconnected = GNUNET_YES;
   if (GNUNET_YES == is_guest_reconnected)
   {
+    GNUNET_assert (NULL != gst);
     GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
   }
 }
@@ -382,7 +390,7 @@ guest_reconnected (void *cls, int result,
                    const struct GNUNET_CRYPTO_EddsaPublicKey *place_pub_key,
                    uint64_t max_message_id)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest reconnected to place: %d\n",
               test, result);
   GNUNET_assert (0 <= result);
@@ -390,6 +398,7 @@ guest_reconnected (void *cls, int result,
   is_guest_reconnected = GNUNET_YES;
   if (GNUNET_YES == is_host_reconnected)
   {
+    GNUNET_assert (NULL != gst);
     GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
   }
 }
@@ -398,7 +407,7 @@ guest_reconnected (void *cls, int result,
 static void
 app_connected (void *cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: App connected: %p\n", test, cls);
 }
 
@@ -411,21 +420,28 @@ app_recv_host (void *cls,
                enum GNUNET_SOCIAL_AppPlaceState place_state)
 {
   struct GNUNET_HashCode host_pub_hash;
-  GNUNET_CRYPTO_hash (host_pub_key, sizeof (*host_pub_key), &host_pub_hash);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_CRYPTO_hash (host_pub_key,
+                      sizeof (*host_pub_key),
+                      &host_pub_hash);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Got app host place notification: %s\n",
-              test, GNUNET_h2s (&host_pub_hash));
+              test,
+              GNUNET_h2s (&host_pub_hash));
 
   if (test == TEST_RECONNECT)
   {
     if (0 == memcmp (&place_pub_key, host_pub_key, sizeof (*host_pub_key)))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                   "Test #%u: Reconnecting to host place: %s\n",
                   test, GNUNET_h2s (&host_pub_hash));
-      hst = GNUNET_SOCIAL_host_enter_reconnect (hconn, host_slicer, 
host_reconnected,
-                                                host_answer_door, 
host_farewell2, NULL);
+      hst = GNUNET_SOCIAL_host_enter_reconnect (hconn, host_slicer,
+                                                &host_reconnected,
+                                                &host_answer_door,
+                                                &host_farewell2,
+                                                NULL);
     }
   }
 }
@@ -439,21 +455,30 @@ app_recv_guest (void *cls,
                 enum GNUNET_SOCIAL_AppPlaceState place_state)
 {
   struct GNUNET_HashCode guest_pub_hash;
-  GNUNET_CRYPTO_hash (guest_pub_key, sizeof (*guest_pub_key), &guest_pub_hash);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_CRYPTO_hash (guest_pub_key,
+                      sizeof (*guest_pub_key),
+                      &guest_pub_hash);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Got app guest place notification: %s\n",
               test, GNUNET_h2s (&guest_pub_hash));
 
   if (test == TEST_RECONNECT)
   {
-    if (0 == memcmp (&place_pub_key, guest_pub_key, sizeof (*guest_pub_key)))
+    if (0 == memcmp (&place_pub_key,
+                     guest_pub_key,
+                     sizeof (*guest_pub_key)))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                   "Test #%u: Reconnecting to guest place: %s\n",
                   test, GNUNET_h2s (&guest_pub_hash));
-      gst = GNUNET_SOCIAL_guest_enter_reconnect (gconn, 
GNUNET_PSYC_SLAVE_JOIN_NONE,
-                                                 guest_slicer, 
guest_reconnected, NULL);
+      gst = GNUNET_SOCIAL_guest_enter_reconnect (gconn,
+                                                 GNUNET_PSYC_SLAVE_JOIN_NONE,
+                                                 guest_slicer,
+                                                 &guest_reconnected,
+                                                 NULL);
+      GNUNET_assert (NULL != gst);
     }
   }
 }
@@ -478,7 +503,7 @@ app_recv_ego (void *cls,
               const char *name)
 {
   char *ego_pub_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (ego_pub_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Got app ego notification: %p %s %s\n",
               test, ego, name, ego_pub_str);
   GNUNET_free (ego_pub_str);
@@ -487,15 +512,30 @@ app_recv_ego (void *cls,
   {
     host_ego = ego;
     host_pub_key = ego_pub_key;
-    GNUNET_assert (TEST_IDENTITIES_CREATE == test);
-    enter_if_ready ();
+    if (TEST_IDENTITIES_CREATE == test)
+    {
+      enter_if_ready ();
+    }
+    else
+    {
+      GNUNET_assert (TEST_RECONNECT == test);
+    }
   }
   else if (NULL != strstr (name, guest_name))
   {
     guest_ego = ego;
     guest_pub_key = ego_pub_key;
-    GNUNET_assert (TEST_IDENTITIES_CREATE == test);
-    enter_if_ready ();
+    if (TEST_IDENTITIES_CREATE == test)
+    {
+      enter_if_ready ();
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+                  "test = %d\n",
+                  test);
+      GNUNET_assert (TEST_RECONNECT == test);
+    }
   }
 }
 
@@ -504,7 +544,6 @@ static void
 schedule_reconnect (void *cls)
 {
   test = TEST_RECONNECT;
-
   GNUNET_SOCIAL_host_disconnect (hst, NULL, NULL);
   GNUNET_SOCIAL_guest_disconnect (gst, NULL, NULL);
   hst = NULL;
@@ -512,10 +551,10 @@ schedule_reconnect (void *cls)
 
   GNUNET_SOCIAL_app_disconnect (app, NULL, NULL);
   app = GNUNET_SOCIAL_app_connect (cfg, app_id,
-                                   app_recv_ego,
-                                   app_recv_host,
-                                   app_recv_guest,
-                                   app_connected,
+                                   &app_recv_ego,
+                                   &app_recv_host,
+                                   &app_recv_guest,
+                                   &app_connected,
                                    NULL);
 }
 
@@ -524,7 +563,7 @@ static void
 host_recv_zone_add_place_result (void *cls, int64_t result,
                                  const void *data, uint16_t data_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Zone add place result: %" PRId64 " (%.*s).\n",
               test, result, data_size, (const char *) data);
   GNUNET_assert (GNUNET_YES == result);
@@ -538,7 +577,7 @@ static void
 zone_add_place ()
 {
   test = TEST_ZONE_ADD_PLACE;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Adding place to zone.\n", test);
 
   GNUNET_SOCIAL_zone_add_place (app, host_ego, "home", "let.me*in!",
@@ -557,7 +596,7 @@ host_farewell (void *cls,
     nym_key = GNUNET_SOCIAL_nym_get_pub_key (nym);
 
   char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (nym_key);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Farewell: nym %s (%s) has left the place.\n",
               test, GNUNET_h2s (GNUNET_SOCIAL_nym_get_pub_key_hash (nym)), 
str);
   GNUNET_free (str);
@@ -578,13 +617,13 @@ host_farewell (void *cls,
 static void
 guest_left (void *cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: The guest has left the place.\n", test);
 }
 
 
 static void
-guest_leave()
+guest_leave ()
 {
   if (test < TEST_RECONNECT)
     test = TEST_GUEST_LEAVE;
@@ -615,11 +654,11 @@ guest_look_for_result (void *cls,
                       uint16_t data_size)
 {
   struct ResultClosure *rcls = cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: guest_look_for_result: %" PRId64 "\n",
               test, result_code);
   GNUNET_assert (GNUNET_OK == result_code);
-  GNUNET_assert (3 == rcls->n);
+  GNUNET_assert (6 == rcls->n);
   GNUNET_free (rcls);
   GNUNET_SCHEDULER_add_now (&schedule_guest_leave, NULL);
 }
@@ -635,7 +674,7 @@ guest_look_for_var (void *cls,
 {
   struct ResultClosure *rcls = cls;
   rcls->n++;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: guest_look_for_var: %s\n%.*s\n",
               test, name, value_size, (const char *) value);
 }
@@ -656,7 +695,7 @@ guest_look_at_result (void *cls, int64_t result_code,
 {
   struct ResultClosure *rcls = cls;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: guest_look_at_result: %" PRId64 "\n",
               test, result_code);
   GNUNET_assert (GNUNET_OK == result_code);
@@ -677,7 +716,7 @@ guest_look_at_var (void *cls,
   struct ResultClosure *rcls = cls;
   rcls->n++;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: guest_look_at_var: %s\n%.*s\n",
               test ,name, value_size, (const char *) value);
 }
@@ -696,7 +735,7 @@ static void
 guest_recv_history_replay_latest_result (void *cls, int64_t result,
                                          const void *data, uint16_t data_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received latest history replay result "
               "(%" PRIu32 " messages, %" PRId64 " fragments):\n"
               "%.*s\n",
@@ -725,7 +764,7 @@ static void
 guest_recv_history_replay_result (void *cls, int64_t result,
                                   const void *data, uint16_t data_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received history replay result: %" PRId64 "\n"
               "%.*s\n",
               test, result, data_size, (const char *) data);
@@ -756,7 +795,7 @@ guest_recv_method (void *cls,
                    uint64_t message_id,
                    const char *method_name)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received method for message ID %" PRIu64 ":\n"
               "%s (flags: %x)\n",
               test, message_id, method_name, ntohl (meth->flags));
@@ -775,7 +814,7 @@ guest_recv_modifier (void *cls,
                      uint16_t value_size,
                      uint16_t full_value_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received modifier for message ID %" PRIu64 ":\n"
               "%c%s: %.*s (size: %u)\n",
               test, message_id, oper, name, value_size, (const char *) value, 
value_size);
@@ -793,7 +832,7 @@ guest_recv_mod_foo_bar (void *cls,
                         uint16_t value_size,
                         uint16_t full_value_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received modifier matching _foo_bar for message 
ID %" PRIu64 ":\n"
               "%c%s: %.*s (size: %u)\n",
               test, message_id, oper, name, value_size, (const char *) value, 
value_size);
@@ -811,7 +850,7 @@ guest_recv_data (void *cls,
                  const void *data,
                  uint16_t data_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received data for message ID %" PRIu64 ":\n"
               "%.*s\n",
               test, message_id, data_size, (const char *) data);
@@ -826,7 +865,7 @@ guest_recv_eom (void *cls,
                 uint64_t message_id,
                 uint8_t is_cancelled)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received end of message ID %" PRIu64
               ", cancelled: %u\n",
               test, message_id, is_cancelled);
@@ -868,7 +907,7 @@ host_recv_method (void *cls,
                   uint64_t message_id,
                   const char *method_name)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host received method for message ID %" PRIu64 ":\n"
               "%s\n",
               test, message_id, method_name);
@@ -887,7 +926,7 @@ host_recv_modifier (void *cls,
                     uint16_t value_size,
                     uint16_t full_value_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host received modifier for message ID %" PRIu64 ":\n"
               "%c%s: %.*s\n",
               test, message_id, oper, name, value_size, (const char *) value);
@@ -902,7 +941,7 @@ host_recv_data (void *cls,
                 const void *data,
                 uint16_t data_size)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host received data for message ID %" PRIu64 ":\n"
               "%.*s\n",
               test, message_id, data_size, (const char *) data);
@@ -916,7 +955,7 @@ host_recv_eom (void *cls,
                uint64_t message_id,
                uint8_t is_cancelled)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host received end of message ID %" PRIu64
               ", cancelled: %u\n",
               test, message_id, is_cancelled);
@@ -981,7 +1020,7 @@ host_announce ()
 {
   test = TEST_HOST_ANNOUNCE;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host announcement.\n", test);
 
   tmit = (struct TransmitClosure) {};
@@ -1015,7 +1054,7 @@ host_announce2 ()
 
   test = TEST_HOST_ANNOUNCE2;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host announcement 2.\n", test);
 
   tmit = (struct TransmitClosure) {};
@@ -1025,7 +1064,7 @@ host_announce2 ()
   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
                        "_foo2_bar", DATA2ARG ("FOO BAR"));
   GNUNET_PSYC_env_add (tmit.env, GNUNET_PSYC_OP_ASSIGN,
-                       "_foo2_bar", DATA2ARG ("FOO BAR BAZ"));
+                       "_foo2_bar_baz", DATA2ARG ("FOO BAR BAZ"));
   tmit.data[0] = "AAA BBB CCC ";
   tmit.data[1] = "ABC DEF GHI JKL.\n";
   tmit.data[2] = "TESTING ONE TWO THREE.\n";
@@ -1043,7 +1082,7 @@ guest_recv_entry_decision (void *cls,
                            int is_admitted,
                            const struct GNUNET_PSYC_Message *entry_msg)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Guest received entry decision (try %u): %d.\n",
               test, join_req_count, is_admitted);
 
@@ -1068,7 +1107,8 @@ guest_recv_entry_decision (void *cls,
   {
   case TEST_GUEST_RECV_ENTRY_DCSN_REFUSE:
     GNUNET_assert (GNUNET_NO == is_admitted);
-    guest_enter ();
+    test = TEST_HOST_ANSWER_DOOR_ADMIT;
+    GNUNET_SOCIAL_guest_disconnect (gst, &guest_enter, NULL);
     break;
 
   case TEST_GUEST_RECV_ENTRY_DCSN_ADMIT:
@@ -1097,7 +1137,7 @@ host_answer_door (void *cls,
 {
   join_req_count++;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
               "Test #%u: Host received entry request from guest (try %u).\n",
               (uint8_t) test, join_req_count);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1118,7 +1158,7 @@ host_answer_door (void *cls,
     // fall through
 
   case TEST_GUEST_ENTER_BY_NAME:
-    join_resp = GNUNET_PSYC_message_create ("_notice_place_admit", env,
+   join_resp = GNUNET_PSYC_message_create ("_notice_place_admit", env,
                                             DATA2ARG ("Welcome, nym!"));
     GNUNET_SOCIAL_host_entry_decision (hst, nym, GNUNET_YES, join_resp);
     break;
@@ -1135,18 +1175,18 @@ guest_recv_local_enter (void *cls, int result,
                         const struct GNUNET_CRYPTO_EddsaPublicKey 
*place_pub_key,
                         uint64_t max_message_id)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "Test #%u: Guest entered to local place: %d\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Test #%u: Guest entered local place: %d\n",
               test, result);
-  GNUNET_assert (0 <= result);
+  GNUNET_assert (GNUNET_OK == result);
 }
 
 
 static void
 guest_enter ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "Test #%u: Entering to place as guest.\n", test);
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Test #%u: Entering place as guest.\n", test);
 
   struct GuestEnterMessage *emsg = &guest_enter_msg;
 
@@ -1177,8 +1217,8 @@ static void
 guest_enter_by_name ()
 {
   test = TEST_GUEST_ENTER_BY_NAME;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Test #%u: Entering to place by name as guest.\n", test);
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Test #%u: Entering place by name as guest.\n", test);
 
   struct GuestEnterMessage *emsg = &guest_enter_msg;
 
@@ -1222,7 +1262,7 @@ guest_init ()
                                  guest_recv_data, guest_recv_eom, NULL);
   GNUNET_PSYC_slicer_modifier_add (guest_slicer, "_foo_bar",
                                    guest_recv_mod_foo_bar, &mod_foo_bar_rcls);
-  test = TEST_HOST_ANSWER_DOOR_ADMIT;
+  test = TEST_HOST_ANSWER_DOOR_REFUSE;
 
   GNUNET_SOCIAL_zone_add_nym (app, guest_ego, "host", host_pub_key,
                               GNUNET_TIME_relative_to_absolute 
(GNUNET_TIME_UNIT_MINUTES),
@@ -1270,8 +1310,8 @@ host_entered (void *cls, int result,
 {
   place_pub_key = *home_pub_key;
   GNUNET_CRYPTO_hash (&place_pub_key, sizeof (place_pub_key), &place_pub_hash);
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "Test #%u: Host entered to place %s\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Test #%u: Host entered place %s\n",
               test, GNUNET_h2s (&place_pub_hash));
   guest_enter ();
 }
@@ -1285,8 +1325,8 @@ host_enter ()
                                  host_recv_method, host_recv_modifier,
                                  host_recv_data, host_recv_eom, NULL);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-              "Test #%u: Entering to place as host.\n", test);
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "Test #%u: Entering place as host.\n", test);
   test = TEST_HOST_ENTER;
   hst = GNUNET_SOCIAL_host_enter (app, host_ego,
                                   GNUNET_PSYC_CHANNEL_PRIVATE,
@@ -1306,6 +1346,8 @@ start_app_if_ready ()
   {
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+              "starting app...\n");
   app = GNUNET_SOCIAL_app_connect (cfg,
                                    app_id,
                                    app_recv_ego,
@@ -1324,17 +1366,17 @@ identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego 
*ego,
   {
     if (ego == identity_host_ego)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                   "Host ego deleted\n");
     }
     else if (ego == identity_guest_ego)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                   "Guest ego deleted\n");
     }
     else if (0 == strcmp (name, host_name))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                   "Created ego %s\n",
                   name);
       identity_host_ego = ego;
@@ -1342,7 +1384,7 @@ identity_ego_cb (void *cls, struct GNUNET_IDENTITY_Ego 
*ego,
     }
     else if (0 == strcmp (name, guest_name))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+      GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                   "Created guest ego %s\n",
                   name);
       identity_guest_ego = ego;
@@ -1370,9 +1412,11 @@ run (void *cls,
 #endif
 {
   cfg = c;
+  res = 1;
   end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
                                                 &end_badly, NULL);
-
+  GNUNET_SCHEDULER_add_shutdown (&end_shutdown,
+                                 NULL);
   GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
 
   id = GNUNET_IDENTITY_connect (cfg, &identity_ego_cb, NULL);
diff --git a/src/social/test_social.conf b/src/social/test_social.conf
index e69de29bb..7cf858b1c 100644
--- a/src/social/test_social.conf
+++ b/src/social/test_social.conf
@@ -0,0 +1,19 @@
address@hidden@ ../../contrib/no_forcestart.conf
+
+[PATHS]
+GNUNET_TEST_HOME = /tmp/gnunet-test-social/
+
+[social]
+FORCESTART = YES
+
+[transport]
+PLUGINS = tcp
+
+[nat]
+DISABLEV6 = YES
+ENABLE_UPNP = NO
+BEHIND_NAT = NO
+ALLOW_NAT = NO
+INTERNAL_ADDRESS = 127.0.0.1
+EXTERNAL_ADDRESS = 127.0.0.1
+
diff --git a/src/statistics/gnunet-service-statistics.c 
b/src/statistics/gnunet-service-statistics.c
index 0cb136b99..87e966a01 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -998,7 +998,9 @@ client_disconnect_cb (void *cls,
  *
  * @param cls NULL
  * @param message the message found on disk
- * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 inject_message (void *cls,
diff --git a/src/testbed/gnunet-helper-testbed.c 
b/src/testbed/gnunet-helper-testbed.c
index 392f257dd..9601e7567 100644
--- a/src/testbed/gnunet-helper-testbed.c
+++ b/src/testbed/gnunet-helper-testbed.c
@@ -292,8 +292,9 @@ child_death_task (void *cls)
  *
  * @param cls identification of the client
  * @param message the actual message
- *
- * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 tokenizer_cb (void *cls,
@@ -359,7 +360,7 @@ tokenizer_cb (void *cls,
   cfg = GNUNET_CONFIGURATION_create ();
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_deserialize (cfg,
-                                       config, 
+                                       config,
                                        ul_config_size,
                                        NULL))
   {
diff --git a/src/transport/gnunet-helper-transport-wlan-dummy.c 
b/src/transport/gnunet-helper-transport-wlan-dummy.c
index 63ed9c4b7..f02d8bdd7 100644
--- a/src/transport/gnunet-helper-transport-wlan-dummy.c
+++ b/src/transport/gnunet-helper-transport-wlan-dummy.c
@@ -121,6 +121,9 @@ send_mac_to_plugin (char *buffer, struct 
GNUNET_TRANSPORT_WLAN_MacAddress *mac)
  *
  * @param cls the 'struct SendBuffer' to copy the converted message to
  * @param hdr inbound message from the FIFO
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 stdin_send (void *cls,
@@ -167,6 +170,9 @@ stdin_send (void *cls,
  *
  * @param cls the 'struct SendBuffer' to copy to
  * @param hdr the message we received to copy to the buffer
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 file_in_send (void *cls,
diff --git a/src/transport/plugin_transport_http_server.c 
b/src/transport/plugin_transport_http_server.c
index d9fade44f..6a9c1b0ba 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -1651,7 +1651,7 @@ server_send_callback (void *cls,
  *
  * @param cls current session as closure
  * @param message the message to be forwarded to transport service
- * @return #GNUNET_OK
+ * @return #GNUNET_OK (all OK)
  */
 static int
 server_receive_mst_cb (void *cls,
diff --git a/src/util/client.c b/src/util/client.c
index 3d74bff33..e5bf7e176 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -261,14 +261,27 @@ transmit_ready (void *cls)
   pos = (const char *) cstate->msg;
   len = ntohs (cstate->msg->size);
   GNUNET_assert (cstate->msg_off < len);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "client: message of type %u trying to send with socket %p (MQ: 
%p\n",
+              ntohs(cstate->msg->type),
+              cstate->sock,
+              cstate->mq);
+
  RETRY:
   ret = GNUNET_NETWORK_socket_send (cstate->sock,
                                     &pos[cstate->msg_off],
                                     len - cstate->msg_off);
   if (-1 == ret)
   {
-    if (EINTR == errno)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "client: error during sending message of type %u\n",
+                ntohs(cstate->msg->type));
+    if (EINTR == errno){
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "client: retrying message of type %u\n",
+                  ntohs(cstate->msg->type));
       goto RETRY;
+    }
     GNUNET_MQ_inject_error (cstate->mq,
                             GNUNET_MQ_ERROR_WRITE);
     return;
@@ -277,6 +290,9 @@ transmit_ready (void *cls)
   cstate->msg_off += ret;
   if (cstate->msg_off < len)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "client: rescheduling message of type %u\n",
+                ntohs(cstate->msg->type));
     cstate->send_task
       = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
                                         cstate->sock,
@@ -286,6 +302,9 @@ transmit_ready (void *cls)
       GNUNET_MQ_impl_send_in_flight (cstate->mq);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "client: sending message of type %u successful\n",
+              ntohs(cstate->msg->type));
   cstate->msg = NULL;
   GNUNET_MQ_impl_send_continue (cstate->mq);
 }
@@ -297,7 +316,9 @@ transmit_ready (void *cls)
  *
  * @param cls the `struct ClientState`
  * @param msg message we received.
- * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success,
+ *     #GNUNET_NO to stop further processing due to disconnect (no error)
+ *     #GNUNET_SYSERR to stop further processing due to error
  */
 static int
 recv_message (void *cls,
@@ -306,7 +327,7 @@ recv_message (void *cls,
   struct ClientState *cstate = cls;
 
   if (GNUNET_YES == cstate->in_destroy)
-    return GNUNET_SYSERR;
+    return GNUNET_NO;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received message of type %u and size %u from %s\n",
        ntohs (msg->type),
@@ -315,7 +336,7 @@ recv_message (void *cls,
   GNUNET_MQ_inject_message (cstate->mq,
                             msg);
   if (GNUNET_YES == cstate->in_destroy)
-    return GNUNET_SYSERR;
+    return GNUNET_NO;
   return GNUNET_OK;
 }
 
@@ -371,8 +392,12 @@ connection_client_destroy_impl (struct GNUNET_MQ_Handle 
*mq,
     GNUNET_SCHEDULER_cancel (cstate->recv_task);
   if (NULL != cstate->retry_task)
     GNUNET_SCHEDULER_cancel (cstate->retry_task);
-  if (NULL != cstate->sock)
+  if (NULL != cstate->sock){
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "client: destroying socket: %p\n",
+                cstate->sock);
     GNUNET_NETWORK_socket_close (cstate->sock);
+  }
   cancel_aps (cstate);
   GNUNET_free (cstate->service_name);
   GNUNET_free_non_null (cstate->hostname);
@@ -794,8 +819,12 @@ connection_client_send_impl (struct GNUNET_MQ_Handle *mq,
   GNUNET_assert (NULL == cstate->send_task);
   cstate->msg = msg;
   cstate->msg_off = 0;
-  if (NULL == cstate->sock)
+  if (NULL == cstate->sock){
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "client: message of type %u waiting for socket\n",
+                ntohs(msg->type));
     return; /* still waiting for connection */
+   }
   cstate->send_task
     = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
                                       cstate->sock,
diff --git a/src/util/mq.c b/src/util/mq.c
index 90b2aa968..8d71359ac 100644
--- a/src/util/mq.c
+++ b/src/util/mq.c
@@ -357,6 +357,12 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq,
   }
   GNUNET_assert (NULL == mq->envelope_head);
   mq->current_envelope = ev;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "mq: sending message of type %u, queue empty (MQ: %p)\n",
+              ntohs(ev->mh->type),
+              mq);
+
   mq->send_impl (mq,
                 ev->mh,
                 mq->impl_state);
@@ -452,6 +458,11 @@ impl_send_continue (void *cls)
   GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
                               mq->envelope_tail,
                               mq->current_envelope);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "mq: sending message of type %u from queue\n",
+              ntohs(mq->current_envelope->mh->type));
+
   mq->send_impl (mq,
                 mq->current_envelope->mh,
                 mq->impl_state);
@@ -840,6 +851,9 @@ GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq)
                                 ev);
     GNUNET_assert (0 < mq->queue_length);
     mq->queue_length--;
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "MQ destroy drops message of type %u\n",
+                ntohs (ev->mh->type));
     GNUNET_MQ_discard (ev);
   }
   if (NULL != mq->current_envelope)
@@ -847,6 +861,9 @@ GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq)
     /* we can only discard envelopes that
      * are not queued! */
     mq->current_envelope->parent_queue = NULL;
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "MQ destroy drops current message of type %u\n",
+                ntohs (mq->current_envelope->mh->type));
     GNUNET_MQ_discard (mq->current_envelope);
     mq->current_envelope = NULL;
     GNUNET_assert (0 < mq->queue_length);
@@ -928,6 +945,11 @@ GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev)
       GNUNET_CONTAINER_DLL_remove (mq->envelope_head,
                                    mq->envelope_tail,
                                    mq->current_envelope);
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "mq: sending canceled message of type %u queue\n",
+                  ntohs(ev->mh->type));
+
       mq->send_impl (mq,
                     mq->current_envelope->mh,
                     mq->impl_state);
diff --git a/src/util/mst.c b/src/util/mst.c
index 0d90c5d10..5e472965f 100644
--- a/src/util/mst.c
+++ b/src/util/mst.c
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2010, 2016 GNUnet e.V.
+     Copyright (C) 2010, 2016, 2017 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -126,6 +126,7 @@ GNUNET_MST_from_buffer (struct 
GNUNET_MessageStreamTokenizer *mst,
   int need_align;
   unsigned long offset;
   int ret;
+  int cbret;
 
   GNUNET_assert (mst->off <= mst->pos);
   GNUNET_assert (mst->pos <= mst->curr_buf);
@@ -229,9 +230,17 @@ do_align:
     if (one_shot == GNUNET_YES)
       one_shot = GNUNET_SYSERR;
     mst->off += want;
-  if (GNUNET_SYSERR == mst->cb (mst->cb_cls,
-                                hdr))
+    if (GNUNET_OK !=
+        (cbret = mst->cb (mst->cb_cls,
+                           hdr)))
+    {
+      if (GNUNET_SYSERR == cbret)
+        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                    "Failure processing message of type %u and size %u\n",
+                    ntohs (hdr->type),
+                    ntohs (hdr->size));
       return GNUNET_SYSERR;
+    }
     if (mst->off == mst->pos)
     {
       /* reset to beginning of buffer, it's free right now! */
@@ -271,9 +280,17 @@ do_align:
       }
       if (one_shot == GNUNET_YES)
         one_shot = GNUNET_SYSERR;
-      if (GNUNET_SYSERR == mst->cb (mst->cb_cls,
-                                    hdr))
+      if (GNUNET_OK !=
+          (cbret = mst->cb (mst->cb_cls,
+                            hdr)))
+      {
+        if (GNUNET_SYSERR == cbret)
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                      "Failure processing message of type %u and size %u\n",
+                      ntohs (hdr->type),
+                      ntohs (hdr->size));
         return GNUNET_SYSERR;
+      }
       buf += want;
       size -= want;
     }
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index 540a60557..4615ecee9 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -589,9 +589,7 @@ static void
 dump_backtrace (struct GNUNET_SCHEDULER_Task *t)
 {
 #if EXECINFO
-  unsigned int i;
-
-  for (i = 0; i < t->num_backtrace_strings; i++)
+  for (unsigned int i = 0; i < t->num_backtrace_strings; i++)
     LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Task %p trace %u: %s\n",
         t,
diff --git a/src/util/service.c b/src/util/service.c
index fcdf45a51..b4eb33caa 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -1932,6 +1932,11 @@ do_send (void *cls)
   size_t left;
   const char *buf;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "service: sending message with type %u",
+       ntohs(client->msg->type));
+
+
   client->send_task = NULL;
   buf = (const char *) client->msg;
   left = ntohs (client->msg->size) - client->msg_pos;
@@ -1941,6 +1946,8 @@ do_send (void *cls)
   GNUNET_assert (ret <= (ssize_t) left);
   if (0 == ret)
   {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "no data send");
     GNUNET_MQ_inject_error (client->mq,
                            GNUNET_MQ_ERROR_WRITE);
     return;
@@ -1958,6 +1965,9 @@ do_send (void *cls)
       if (EPIPE != errno)
         GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
                              "send");
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "socket send returned with error code %i",
+           errno);
       GNUNET_MQ_inject_error (client->mq,
                              GNUNET_MQ_ERROR_WRITE);
       return;
@@ -2402,7 +2412,7 @@ resume_client_receive (void *cls)
                         GNUNET_YES);
   if (GNUNET_SYSERR == ret)
   {
-    if (NULL != c->drop_task)
+    if (NULL == c->drop_task)
       GNUNET_SERVICE_client_drop (c);
     return;
   }
@@ -2431,6 +2441,7 @@ resume_client_receive (void *cls)
 void
 GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
 {
+  GNUNET_assert (NULL == c->drop_task);
   GNUNET_assert (GNUNET_YES == c->needs_continue);
   GNUNET_assert (NULL == c->recv_task);
   c->needs_continue = GNUNET_NO;
@@ -2513,6 +2524,24 @@ GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client 
*c)
 {
   struct GNUNET_SERVICE_Handle *sh = c->sh;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Client dropped: %p (MQ: %p)\n",
+              c,
+              c->mq);
+
+#if EXECINFO
+  void *backtrace_array[MAX_TRACE_DEPTH];
+  int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
+    char **backtrace_strings =
+        backtrace_symbols (backtrace_array,
+         t->num_backtrace_strings);
+    for (unsigned int i = 0; i < num_backtrace_strings; i++)
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+     "client drop trace %u: %s\n",
+     i,
+     backtrace_strings[i]);
+#endif
+
   if (NULL != c->drop_task)
   {
     /* asked to drop twice! */
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index d9daaa7e2..bdc638176 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -2218,6 +2218,9 @@ route_packet (struct DestinationEntry *destination,
  *
  * @param cls closure, NULL
  * @param message message we got from the client (VPN channel interface)
+ * @return #GNUNET_OK on success,
+ *    #GNUNET_NO to stop further processing (no error)
+ *    #GNUNET_SYSERR to stop further processing with error
  */
 static int
 message_token (void *cls,

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



reply via email to

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