-bringing copyright tags up to FSF standard
[oweals/gnunet.git] / src / transport / gnunet-service-transport_clients.c
index 9fc167985e396967f9a1b9b116ba1b87a9493155..0aef9f97e6b457d79bb6e047e85e4649bfeed1a3 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2010-2014 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2010-2014 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -20,7 +20,7 @@
 
 /**
  * @file transport/gnunet-service-transport_clients.c
- * @brief plugin management API
+ * @brief communication with clients (core service and monitors)
  * @author Christian Grothoff
  */
 #include "platform.h"
@@ -141,7 +141,9 @@ struct AddressToStringContext
 
 
 /**
- * Client monitoring changes of active addresses of our neighbours.
+ * Client monitoring changes of active addresses or validations
+ * of our neighbours. Which type is being monitored depends on the
+ * DLL this struct is in.
  */
 struct MonitoringClient
 {
@@ -182,12 +184,12 @@ static struct TransportClient *clients_tail;
 /**
  * Head of linked list of all pending address iterations
  */
-struct AddressToStringContext *a2s_head;
+static struct AddressToStringContext *a2s_head;
 
 /**
  * Tail of linked list of all pending address iterations
  */
-struct AddressToStringContext *a2s_tail;
+static struct AddressToStringContext *a2s_tail;
 
 /**
  * Head of linked list of monitoring clients.
@@ -233,9 +235,15 @@ static struct GNUNET_SERVER_NotificationContext *plugin_nc;
  */
 static struct GNUNET_SERVER_Client *sync_client;
 
+/**
+ * Peer identity that is all zeros, used as a way to indicate
+ * "all peers".  Used for comparissons.
+ */
+static struct GNUNET_PeerIdentity all_zeros;
+
 
 /**
- * Find the internal handle associated with the given client handle
+ * Find the internal handle associated with the given client handle.
  *
  * @param client server's client handle to look up
  * @return internal client handle
@@ -243,17 +251,13 @@ static struct GNUNET_SERVER_Client *sync_client;
 static struct TransportClient *
 lookup_client (struct GNUNET_SERVER_Client *client)
 {
-  struct TransportClient *tc;
-
-  for (tc = clients_head; NULL != tc; tc = tc->next)
-    if (tc->client == client)
-      return tc;
-  return NULL;
+  return GNUNET_SERVER_client_get_user_context (client,
+                                                struct TransportClient);
 }
 
 
 /**
- * Create the internal handle for the given server client handle
+ * Create the internal handle for the given server client handle.
  *
  * @param client server's client handle to create our internal handle for
  * @return fresh internal client handle
@@ -266,6 +270,10 @@ setup_client (struct GNUNET_SERVER_Client *client)
   GNUNET_assert (NULL == lookup_client (client));
   tc = GNUNET_new (struct TransportClient);
   tc->client = client;
+  GNUNET_SERVER_client_set_user_context (client, tc);
+  GNUNET_CONTAINER_DLL_insert (clients_head,
+                               clients_tail,
+                               tc);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Client %p connected\n",
               tc);
@@ -275,7 +283,7 @@ setup_client (struct GNUNET_SERVER_Client *client)
 
 /**
  * Find the handle to the monitoring client associated with the given
- * client handle
+ * client handle.
  *
  * @param head the head of the client queue to look in
  * @param client server's client handle to look up
@@ -308,7 +316,6 @@ setup_peer_monitoring_client (struct GNUNET_SERVER_Client *client,
                               const struct GNUNET_PeerIdentity *peer)
 {
   struct MonitoringClient *mc;
-  static struct GNUNET_PeerIdentity all_zeros;
 
   GNUNET_assert (NULL ==
                  lookup_monitoring_client (peer_monitoring_clients_head,
@@ -320,15 +327,17 @@ setup_peer_monitoring_client (struct GNUNET_SERVER_Client *client,
                                peer_monitoring_clients_tail,
                                mc);
   GNUNET_SERVER_client_mark_monitor (client);
-  GNUNET_SERVER_notification_context_add (peer_nc, client);
-
-  if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_SERVER_notification_context_add (peer_nc,
+                                          client);
+  if (0 != memcmp (peer,
+                   &all_zeros,
+                   sizeof (struct GNUNET_PeerIdentity)))
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Client %p started monitoring of the peer `%s'\n",
                 mc,
                 GNUNET_i2s (peer));
   else
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Client %p started monitoring all peers\n",
                 mc);
   return mc;
@@ -349,7 +358,6 @@ setup_val_monitoring_client (struct GNUNET_SERVER_Client *client,
                              struct GNUNET_PeerIdentity *peer)
 {
   struct MonitoringClient *mc;
-  static struct GNUNET_PeerIdentity all_zeros;
 
   GNUNET_assert (NULL ==
                  lookup_monitoring_client (val_monitoring_clients_head,
@@ -365,19 +373,21 @@ setup_val_monitoring_client (struct GNUNET_SERVER_Client *client,
   if (0 != memcmp (peer,
                    &all_zeros,
                    sizeof (struct GNUNET_PeerIdentity)))
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Client %p started monitoring of the peer `%s'\n",
-                mc, GNUNET_i2s (peer));
+                mc,
+                GNUNET_i2s (peer));
   else
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Client %p started monitoring all peers\n", mc);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Client %p started monitoring all peers\n",
+                mc);
   return mc;
 }
 
 
 /**
  * Function called to notify a client about the socket being ready to
- * queue more data.  "buf" will be NULL and "size" zero if the socket
+ * queue more data.  @a buf will be NULL and @a size zero if the socket
  * was closed for writing in the meantime.
  *
  * @param cls closure
@@ -414,7 +424,8 @@ transmit_to_client_callback (void *cls,
       break;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Transmitting message of type %u to client %p.\n",
-                ntohs (msg->type), tc);
+                ntohs (msg->type),
+                tc);
     GNUNET_CONTAINER_DLL_remove (tc->message_queue_head,
                                  tc->message_queue_tail,
                                  q);
@@ -456,11 +467,11 @@ unicast (struct TransportClient *tc,
     GNUNET_break (0);
     return;
   }
-
-  if ((tc->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop))
+  if ( (tc->message_count >= MAX_PENDING) &&
+       (GNUNET_YES == may_drop) )
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Dropping message of type %u and size %u, have %u/%u messages pending\n"),
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Dropping message of type %u and size %u, have %u/%u messages pending\n",
                 ntohs (msg->type),
                 ntohs (msg->size),
                 tc->message_count,
@@ -476,7 +487,8 @@ unicast (struct TransportClient *tc,
   q = GNUNET_malloc (sizeof (struct ClientMessageQueueEntry) + msize);
   memcpy (&q[1], msg, msize);
   GNUNET_CONTAINER_DLL_insert_tail (tc->message_queue_head,
-                                    tc->message_queue_tail, q);
+                                    tc->message_queue_tail,
+                                    q);
   tc->message_count++;
   if (NULL != tc->th)
     return;
@@ -492,7 +504,7 @@ unicast (struct TransportClient *tc,
  * Called whenever a client is disconnected.  Frees our
  * resources associated with that client.
  *
- * @param cls closure
+ * @param cls closure, NULL
  * @param client identification of the client
  */
 static void
@@ -503,11 +515,11 @@ client_disconnect_notification (void *cls,
   struct MonitoringClient *mc;
   struct ClientMessageQueueEntry *mqe;
 
-  if (client == NULL)
+  if (NULL == client)
     return;
   mc = lookup_monitoring_client (peer_monitoring_clients_head,
                                  client);
-  if (mc != NULL)
+  if (NULL != mc)
   {
     GNUNET_CONTAINER_DLL_remove (peer_monitoring_clients_head,
                                  peer_monitoring_clients_tail,
@@ -516,7 +528,7 @@ client_disconnect_notification (void *cls,
   }
   mc = lookup_monitoring_client (val_monitoring_clients_head,
                                  client);
-  if (mc != NULL)
+  if (NULL != mc)
   {
     GNUNET_CONTAINER_DLL_remove (val_monitoring_clients_head,
                                  val_monitoring_clients_tail,
@@ -524,19 +536,24 @@ client_disconnect_notification (void *cls,
     GNUNET_free (mc);
   }
   tc = lookup_client (client);
-  if (tc == NULL)
+  if (NULL == tc)
     return;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-              "Client %p disconnected, cleaning up.\n", tc);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Client %p disconnected, cleaning up.\n",
+              tc);
   while (NULL != (mqe = tc->message_queue_head))
   {
-    GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_tail,
+    GNUNET_CONTAINER_DLL_remove (tc->message_queue_head,
+                                 tc->message_queue_tail,
                                  mqe);
     tc->message_count--;
     GNUNET_free (mqe);
   }
-  GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc);
-  if (tc->th != NULL)
+  GNUNET_CONTAINER_DLL_remove (clients_head,
+                               clients_tail,
+                               tc);
+  GNUNET_SERVER_client_set_user_context (client, NULL);
+  if (NULL != tc->th)
   {
     GNUNET_SERVER_notify_transmit_ready_cancel (tc->th);
     tc->th = NULL;
@@ -568,21 +585,16 @@ notify_client_about_neighbour (void *cls,
                                struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
 {
   struct TransportClient *tc = cls;
-  struct ConnectInfoMessage *cim;
-  size_t size = sizeof (struct ConnectInfoMessage);
-  char buf[size] GNUNET_ALIGN;
+  struct ConnectInfoMessage cim;
 
   if (GNUNET_NO == GST_neighbours_test_connected (peer))
     return;
-
-  GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  cim = (struct ConnectInfoMessage *) buf;
-  cim->header.size = htons (size);
-  cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
-  cim->id = *peer;
-  cim->quota_in = bandwidth_in;
-  cim->quota_out = bandwidth_out;
-  unicast (tc, &cim->header, GNUNET_NO);
+  cim.header.size = htons (sizeof (struct ConnectInfoMessage));
+  cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
+  cim.id = *peer;
+  cim.quota_in = bandwidth_in;
+  cim.quota_out = bandwidth_out;
+  unicast (tc, &cim.header, GNUNET_NO);
 }
 
 
@@ -605,15 +617,11 @@ clients_handle_start (void *cls,
   uint32_t options;
 
   tc = lookup_client (client);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Client %p sent START\n", tc);
-  if (tc != NULL)
+  if (NULL != tc)
   {
     /* got 'start' twice from the same client, not allowed */
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-                "TransportClient %p ServerClient %p sent multiple START messages\n",
-                tc, tc->client);
     GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
@@ -626,17 +634,16 @@ clients_handle_start (void *cls,
                sizeof (struct GNUNET_PeerIdentity))))
   {
     /* client thinks this is a different peer, reject */
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Rejecting control connection from peer `%s', which is not me!\n"),
-                GNUNET_i2s (&start->self));
+    GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
   }
   tc = setup_client (client);
   tc->send_payload = (0 != (2 & options));
-  unicast (tc, GST_hello_get (), GNUNET_NO);
+  unicast (tc,
+           GST_hello_get (),
+           GNUNET_NO);
   GST_neighbours_iterate (&notify_client_about_neighbour, tc);
-  GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -649,7 +656,8 @@ clients_handle_start (void *cls,
  * @param message the HELLO message
  */
 static void
-clients_handle_hello (void *cls, struct GNUNET_SERVER_Client *client,
+clients_handle_hello (void *cls,
+                      struct GNUNET_SERVER_Client *client,
                       const struct GNUNET_MessageHeader *message)
 {
   GST_validation_handle_hello (message);
@@ -684,7 +692,8 @@ struct SendTransmitContinuationContext
  * @param bytes_on_wire bytes sent on wire
  */
 static void
-handle_send_transmit_continuation (void *cls, int success,
+handle_send_transmit_continuation (void *cls,
+                                   int success,
                                    size_t bytes_payload,
                                    size_t bytes_on_wire)
 {
@@ -692,17 +701,17 @@ handle_send_transmit_continuation (void *cls, int success,
   struct SendOkMessage send_ok_msg;
 
   if (GNUNET_OK == success)
-    GST_neighbours_notify_payload_sent (&stcc->target, bytes_payload);
-
+    GST_neighbours_notify_payload_sent (&stcc->target,
+                                        bytes_payload);
   send_ok_msg.header.size = htons (sizeof (send_ok_msg));
   send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
   send_ok_msg.bytes_msg = htonl (bytes_payload);
   send_ok_msg.bytes_physical = htonl (bytes_on_wire);
   send_ok_msg.success = htonl (success);
-  send_ok_msg.latency =
-      GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_FOREVER_REL);
   send_ok_msg.peer = stcc->target;
-  GST_clients_unicast (stcc->client, &send_ok_msg.header, GNUNET_NO);
+  GST_clients_unicast (stcc->client,
+                       &send_ok_msg.header,
+                       GNUNET_NO);
   GNUNET_SERVER_client_drop (stcc->client);
   GNUNET_free (stcc);
 }
@@ -754,12 +763,6 @@ clients_handle_send (void *cls,
     return;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Received `%s' request from client with target `%4s' and first message of type %u and total size %u\n",
-              "SEND",
-              GNUNET_i2s (&obm->peer),
-              ntohs (obmm->type),
-              msize);
   if (GNUNET_NO == GST_neighbours_test_connected (&obm->peer))
   {
     /* not connected, not allowed to send; can happen due to asynchronous operations */
@@ -773,14 +776,20 @@ clients_handle_send (void *cls,
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received `%s' request from client with target `%4s' and first message of type %u and total size %u\n",
+              "SEND",
+              GNUNET_i2s (&obm->peer),
+              ntohs (obmm->type),
+              msize);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
   stcc = GNUNET_new (struct SendTransmitContinuationContext);
   stcc->target = obm->peer;
   stcc->client = client;
   GNUNET_SERVER_client_keep (client);
   GST_manipulation_send (&obm->peer, obmm, msize,
-                       GNUNET_TIME_relative_ntoh (obm->timeout),
-                       &handle_send_transmit_continuation, stcc);
+                         GNUNET_TIME_relative_ntoh (obm->timeout),
+                         &handle_send_transmit_continuation, stcc);
 }
 
 
@@ -805,9 +814,8 @@ try_connect_if_allowed (void *cls,
                 GNUNET_i2s (peer));
     return;                     /* not allowed */
   }
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              _("Blacklist allows connection attempt to peer `%s'\n"),
+              "Blacklist allows connection attempt to peer `%s'\n",
               GNUNET_i2s (peer));
 
   GST_neighbours_try_connect (peer);
@@ -826,63 +834,65 @@ clients_handle_request_connect (void *cls,
                                 struct GNUNET_SERVER_Client *client,
                                 const struct GNUNET_MessageHeader *message)
 {
-  const struct TransportRequestConnectMessage *trcm =
-      (const struct TransportRequestConnectMessage *) message;
-
-  if (GNUNET_YES == ntohl (trcm->connect))
+  const struct TransportRequestConnectMessage *trcm;
+
+  trcm = (const struct TransportRequestConnectMessage *) message;
+  GNUNET_break (0 == ntohl (trcm->reserved));
+  GNUNET_STATISTICS_update (GST_stats,
+                            gettext_noop
+                            ("# REQUEST CONNECT messages received"), 1,
+                            GNUNET_NO);
+  if (0 == memcmp (&trcm->peer,
+                   &GST_my_identity,
+                   sizeof (struct GNUNET_PeerIdentity)))
   {
-    GNUNET_STATISTICS_update (GST_stats,
-                              gettext_noop
-                              ("# REQUEST CONNECT messages received"), 1,
-                              GNUNET_NO);
-
-    if (0 == memcmp (&trcm->peer, &GST_my_identity,
-                  sizeof (struct GNUNET_PeerIdentity)))
-    {
-      GNUNET_break_op (0);
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "Received a request connect message myself `%s'\n",
-                  GNUNET_i2s (&trcm->peer));
-    }
-    else
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Received a request connect message for peer `%s'\n"),
-                  GNUNET_i2s (&trcm->peer));
-
-      (void) GST_blacklist_test_allowed (&trcm->peer, NULL, &try_connect_if_allowed,
-                                       NULL);
-    }
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
   }
-  else if (GNUNET_NO == ntohl (trcm->connect))
-  {
-    GNUNET_STATISTICS_update (GST_stats,
-                              gettext_noop
-                              ("# REQUEST DISCONNECT messages received"), 1,
-                              GNUNET_NO);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received a request connect message for peer `%s'\n",
+              GNUNET_i2s (&trcm->peer));
+  (void) GST_blacklist_test_allowed (&trcm->peer,
+                                     NULL,
+                                     &try_connect_if_allowed,
+                                     NULL);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
 
-    if (0 == memcmp (&trcm->peer, &GST_my_identity,
-                  sizeof (struct GNUNET_PeerIdentity)))
-    {
-      GNUNET_break_op (0);
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "Received a request disconnect message myself `%s'\n",
-                  GNUNET_i2s (&trcm->peer));
-    }
-    else
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Received a request disconnect message for peer `%s'\n"),
-                  GNUNET_i2s (&trcm->peer));
-      (void) GST_neighbours_force_disconnect (&trcm->peer);
-    }
-  }
-  else
+
+/**
+ * Handle request disconnect message
+ *
+ * @param cls closure (always NULL)
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+clients_handle_request_disconnect (void *cls,
+                                   struct GNUNET_SERVER_Client *client,
+                                   const struct GNUNET_MessageHeader *message)
+{
+  const struct TransportRequestDisconnectMessage *trdm;
+
+  trdm = (const struct TransportRequestDisconnectMessage *) message;
+  GNUNET_break (0 == ntohl (trdm->reserved));
+  GNUNET_STATISTICS_update (GST_stats,
+                            gettext_noop
+                            ("# REQUEST DISCONNECT messages received"), 1,
+                            GNUNET_NO);
+  if (0 == memcmp (&trdm->peer,
+                   &GST_my_identity,
+                   sizeof (struct GNUNET_PeerIdentity)))
   {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received a request disconnect message for peer `%s'\n",
+              GNUNET_i2s (&trdm->peer));
+  (void) GST_neighbours_force_disconnect (&trdm->peer);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -1070,7 +1080,10 @@ compose_address_iterate_response_message (const struct GNUNET_PeerIdentity *peer
     alen = address->address_length;
   }
   else
-    tlen = alen = 0;
+  {
+    tlen = 0;
+    alen = 0;
+  }
   size = (sizeof (struct PeerIterateResponseMessage) + alen + tlen);
   msg = GNUNET_malloc (size);
   msg->header.size = htons (size);
@@ -1116,7 +1129,10 @@ compose_validation_iterate_response_message (const struct GNUNET_PeerIdentity *p
     alen = address->address_length;
   }
   else
-    tlen = alen = 0;
+  {
+    tlen = 0;
+    alen = 0;
+  }
   size = (sizeof (struct ValidationIterateResponseMessage) + alen + tlen);
   msg = GNUNET_malloc (size);
   msg->header.size = htons (size);
@@ -1165,7 +1181,6 @@ struct IterationContext
  * Output information of validation entries to the given client.
  *
  * @param cls the `struct IterationContext *`
- * @param peer identity of the neighbour
  * @param address the address
  * @param last_validation point in time when last validation was performed
  * @param valid_until point in time how long address is valid
@@ -1174,7 +1189,6 @@ struct IterationContext
  */
 static void
 send_validation_information (void *cls,
-                             const struct GNUNET_PeerIdentity *peer,
                              const struct GNUNET_HELLO_Address *address,
                              struct GNUNET_TIME_Absolute last_validation,
                              struct GNUNET_TIME_Absolute valid_until,
@@ -1184,20 +1198,20 @@ send_validation_information (void *cls,
   struct IterationContext *pc = cls;
   struct ValidationIterateResponseMessage *msg;
 
-  if ( (GNUNET_YES == pc->all) ||
-       (0 == memcmp (peer, &pc->id, sizeof (pc->id))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-        "Sending information about for validation entry for peer `%s' using address `%s'\n",
-        GNUNET_i2s(peer), (address != NULL) ? GST_plugins_a2s (address) : "<none>");
-    msg = compose_validation_iterate_response_message (peer, address);
-    msg->last_validation = GNUNET_TIME_absolute_hton(last_validation);
-    msg->valid_until = GNUNET_TIME_absolute_hton(valid_until);
-    msg->next_validation = GNUNET_TIME_absolute_hton(next_validation);
-    msg->state = htonl ((uint32_t) state);
-    GNUNET_SERVER_transmit_context_append_message (pc->tc, &msg->header);
-    GNUNET_free (msg);
-  }
+  if ( (GNUNET_YES != pc->all) &&
+       (0 != memcmp (&address->peer, &pc->id, sizeof (pc->id))) )
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending information about for validation entry for peer `%s' using address `%s'\n",
+              GNUNET_i2s (&address->peer),
+              (NULL != address) ? GST_plugins_a2s (address) : "<none>");
+  msg = compose_validation_iterate_response_message (&address->peer, address);
+  msg->last_validation = GNUNET_TIME_absolute_hton(last_validation);
+  msg->valid_until = GNUNET_TIME_absolute_hton(valid_until);
+  msg->next_validation = GNUNET_TIME_absolute_hton(next_validation);
+  msg->state = htonl ((uint32_t) state);
+  GNUNET_SERVER_transmit_context_append_message (pc->tc, &msg->header);
+  GNUNET_free (msg);
 }
 
 
@@ -1224,20 +1238,19 @@ send_peer_information (void *cls,
   struct IterationContext *pc = cls;
   struct PeerIterateResponseMessage *msg;
 
-  if ( (GNUNET_YES == pc->all) ||
-       (0 == memcmp (peer, &pc->id, sizeof (pc->id))) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-        "Sending information about `%s' using address `%s' in state `%s'\n",
-        GNUNET_i2s(peer),
-        (address != NULL) ? GST_plugins_a2s (address) : "<none>",
-        GNUNET_TRANSPORT_ps2s (state));
-    msg = compose_address_iterate_response_message (peer, address);
-    msg->state = htonl (state);
-    msg->state_timeout = GNUNET_TIME_absolute_hton(state_timeout);
-    GNUNET_SERVER_transmit_context_append_message (pc->tc, &msg->header);
-    GNUNET_free (msg);
-  }
+  if ( (GNUNET_YES != pc->all) &&
+       (0 != memcmp (peer, &pc->id, sizeof (pc->id))) )
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending information about `%s' using address `%s' in state `%s'\n",
+              GNUNET_i2s(peer),
+              (NULL != address) ? GST_plugins_a2s (address) : "<none>",
+              GNUNET_TRANSPORT_ps2s (state));
+  msg = compose_address_iterate_response_message (peer, address);
+  msg->state = htonl (state);
+  msg->state_timeout = GNUNET_TIME_absolute_hton(state_timeout);
+  GNUNET_SERVER_transmit_context_append_message (pc->tc, &msg->header);
+  GNUNET_free (msg);
 }
 
 
@@ -1254,18 +1267,15 @@ clients_handle_monitor_peers (void *cls,
                               struct GNUNET_SERVER_Client *client,
                               const struct GNUNET_MessageHeader *message)
 {
-  static struct GNUNET_PeerIdentity all_zeros;
   struct GNUNET_SERVER_TransmitContext *tc;
   const struct PeerMonitorMessage *msg;
   struct IterationContext pc;
 
   msg = (const struct PeerMonitorMessage *) message;
   if ( (GNUNET_YES != ntohl (msg->one_shot)) &&
-       (NULL != lookup_monitoring_client (peer_monitoring_clients_head, client)) )
+       (NULL != lookup_monitoring_client (peer_monitoring_clients_head,
+                                          client)) )
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-               "ServerClient %p tried to start monitoring twice\n",
-               client);
     GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
@@ -1275,7 +1285,9 @@ clients_handle_monitor_peers (void *cls,
   pc.tc = tc = GNUNET_SERVER_transmit_context_create (client);
 
   /* Send initial list */
-  if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
+  if (0 == memcmp (&msg->peer,
+                   &all_zeros,
+                   sizeof (struct GNUNET_PeerIdentity)))
   {
     /* iterate over all neighbours */
     pc.all = GNUNET_YES;
@@ -1316,7 +1328,6 @@ clients_handle_monitor_validation (void *cls,
                                   struct GNUNET_SERVER_Client *client,
                                   const struct GNUNET_MessageHeader *message)
 {
-  static struct GNUNET_PeerIdentity all_zeros;
   struct GNUNET_SERVER_TransmitContext *tc;
   struct PeerMonitorMessage *msg;
   struct IterationContext pc;
@@ -1337,9 +1348,6 @@ clients_handle_monitor_validation (void *cls,
   if ( (GNUNET_YES != ntohl (msg->one_shot)) &&
        (NULL != lookup_monitoring_client (val_monitoring_clients_head, client)) )
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-                "ServerClient %p tried to start monitoring twice\n",
-                client);
     GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
@@ -1349,7 +1357,9 @@ clients_handle_monitor_validation (void *cls,
   pc.tc = tc = GNUNET_SERVER_transmit_context_create (client);
 
   /* Send initial list */
-  if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
+  if (0 == memcmp (&msg->peer,
+                   &all_zeros,
+                   sizeof (struct GNUNET_PeerIdentity)))
   {
     /* iterate over all neighbours */
     pc.all = GNUNET_YES;
@@ -1361,8 +1371,8 @@ clients_handle_monitor_validation (void *cls,
     pc.all = GNUNET_NO;
     pc.id = msg->peer;
   }
-
-  GST_validation_iterate (&send_validation_information, &pc);
+  GST_validation_iterate (&send_validation_information,
+                          &pc);
 
   if (GNUNET_YES != ntohl (msg->one_shot))
   {
@@ -1371,7 +1381,7 @@ clients_handle_monitor_validation (void *cls,
   else
   {
     GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
-        GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);
+                                                GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);
   }
   GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
 }
@@ -1452,7 +1462,7 @@ plugin_session_info_cb (void *cls,
   msg->plugin_address_len = htons (alen);
   name = (char *) &msg[1];
   memcpy (name, info->address->transport_name, slen);
-  addr = &name[slen + 1];
+  addr = &name[slen];
   memcpy (addr, info->address->address, alen);
   if (NULL != sync_client)
     GNUNET_SERVER_notification_context_unicast (plugin_nc,
@@ -1505,6 +1515,9 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server)
     {&clients_handle_request_connect, NULL,
      GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT,
      sizeof (struct TransportRequestConnectMessage)},
+    {&clients_handle_request_disconnect, NULL,
+     GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_DISCONNECT,
+     sizeof (struct TransportRequestDisconnectMessage)},
     {&clients_handle_address_to_string, NULL,
      GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING, 0},
     {&clients_handle_monitor_peers, NULL,
@@ -1582,8 +1595,9 @@ GST_clients_broadcast (const struct GNUNET_MessageHeader *msg,
 
   for (tc = clients_head; NULL != tc; tc = tc->next)
   {
-    if ((GNUNET_YES == may_drop) && (GNUNET_YES != tc->send_payload))
-      continue;                 /* skip, this client does not care about payload */
+    if ( (GNUNET_YES == may_drop) &&
+         (GNUNET_YES != tc->send_payload) )
+      continue; /* skip, this client does not care about payload */
     unicast (tc, msg, may_drop);
   }
 }
@@ -1624,30 +1638,25 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
                                          enum GNUNET_TRANSPORT_PeerState state,
                                          struct GNUNET_TIME_Absolute state_timeout)
 {
-  static struct GNUNET_PeerIdentity all_zeros;
   struct PeerIterateResponseMessage *msg;
   struct MonitoringClient *mc;
 
   msg = compose_address_iterate_response_message (peer, address);
   msg->state = htonl (state);
   msg->state_timeout = GNUNET_TIME_absolute_hton (state_timeout);
-  mc = peer_monitoring_clients_head;
-  while (mc != NULL)
-  {
+  for (mc = peer_monitoring_clients_head; NULL != mc; mc = mc->next)
     if ((0 == memcmp (&mc->peer, &all_zeros,
                       sizeof (struct GNUNET_PeerIdentity))) ||
         (0 == memcmp (&mc->peer, peer,
                       sizeof (struct GNUNET_PeerIdentity))))
-    {
-      GNUNET_SERVER_notification_context_unicast (peer_nc, mc->client,
-                                                  &msg->header, GNUNET_NO);
-    }
-
-    mc = mc->next;
-  }
+      GNUNET_SERVER_notification_context_unicast (peer_nc,
+                                                  mc->client,
+                                                  &msg->header,
+                                                  GNUNET_NO);
   GNUNET_free (msg);
 }
 
+
 /**
  * Broadcast the new validation changes to all clients monitoring the peer.
  *
@@ -1668,31 +1677,25 @@ GST_clients_broadcast_validation_notification (const struct GNUNET_PeerIdentity
 {
   struct ValidationIterateResponseMessage *msg;
   struct MonitoringClient *mc;
-  static struct GNUNET_PeerIdentity all_zeros;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Sending information about for validation entry for peer `%s' using address `%s'\n",
-              GNUNET_i2s(peer), (address != NULL) ? GST_plugins_a2s (address) : "<none>");
-
+              GNUNET_i2s(peer),
+              (address != NULL) ? GST_plugins_a2s (address) : "<none>");
   msg = compose_validation_iterate_response_message (peer, address);
   msg->last_validation = GNUNET_TIME_absolute_hton(last_validation);
   msg->valid_until = GNUNET_TIME_absolute_hton(valid_until);
   msg->next_validation = GNUNET_TIME_absolute_hton(next_validation);
   msg->state = htonl ((uint32_t) state);
-  mc = val_monitoring_clients_head;
-  while (mc != NULL)
-  {
+  for (mc = val_monitoring_clients_head; NULL != mc; mc = mc->next)
     if ((0 == memcmp (&mc->peer, &all_zeros,
                       sizeof (struct GNUNET_PeerIdentity))) ||
         (0 == memcmp (&mc->peer, peer,
                       sizeof (struct GNUNET_PeerIdentity))))
-    {
-      GNUNET_SERVER_notification_context_unicast (val_nc, mc->client,
-                                                  &msg->header, GNUNET_NO);
-
-    }
-    mc = mc->next;
-  }
+      GNUNET_SERVER_notification_context_unicast (val_nc,
+                                                  mc->client,
+                                                  &msg->header,
+                                                  GNUNET_NO);
   GNUNET_free (msg);
 }