gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated (a225f5848 -> 4c56d5a0f)


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated (a225f5848 -> 4c56d5a0f)
Date: Sun, 22 Jan 2017 15:23:41 +0100

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

grothoff pushed a change to branch master
in repository gnunet.

    from a225f5848 still fixing the stupid connect_task cleanup issue
     new abda55f70 optimize startup sequence for when we execute first DHT PUTs
     new 868081cc8 do not run upnpc during tests, produces unnecessary errors 
if not available
     new da1a4cb33 improve logging, log before doing, not after
     new 2ecdd817e fix startup interaction between channel and tunnel to not 
send CHANNEL_OPEN until tunnel is in KEY_OK state
     new e8e9d0338 only send CHANNEL_DESTROY message if we at least send the 
CHANNEL_CREATE message, and not if the tunnel never went up in the first place
     new 0e6da3245 improving logging
     new 02132e8fc introcude GNUNET_i2s2()
     new ee5f54e2a allow NULL argument for GNUNET_i2s()
     new da6e9cb61 more logging for cadet-core subsystem
     new 568dcc7b4 make GCPP_2s also return static string
     new 07bb7990c fix buffer size
     new 56d30aad4 fix a few off-by-ones
     new 2df6a5610 properly launch DHT GETs based on need for paths
     new c79a9a5ad fix indentation
     new 0e9db527b minor cleanup
     new c559c5b81 nicer order of LOG statements
     new 2fd64e117 must delay iteration over paths until later, as we may be 
right now creating a connection
     new 9f1d37266 nicer logging
     new 4c56d5a0f must not move location of -struct CadetPeerPathEntry- in 
memory when growing path length as those structs are also referenced from a DLL

The 19 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-new.c            |  11 +-
 src/cadet/gnunet-service-cadet-new_channel.c    |  47 ++-
 src/cadet/gnunet-service-cadet-new_channel.h    |  14 +
 src/cadet/gnunet-service-cadet-new_connection.c |  23 +-
 src/cadet/gnunet-service-cadet-new_core.c       |  80 ++++-
 src/cadet/gnunet-service-cadet-new_dht.c        |  40 ++-
 src/cadet/gnunet-service-cadet-new_dht.h        |   7 +
 src/cadet/gnunet-service-cadet-new_hello.c      |   2 +
 src/cadet/gnunet-service-cadet-new_paths.c      | 130 +++++--
 src/cadet/gnunet-service-cadet-new_paths.h      |   4 +-
 src/cadet/gnunet-service-cadet-new_peer.c       | 452 +++++++++++++++---------
 src/cadet/gnunet-service-cadet-new_tunnels.c    | 108 ++++--
 src/cadet/test_cadet.c                          |  63 ++--
 src/cadet/test_cadet.conf                       |   2 +
 src/include/gnunet_common.h                     |  16 +
 src/util/common_logging.c                       |  35 +-
 src/util/strings.c                              |   4 +-
 17 files changed, 752 insertions(+), 286 deletions(-)

diff --git a/src/cadet/gnunet-service-cadet-new.c 
b/src/cadet/gnunet-service-cadet-new.c
index ff143b4b3..b0d8fc32d 100644
--- a/src/cadet/gnunet-service-cadet-new.c
+++ b/src/cadet/gnunet-service-cadet-new.c
@@ -525,6 +525,11 @@ handle_channel_create (void *cls,
     GNUNET_SERVICE_client_drop (c->client);
     return;
   }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "New channel to %s at port %s requested by client %s\n",
+       GNUNET_i2s (&tcm->peer),
+       GNUNET_h2s (&tcm->port),
+       GSC_2s (c));
 
   /* Create channel */
   ch = GCCH_channel_local_new (c,
@@ -545,12 +550,6 @@ handle_channel_create (void *cls,
                                                       ch,
                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "New channel %s to %s at port %s requested by client %s\n",
-       GCCH_2s (ch),
-       GNUNET_i2s (&tcm->peer),
-       GNUNET_h2s (&tcm->port),
-       GSC_2s (c));
   GNUNET_SERVICE_client_continue (c->client);
 }
 
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c 
b/src/cadet/gnunet-service-cadet-new_channel.c
index 6f57538ac..563b1c7e7 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ b/src/cadet/gnunet-service-cadet-new_channel.c
@@ -323,12 +323,10 @@ GCCH_2s (const struct CadetChannel *ch)
 {
   static char buf[128];
 
-  if (NULL == ch)
-    return "(NULL Channel)";
   GNUNET_snprintf (buf,
                    sizeof (buf),
-                   "%s:%s ctn:%X (%X)",
-                   GCT_2s (ch->t),
+                   "%s:%s ctn:%X(%X)",
+                   GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))),
                    GNUNET_h2s (&ch->port),
                    ch->ctn,
                    ntohl (ch->ccn.channel_of_client));
@@ -440,6 +438,9 @@ send_channel_open (void *cls)
   uint32_t options;
 
   ch->retry_task = NULL;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Sending CHANNEL_OPEN message for channel %s\n",
+       GCCH_2s (ch));
   options = 0;
   if (ch->nobuffer)
     options |= GNUNET_CADET_OPTION_NOBUFFER;
@@ -457,9 +458,25 @@ send_channel_open (void *cls)
                                   &msgcc.header,
                                   &channel_open_sent_cb,
                                   ch);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Sending CHANNEL_OPEN message for channel %s\n",
-       GCCH_2s (ch));
+}
+
+
+/**
+ * Function called once and only once after a channel was bound
+ * to its tunnel via #GCT_add_channel() is ready for transmission.
+ * Note that this is only the case for channels that this peer
+ * initiates, as for incoming channels we assume that they are
+ * ready for transmission immediately upon receiving the open
+ * message.  Used to bootstrap the #GCT_send() process.
+ *
+ * @param ch the channel for which the tunnel is now ready
+ */
+void
+GCCH_tunnel_up (struct CadetChannel *ch)
+{
+  GNUNET_assert (NULL == ch->retry_task);
+  ch->retry_task = GNUNET_SCHEDULER_add_now (&send_channel_open,
+                                             ch);
 }
 
 
@@ -492,11 +509,9 @@ GCCH_channel_local_new (struct CadetClient *owner,
   ch->port = *port;
   ch->t = GCP_get_tunnel (destination,
                           GNUNET_YES);
-  ch->ctn = GCT_add_channel (ch->t,
-                              ch);
   ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
-  ch->retry_task = GNUNET_SCHEDULER_add_now (&send_channel_open,
-                                             ch);
+  ch->ctn = GCT_add_channel (ch->t,
+                             ch);
   GNUNET_STATISTICS_update (stats,
                             "# channels",
                             1,
@@ -753,9 +768,11 @@ GCCH_channel_local_destroy (struct CadetChannel *ch)
     ch->destroy = GNUNET_YES;
     return;
   }
-  /* Nothing left to do, just finish destruction */
-  GCT_send_channel_destroy (ch->t,
-                            ch->ctn);
+  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy 
message. */
+  if (CADET_CHANNEL_NEW != ch->state)
+    GCT_send_channel_destroy (ch->t,
+                              ch->ctn);
+  /* Now finish our clean up */
   channel_destroy (ch);
 }
 
@@ -814,6 +831,8 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch)
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Received channel OPEN_ACK for waiting channel %s, entering READY 
state\n",
          GCCH_2s (ch));
+    GNUNET_SCHEDULER_cancel (ch->retry_task);
+    ch->retry_task = NULL;
     ch->state = CADET_CHANNEL_READY;
     /* On first connect, send client as many ACKs as we allow messages
        to be buffered! */
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h 
b/src/cadet/gnunet-service-cadet-new_channel.h
index a479145aa..ae4c5da5a 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.h
+++ b/src/cadet/gnunet-service-cadet-new_channel.h
@@ -119,6 +119,20 @@ GCCH_channel_local_destroy (struct CadetChannel *ch);
 
 
 /**
+ * Function called once and only once after a channel was bound
+ * to its tunnel via #GCT_add_channel() is ready for transmission.
+ * Note that this is only the case for channels that this peer
+ * initiates, as for incoming channels we assume that they are
+ * ready for transmission immediately upon receiving the open
+ * message.  Used to bootstrap the #GCT_send() process.
+ *
+ * @param ch the channel for which the tunnel is now ready
+ */
+void
+GCCH_tunnel_up (struct CadetChannel *ch);
+
+
+/**
  * Create a new channel based on a request coming in over the network.
  *
  * @param t tunnel to the remote peer
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c 
b/src/cadet/gnunet-service-cadet-new_connection.c
index e22202a59..3d0b96fcf 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ b/src/cadet/gnunet-service-cadet-new_connection.c
@@ -294,16 +294,16 @@ send_create (void *cls)
 
   cc->task = NULL;
   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
-  path_length = GCPP_get_length (cc->path) + 1;
+  path_length = GCPP_get_length (cc->path);
   env = GNUNET_MQ_msg_extra (create_msg,
-                             path_length * sizeof (struct GNUNET_PeerIdentity),
+                             (1 + path_length) * sizeof (struct 
GNUNET_PeerIdentity),
                              GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
   create_msg->cid = cc->cid;
   pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
   pids[0] = my_full_id;
-  for (unsigned int i=1;i<=path_length;i++)
-    pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
-                                                    i - 1));
+  for (unsigned int i=0;i<path_length;i++)
+    pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
+                                                        i));
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Sending CONNECTION_CREATE message for connection %s\n",
        GCC_2s (cc));
@@ -493,6 +493,10 @@ connection_create (struct CadetPeer *destination,
   cc->ready_cb_cls = ready_cb_cls;
   cc->path = path;
   cc->off = off;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Creating connection %s using path %s\n",
+       GCC_2s (cc),
+       GCPP_2s (path));
   GCPP_add_connection (path,
                        off,
                        cc);
@@ -506,10 +510,6 @@ connection_create (struct CadetPeer *destination,
   cc->mq_man = GCP_request_mq (first_hop,
                                &manage_first_hop_mq,
                                cc);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Created connection %s using path %s\n",
-       GCC_2s (cc),
-       GCPP_2s (path));
   return cc;
 }
 
@@ -672,7 +672,6 @@ GCC_debug (struct CadetConnection *cc,
            enum GNUNET_ErrorType level)
 {
   int do_log;
-  char *s;
 
   do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
                                        "cadet-con",
@@ -685,15 +684,13 @@ GCC_debug (struct CadetConnection *cc,
           "Connection (NULL)\n");
     return;
   }
-  s = GCPP_2s (cc->path);
   LOG2 (level,
         "Connection %s to %s via path %s in state %d is %s\n",
         GCC_2s (cc),
         GCP_2s (cc->destination),
-        s,
+        GCPP_2s (cc->path),
         cc->state,
         (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
-  GNUNET_free (s);
 }
 
 /* end of gnunet-service-cadet-new_connection.c */
diff --git a/src/cadet/gnunet-service-cadet-new_core.c 
b/src/cadet/gnunet-service-cadet-new_core.c
index 26952f616..7cff68f4a 100644
--- a/src/cadet/gnunet-service-cadet-new_core.c
+++ b/src/cadet/gnunet-service-cadet-new_core.c
@@ -173,6 +173,11 @@ route_message (struct CadetPeer *prev,
     struct GNUNET_MQ_Envelope *env;
     struct GNUNET_CADET_ConnectionBrokenMessage *bm;
 
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Failed to route message of type %u from %s on connection %s: no 
route\n",
+         ntohs (msg->type),
+         GCP_2s (prev),
+         GNUNET_sh2s (&cid->connection_of_tunnel));
     env = GNUNET_MQ_msg (bm,
                          GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
     bm->cid = *cid;
@@ -184,6 +189,12 @@ route_message (struct CadetPeer *prev,
   dir = (prev == route->prev.hop) ? &route->next : &route->prev;
   if (GNUNET_YES == dir->is_ready)
   {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Routing message of type %u from %s to %s on connection %s\n",
+         ntohs (msg->type),
+         GCP_2s (prev),
+         GNUNET_i2s (GCP_get_id (dir->hop)),
+         GNUNET_sh2s (&cid->connection_of_tunnel));
     dir->is_ready = GNUNET_NO;
     GCP_send (dir->mqm,
               GNUNET_MQ_msg_copy (msg));
@@ -193,12 +204,24 @@ route_message (struct CadetPeer *prev,
   if (NULL != env)
   {
     /* Queue full, drop earliest message in queue */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Queue full due to new message of type %u from %s to %s on connection 
%s, dropping old message\n",
+         ntohs (msg->type),
+         GCP_2s (prev),
+         GNUNET_i2s (GCP_get_id (dir->hop)),
+         GNUNET_sh2s (&cid->connection_of_tunnel));
     GNUNET_assert (dir->out_rpos == dir->out_wpos);
     GNUNET_MQ_discard (env);
     dir->out_rpos++;
     if (ROUTE_BUFFER_SIZE == dir->out_rpos)
       dir->out_rpos = 0;
   }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Queueing new message of type %u from %s to %s on connection %s\n",
+       ntohs (msg->type),
+       GCP_2s (prev),
+       GNUNET_i2s (GCP_get_id (dir->hop)),
+       GNUNET_sh2s (&cid->connection_of_tunnel));
   env = GNUNET_MQ_msg_copy (msg);
   dir->out_buffer[dir->out_wpos] = env;
   dir->out_wpos++;
@@ -261,6 +284,11 @@ destroy_direction (struct RouteDirection *dir)
 static void
 destroy_route (struct CadetRoute *route)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Destroying route from %s to %s of connection %s\n",
+       GNUNET_i2s  (GCP_get_id (route->prev.hop)),
+       GNUNET_i2s2 (GCP_get_id (route->next.hop)),
+       GNUNET_sh2s (&route->cid.connection_of_tunnel));
   destroy_direction (&route->prev);
   destroy_direction (&route->next);
   GNUNET_free (route);
@@ -284,6 +312,13 @@ send_broken (struct RouteDirection *target,
   struct GNUNET_MQ_Envelope *env;
   struct GNUNET_CADET_ConnectionBrokenMessage *bm;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Notifying %s about BROKEN route at %s-%s of connection %s\n",
+       GCP_2s (target->hop),
+       GNUNET_i2s (peer1),
+       GNUNET_i2s2 (peer2),
+       GNUNET_sh2s (&cid->connection_of_tunnel));
+
   env = GNUNET_MQ_msg (bm,
                        GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
   bm->cid = *cid;
@@ -407,6 +442,9 @@ handle_connection_create (void *cls,
       get_route (&msg->cid))
   {
     /* Duplicate CREATE, pass it on, previous one might have been lost! */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Passing on duplicate CREATE message on connection %s\n",
+         GNUNET_sh2s (&msg->cid.connection_of_tunnel));
     route_message (sender,
                    &msg->cid,
                    &msg->header);
@@ -423,14 +461,21 @@ handle_connection_create (void *cls,
                                              &msg->cid.connection_of_tunnel);
     if (NULL != cc)
     {
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Received duplicate CREATE message on connection %s\n",
+           GNUNET_sh2s (&msg->cid.connection_of_tunnel));
       GCC_handle_duplicate_create (cc);
       return;
     }
 
-    path = GCPP_get_path_from_route (path_length - 1,
-                                     pids);
     origin = GCP_get (&pids[0],
                       GNUNET_YES);
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Received CREATE message from %s for connection %s, building inverse 
path\n",
+         GCP_2s (origin),
+         GNUNET_sh2s (&msg->cid.connection_of_tunnel));
+    path = GCPP_get_path_from_route (path_length - 1,
+                                     pids);
     GCT_add_inbound_connection (GCT_create_tunnel (origin),
                                 &msg->cid,
                                 path);
@@ -446,6 +491,12 @@ handle_connection_create (void *cls,
     struct GNUNET_MQ_Envelope *env;
     struct GNUNET_CADET_ConnectionBrokenMessage *bm;
 
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Received CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. 
Sending BROKEN\n",
+         GCP_2s (sender),
+         GNUNET_sh2s (&msg->cid.connection_of_tunnel),
+         GNUNET_i2s (&pids[off + 1]),
+         off + 1);
     env = GNUNET_MQ_msg (bm,
                          GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
     bm->cid = msg->cid;
@@ -457,6 +508,12 @@ handle_connection_create (void *cls,
   }
 
   /* Workable route, create routing entry */
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. 
Creating route\n",
+       GCP_2s (sender),
+       GNUNET_sh2s (&msg->cid.connection_of_tunnel),
+       GNUNET_i2s (&pids[off + 1]),
+       off + 1);
   route = GNUNET_new (struct CadetRoute);
   route->cid = msg->cid;
   dir_init (&route->prev,
@@ -502,6 +559,9 @@ handle_connection_create_ack (void *cls,
       GNUNET_break_op (0);
       return;
     }
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Received CONNECTION_CREATE_ACK for connection %s.\n",
+         GNUNET_sh2s (&msg->cid.connection_of_tunnel));
     GCC_handle_connection_create_ack (cc);
     return;
   }
@@ -544,6 +604,9 @@ handle_connection_broken (void *cls,
       GNUNET_break_op (0);
       return;
     }
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
+         GNUNET_sh2s (&msg->cid.connection_of_tunnel));
     GCC_destroy (cc);
 
     /* FIXME: also destroy the path up to the specified link! */
@@ -590,11 +653,18 @@ handle_connection_destroy (void *cls,
       GNUNET_break_op (0);
       return;
     }
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Received CONNECTION_DESTROY for connection %s. Destroying 
connection.\n",
+         GNUNET_sh2s (&msg->cid.connection_of_tunnel));
+
     GCC_destroy (cc);
     return;
   }
 
   /* We're just an intermediary peer, route the message along its path */
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
+       GNUNET_sh2s (&msg->cid.connection_of_tunnel));
   route = get_route (&msg->cid);
   route_message (peer,
                  &msg->cid,
@@ -741,6 +811,9 @@ core_connect_cb (void *cls,
 {
   struct CadetPeer *cp;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "CORE connection to peer %s was established.\n",
+       GNUNET_i2s (peer));
   cp = GCP_get (peer,
                 GNUNET_YES);
   GCP_set_mq (cp,
@@ -762,6 +835,9 @@ core_disconnect_cb (void *cls,
 {
   struct CadetPeer *cp = peer_cls;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "CORE connection to peer %s went down.\n",
+       GNUNET_i2s (peer));
   GCP_set_mq (cp,
               NULL);
 }
diff --git a/src/cadet/gnunet-service-cadet-new_dht.c 
b/src/cadet/gnunet-service-cadet-new_dht.c
index 981553601..849562f23 100644
--- a/src/cadet/gnunet-service-cadet-new_dht.c
+++ b/src/cadet/gnunet-service-cadet-new_dht.c
@@ -34,6 +34,22 @@
 #include "gnunet-service-cadet-new_peer.h"
 #include "gnunet-service-cadet-new_paths.h"
 
+/**
+ * How long do we wait before first announcing our presence to the DHT.
+ * Used to wait for our HELLO to be available.  Note that we also get
+ * notifications when our HELLO is ready, so this is just the maximum
+ * we wait for the first notification.
+ */
+#define STARTUP_DELAY GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS, 500)
+
+/**
+ * How long do we wait after we get an updated HELLO before publishing?
+ * Allows for the HELLO to be updated again quickly, for example in
+ * case multiple addresses changed and we got a partial update.
+ */
+#define CHANGE_DELAY GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS, 100)
+
+
 #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__)
 
 
@@ -195,6 +211,23 @@ announce_id (void *cls)
 
 
 /**
+ * Function called by the HELLO subsystem whenever OUR hello
+ * changes. Re-triggers the DHT PUT immediately.
+ */
+void
+GCD_hello_update ()
+{
+  if (NULL == announce_id_task)
+    return; /* too early */
+  GNUNET_SCHEDULER_cancel (announce_id_task);
+  announce_id_task
+    = GNUNET_SCHEDULER_add_delayed (CHANGE_DELAY,
+                                    &announce_id,
+                                    NULL);
+}
+
+
+/**
  * Initialize the DHT subsystem.
  *
  * @param c Configuration.
@@ -202,8 +235,6 @@ announce_id (void *cls)
 void
 GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
 {
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "init\n");
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_number (c,
                                              "CADET",
@@ -235,8 +266,9 @@ GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
                                    64);
   GNUNET_break (NULL != dht_handle);
   announce_delay = GNUNET_TIME_UNIT_SECONDS;
-  announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id,
-                                               NULL);
+  announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY,
+                                                   &announce_id,
+                                                   NULL);
 }
 
 
diff --git a/src/cadet/gnunet-service-cadet-new_dht.h 
b/src/cadet/gnunet-service-cadet-new_dht.h
index 81f16ae99..5d7ab29a0 100644
--- a/src/cadet/gnunet-service-cadet-new_dht.h
+++ b/src/cadet/gnunet-service-cadet-new_dht.h
@@ -63,6 +63,13 @@ GCD_shutdown (void);
 
 
 /**
+ * Function called by the HELLO subsystem whenever OUR hello
+ * changes. Re-triggers the DHT PUT immediately.
+ */
+void
+GCD_hello_update (void);
+
+/**
  * Search DHT for paths to @a peeR_id
  *
  * @param peer_id peer to search for
diff --git a/src/cadet/gnunet-service-cadet-new_hello.c 
b/src/cadet/gnunet-service-cadet-new_hello.c
index 7c8ba3b25..a24325ada 100644
--- a/src/cadet/gnunet-service-cadet-new_hello.c
+++ b/src/cadet/gnunet-service-cadet-new_hello.c
@@ -34,6 +34,7 @@
 #include "gnunet_peerinfo_service.h"
 #include "cadet_protocol.h"
 #include "gnunet-service-cadet-new.h"
+#include "gnunet-service-cadet-new_dht.h"
 #include "gnunet-service-cadet-new_hello.h"
 #include "gnunet-service-cadet-new_peer.h"
 
@@ -80,6 +81,7 @@ got_hello (void *cls,
   {
     GNUNET_free_non_null (mine);
     mine = (struct GNUNET_HELLO_Message *) GNUNET_copy_message 
(&hello->header);
+    GCD_hello_update ();
     return;
   }
 
diff --git a/src/cadet/gnunet-service-cadet-new_paths.c 
b/src/cadet/gnunet-service-cadet-new_paths.c
index 2bd62f436..1c648462d 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.c
+++ b/src/cadet/gnunet-service-cadet-new_paths.c
@@ -28,6 +28,7 @@
  *   (and will be tricky to have during path changes)
  */
 #include "platform.h"
+#include "gnunet-service-cadet-new_connection.h"
 #include "gnunet-service-cadet-new_peer.h"
 #include "gnunet-service-cadet-new_paths.h"
 
@@ -45,7 +46,7 @@ struct CadetPeerPath
    * Array of all the peers on the path.  If @e hn is non-NULL, the
    * last one is our owner.
    */
-  struct CadetPeerPathEntry *entries;
+  struct CadetPeerPathEntry **entries;
 
   /**
    * Node of this path in the owner's heap.  Used to update our position
@@ -112,7 +113,7 @@ GCPP_get_connection (struct CadetPeerPath *path,
   struct CadetPeerPathEntry *entry;
 
   GNUNET_assert (off < path->entries_length);
-  entry = &path->entries[off];
+  entry = path->entries[off];
   GNUNET_assert (entry->peer == destination);
   return entry->cc;
 }
@@ -133,8 +134,13 @@ GCPP_add_connection (struct CadetPeerPath *path,
 {
   struct CadetPeerPathEntry *entry;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Adding connection %s to path %s at offset %u\n",
+       GCC_2s (cc),
+       GCPP_2s (path),
+       off);
   GNUNET_assert (off < path->entries_length);
-  entry = &path->entries[off];
+  entry = path->entries[off];
   GNUNET_assert (NULL == entry->cc);
   entry->cc = cc;
 }
@@ -156,8 +162,13 @@ GCPP_del_connection (struct CadetPeerPath *path,
 {
   struct CadetPeerPathEntry *entry;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Removing connection %s to path %s at offset %u\n",
+       GCC_2s (cc),
+       GCPP_2s (path),
+       off);
   GNUNET_assert (off < path->entries_length);
-  entry = &path->entries[off];
+  entry = path->entries[off];
   GNUNET_assert (cc == entry->cc);
   entry->cc = NULL;
 }
@@ -171,9 +182,14 @@ GCPP_del_connection (struct CadetPeerPath *path,
 static void
 path_destroy (struct CadetPeerPath *path)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Destroying path %s\n",
+       GCPP_2s (path));
   GNUNET_assert (0 ==
                  GNUNET_CONTAINER_multipeermap_size (path->connections));
   GNUNET_CONTAINER_multipeermap_destroy (path->connections);
+  for (unsigned int i=0;i<path->entries_length;i++)
+    GNUNET_free (path->entries[i]);
   GNUNET_free (path->entries);
   GNUNET_free (path);
 }
@@ -191,8 +207,11 @@ GCPP_release (struct CadetPeerPath *path)
 {
   struct CadetPeerPathEntry *entry;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Owner releases path %s\n",
+       GCPP_2s (path));
   path->hn = NULL;
-  entry = &path->entries[path->entries_length - 1];
+  entry = path->entries[path->entries_length - 1];
   while (1)
   {
     /* cut 'off' end of path, verifying it is not in use */
@@ -204,11 +223,12 @@ GCPP_release (struct CadetPeerPath *path)
                            path->entries_length - 1);
     path->entries_length--; /* We don't bother shrinking the 'entries' array,
                                as it's probably not worth it. */
+    GNUNET_free (entry);
     if (0 == path->entries_length)
       break; /* the end */
 
     /* see if new peer at the end likes this path any better */
-    entry = &path->entries[path->entries_length - 1];
+    entry = path->entries[path->entries_length - 1];
     path->hn = GCP_attach_path (entry->peer,
                                 path,
                                 path->entries_length,
@@ -238,7 +258,7 @@ GCPP_update_score (struct CadetPeerPath *path,
   struct CadetPeerPathEntry *entry;
 
   GNUNET_assert (off < path->entries_length);
-  entry = &path->entries[off];
+  entry = path->entries[off];
 
   /* Add delta, with checks for overflows */
   if (delta >= 0)
@@ -276,6 +296,11 @@ struct CheckMatchContext
    */
   struct CadetPeer **cpath;
 
+  /**
+   * How long is the @e cpath array?
+   */
+  unsigned int cpath_length;
+
 };
 
 
@@ -296,8 +321,10 @@ check_match (void *cls,
 {
   struct CheckMatchContext *cm_ctx = cls;
 
-  if (path->entries_length > off)
-    return GNUNET_YES; /* too long, cannot be useful */
+  GNUNET_assert (path->entries_length > off);
+  if ( (path->entries_length != off + 1) &&
+       (off + 1 != cm_ctx->cpath_length) )
+    return GNUNET_YES; /* too long, goes somewhere else already, thus cannot 
be useful */
   for (unsigned int i=0;i<off;i++)
     if (cm_ctx->cpath[i] !=
         GCPP_get_peer_at_offset (path,
@@ -343,7 +370,7 @@ extend_path (struct CadetPeerPath *path,
   }
   if (NULL == hn)
     return; /* none of the peers is interested in this path */
-  GCP_detach_path (path->entries[old_len-1].peer,
+  GCP_detach_path (path->entries[old_len-1]->peer,
                    path,
                    path->hn);
   path->hn = hn;
@@ -352,14 +379,18 @@ extend_path (struct CadetPeerPath *path,
                      old_len + i);
   for (;i >= 0;i--)
   {
-    struct CadetPeerPathEntry *entry = &path->entries[old_len + i];
+    struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
 
+    path->entries[old_len + i] = entry;
     entry->peer = peers[i];
     entry->path = path;
     GCP_path_entry_add (entry->peer,
                         entry,
                         old_len + i);
   }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Extended path %s\n",
+       GCPP_2s (path));
 }
 
 
@@ -401,6 +432,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity 
*get_path,
 
   /* First figure out if this path is a subset of an existing path, an
      extension of an existing path, or a new path. */
+  cm_ctx.cpath_length = get_path_length + put_path_length;
   cm_ctx.cpath = cpath;
   cm_ctx.match = NULL;
   for (i=get_path_length + put_path_length-1;i>=0;i--)
@@ -414,11 +446,16 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity 
*get_path,
       if (i == get_path_length + put_path_length - 1)
       {
         /* Existing path includes this one, nothing to do! */
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+             "Path discovered from DHT is already known\n");
         return;
       }
       if (cm_ctx.match->entries_length == i + 1)
       {
         /* Existing path ends in the middle of new path, extend it! */
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+             "Trying to extend existing path %s by additional links discovered 
from DHT\n",
+             GCPP_2s (cm_ctx.match));
         extend_path (cm_ctx.match,
                      &cpath[i],
                      get_path_length + put_path_length - i,
@@ -435,7 +472,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity 
*get_path,
   hn = NULL;
   for (i=get_path_length + put_path_length-1;i>=0;i--)
   {
-    path->entries_length = i;
+    path->entries_length = i + 1;
     /* FIXME: note that path->desirability is used, but not yet initialized 
here! */
     hn = GCP_attach_path (cpath[i],
                           path,
@@ -447,23 +484,29 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity 
*get_path,
   if (NULL == hn)
   {
     /* None of the peers on the path care about it. */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Path discovered from DHT is not interesting to us\n");
     GNUNET_free (path);
     return;
   }
   path->hn = hn;
-  path->entries_length = i;
+  path->entries_length = i + 1;
   path->entries = GNUNET_new_array (path->entries_length,
-                                    struct CadetPeerPathEntry);
+                                    struct CadetPeerPathEntry *);
   for (;i>=0;i--)
   {
-    struct CadetPeerPathEntry *entry = &path->entries[i];
+    struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
 
+    path->entries[i] = entry;
     entry->peer = cpath[i];
     entry->path = path;
     GCP_path_entry_add (entry->peer,
                         entry,
                         i);
   }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Created new path %s based on information from DHT\n",
+       GCPP_2s (path));
 }
 
 
@@ -491,6 +534,7 @@ GCPP_get_path_from_route (unsigned int path_length,
   /* First figure out if this path is a subset of an existing path, an
      extension of an existing path, or a new path. */
   cm_ctx.cpath = cpath;
+  cm_ctx.cpath_length = path_length;
   cm_ctx.match = NULL;
   for (int i=path_length-1;i>=0;i--)
   {
@@ -503,11 +547,17 @@ GCPP_get_path_from_route (unsigned int path_length,
       if (i == path_length - 1)
       {
         /* Existing path includes this one, return the match! */
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+             "Returning existing path %s as inverse for incoming connection\n",
+             GCPP_2s (cm_ctx.match));
         return cm_ctx.match;
       }
       if (cm_ctx.match->entries_length == i + 1)
       {
         /* Existing path ends in the middle of new path, extend it! */
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+             "Extending existing path %s to create inverse for incoming 
connection\n",
+             GCPP_2s (cm_ctx.match));
         extend_path (cm_ctx.match,
                      &cpath[i],
                      path_length - i,
@@ -516,6 +566,8 @@ GCPP_get_path_from_route (unsigned int path_length,
         GNUNET_assert (cm_ctx.match->entries_length == path_length);
         return cm_ctx.match;
       }
+      /* Eh, we found a match but couldn't use it? Something is wrong. */
+      GNUNET_break (0);
     }
   }
 
@@ -523,17 +575,21 @@ GCPP_get_path_from_route (unsigned int path_length,
   path = GNUNET_new (struct CadetPeerPath);
   path->entries_length = path_length;
   path->entries = GNUNET_new_array (path->entries_length,
-                                    struct CadetPeerPathEntry);
+                                    struct CadetPeerPathEntry *);
   for (int i=path_length-1;i>=0;i--)
   {
-    struct CadetPeerPathEntry *entry = &path->entries[i];
+    struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
 
+    path->entries[i] = entry;
     entry->peer = cpath[i];
     entry->path = path;
     GCP_path_entry_add (entry->peer,
                         entry,
                         i);
   }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Created new path %s to create inverse for incoming connection\n",
+       GCPP_2s (path));
   path->hn = GCP_attach_path (cpath[path_length - 1],
                               path,
                               path_length - 1,
@@ -588,7 +644,8 @@ struct CadetPeer *
 GCPP_get_peer_at_offset (struct CadetPeerPath *path,
                          unsigned int off)
 {
-  return path->entries[off].peer;
+  GNUNET_assert (off < path->entries_length);
+  return path->entries[off]->peer;
 }
 
 
@@ -598,26 +655,39 @@ GCPP_get_peer_at_offset (struct CadetPeerPath *path,
  * @param path path to convert
  * @return string, to be freed by caller (unlike other *_2s APIs!)
  */
-char *
+const char *
 GCPP_2s (struct CadetPeerPath *path)
 {
-  char *s;
-  char *old;
+  static char buf[2048];
+  size_t off;
+  const unsigned int max_plen = (sizeof(buf) - 16) / 5 - 2; /* 5 characters 
per entry */
 
-  old = GNUNET_strdup ("");
+  off = 0;
   for (unsigned int i = 0;
        i < path->entries_length;
        i++)
   {
-    GNUNET_asprintf (&s,
-                     "%s %s",
-                     old,
-                     GCP_2s (GCPP_get_peer_at_offset (path,
-                                                      i)));
-    GNUNET_free_non_null (old);
-    old = s;
+    if ( (path->entries_length > max_plen) &&
+         (i == max_plen / 2) )
+      off += GNUNET_snprintf (&buf[off],
+                              sizeof (buf) - off,
+                              "...-");
+    if ( (path->entries_length > max_plen) &&
+         (i > max_plen / 2) &&
+         (i < path->entries_length - max_plen / 2) )
+      continue;
+    off += GNUNET_snprintf (&buf[off],
+                            sizeof (buf) - off,
+                            "%s%s",
+                            GNUNET_i2s (GCP_get_id (GCPP_get_peer_at_offset 
(path,
+                                                                             
i))),
+                            (i == path->entries_length -1) ? "" : "-");
   }
-  return old;
+  GNUNET_snprintf (&buf[off],
+                   sizeof (buf) - off,
+                   "(%p)",
+                   path);
+  return buf;
 }
 
 
diff --git a/src/cadet/gnunet-service-cadet-new_paths.h 
b/src/cadet/gnunet-service-cadet-new_paths.h
index 5714368c7..7310d75e6 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.h
+++ b/src/cadet/gnunet-service-cadet-new_paths.h
@@ -173,9 +173,9 @@ GCPP_get_peer_at_offset (struct CadetPeerPath *path,
  * Convert a path to a human-readable string.
  *
  * @param path path to convert
- * @return string, to be freed by caller (unlike other *_2s APIs!)
+ * @return string, statically allocated
  */
-char *
+const char *
 GCPP_2s (struct CadetPeerPath *p);
 
 
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c 
b/src/cadet/gnunet-service-cadet-new_peer.c
index cb9ea091b..39645c909 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ b/src/cadet/gnunet-service-cadet-new_peer.c
@@ -1,4 +1,3 @@
-
 /*
      This file is part of GNUnet.
      Copyright (C) 2001-2017 GNUnet e.V.
@@ -34,6 +33,7 @@
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
+#include "gnunet_hello_lib.h"
 #include "gnunet_signatures.h"
 #include "gnunet_transport_service.h"
 #include "gnunet_ats_service.h"
@@ -225,16 +225,19 @@ struct CadetPeer
 /**
  * Get the static string for a peer ID.
  *
- * @param peer Peer.
- *
+ * @param cp Peer.
  * @return Static string for it's ID.
  */
 const char *
-GCP_2s (const struct CadetPeer *peer)
+GCP_2s (const struct CadetPeer *cp)
 {
-  if (NULL == peer)
-    return "PEER(NULL)";
-  return GNUNET_i2s (&peer->pid);
+  static char buf[32];
+
+  GNUNET_snprintf (buf,
+                   sizeof (buf),
+                   "P(%s)",
+                   GNUNET_i2s (&cp->pid));
+  return buf;
 }
 
 
@@ -248,6 +251,9 @@ destroy_peer (void *cls)
 {
   struct CadetPeer *cp = cls;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Destroying state about peer %s\n",
+       GCP_2s (cp));
   cp->destroy_task = NULL;
   GNUNET_assert (NULL == cp->t);
   GNUNET_assert (NULL == cp->core_mq);
@@ -290,6 +296,146 @@ destroy_peer (void *cls)
 
 
 /**
+ * This peer is now on more "active" duty, activate processes related to it.
+ *
+ * @param cp the more-active peer
+ */
+static void
+consider_peer_activate (struct CadetPeer *cp)
+{
+  uint32_t strength;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Updating peer %s activation state (%u connections)%s%s\n",
+       GCP_2s (cp),
+       GNUNET_CONTAINER_multishortmap_size (cp->connections),
+       (NULL == cp->t) ? "" : " with tunnel",
+       (NULL == cp->core_mq) ? "" : " with CORE link");
+  if (NULL != cp->destroy_task)
+  {
+    /* It's active, do not destory! */
+    GNUNET_SCHEDULER_cancel (cp->destroy_task);
+    cp->destroy_task = NULL;
+  }
+  if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
+       (NULL == cp->t) )
+  {
+    /* We're just on a path or directly connected; don't bother too much */
+    if (NULL != cp->connectivity_suggestion)
+    {
+      GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
+      cp->connectivity_suggestion = NULL;
+    }
+    if (NULL != cp->search_h)
+    {
+      GCD_search_stop (cp->search_h);
+      cp->search_h = NULL;
+    }
+    return;
+  }
+  if (NULL == cp->core_mq)
+  {
+    /* Lacks direct connection, try to create one by querying the DHT */
+    if ( (NULL == cp->search_h) &&
+         (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
+      cp->search_h
+        = GCD_search (&cp->pid);
+  }
+  else
+  {
+    /* Have direct connection, stop DHT search if active */
+    if (NULL != cp->search_h)
+    {
+      GCD_search_stop (cp->search_h);
+      cp->search_h = NULL;
+    }
+  }
+
+  /* If we have a tunnel, our urge for connections is much bigger */
+  strength = (NULL != cp->t) ? 32 : 1;
+  if (NULL != cp->connectivity_suggestion)
+    GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
+  cp->connectivity_suggestion
+    = GNUNET_ATS_connectivity_suggest (ats_ch,
+                                       &cp->pid,
+                                       strength);
+}
+
+
+/**
+ * This peer may no longer be needed, consider cleaning it up.
+ *
+ * @param cp peer to clean up
+ */
+static void
+consider_peer_destroy (struct CadetPeer *cp);
+
+
+/**
+ * We really no longere care about a peer, stop hogging memory with paths to 
it.
+ * Afterwards, see if there is more to be cleaned up about this peer.
+ *
+ * @param cls a `struct CadetPeer`.
+ */
+static void
+drop_paths (void *cls)
+{
+  struct CadetPeer *cp = cls;
+  struct CadetPeerPath *path;
+
+  cp->destroy_task = NULL;
+  while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
+    GCPP_release (path);
+  consider_peer_destroy (cp);
+}
+
+
+/**
+ * This peer may no longer be needed, consider cleaning it up.
+ *
+ * @param cp peer to clean up
+ */
+static void
+consider_peer_destroy (struct CadetPeer *cp)
+{
+  struct GNUNET_TIME_Relative exp;
+
+  if (NULL != cp->destroy_task)
+  {
+    GNUNET_SCHEDULER_cancel (cp->destroy_task);
+    cp->destroy_task = NULL;
+  }
+  if (NULL != cp->t)
+    return; /* still relevant! */
+  if (NULL != cp->core_mq)
+    return; /* still relevant! */
+  if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
+    return; /* still relevant! */
+  if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap))
+  {
+    cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
+                                                     &drop_paths,
+                                                     cp);
+    return;
+  }
+  if (0 < cp->path_dll_length)
+    return; /* still relevant! */
+  if (NULL != cp->hello)
+  {
+    /* relevant only until HELLO expires */
+    exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration 
(cp->hello));
+    cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
+                                                     &destroy_peer,
+                                                     cp);
+    return;
+  }
+  cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
+                                                   &destroy_peer,
+                                                   cp);
+}
+
+
+/**
  * Set the message queue to @a mq for peer @a cp and notify watchers.
  *
  * @param cp peer to modify
@@ -299,8 +445,11 @@ void
 GCP_set_mq (struct CadetPeer *cp,
             struct GNUNET_MQ_Handle *mq)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Message queue for peer %s is now %p\n",
+       GCP_2s (cp),
+       mq);
   cp->core_mq = mq;
-
   for (struct GCP_MessageQueueManager *mqm = cp->mqm_head;
        NULL != mqm;
        mqm = mqm->next)
@@ -327,6 +476,24 @@ GCP_set_mq (struct CadetPeer *cp,
                GNUNET_YES);
     }
   }
+  if ( (NULL != mq) ||
+       (NULL != cp->t) )
+    consider_peer_activate (cp);
+  else
+    consider_peer_destroy (cp);
+
+  if ( (NULL != mq) &&
+       (NULL != cp->t) )
+  {
+    /* have a new, direct path to the target, notify tunnel */
+    struct CadetPeerPath *path;
+
+    path = GCPP_get_path_from_route (1,
+                                     &cp->pid);
+    GCT_consider_path (cp->t,
+                       path,
+                       0);
+  }
 }
 
 
@@ -340,6 +507,10 @@ mqm_execute (struct GCP_MessageQueueManager *mqm)
 {
   struct CadetPeer *cp = mqm->cp;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Sending to peer %s from MQM %p\n",
+       GCP_2s (cp),
+       mqm);
   /* Move entry to the end of the DLL, to be fair. */
   if (mqm != cp->mqm_tail)
   {
@@ -368,6 +539,9 @@ mqm_send_done (void *cls)
 {
   struct CadetPeer *cp = cls;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Sending to peer %s completed\n",
+       GCP_2s (cp));
   if (0 == cp->mqm_ready_counter)
     return; /* nothing to do */
   for (struct GCP_MessageQueueManager *mqm = cp->mqm_head;
@@ -395,6 +569,10 @@ GCP_send (struct GCP_MessageQueueManager *mqm,
 {
   struct CadetPeer *cp = mqm->cp;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Queueing message to peer %s in MQM %p\n",
+       GCP_2s (cp),
+       mqm);
   GNUNET_assert (NULL != cp->core_mq);
   GNUNET_assert (NULL == mqm->env);
   GNUNET_MQ_notify_sent (env,
@@ -441,6 +619,8 @@ destroy_iterator_cb (void *cls,
 void
 GCP_destroy_all_peers ()
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Destroying all peers now\n");
   GNUNET_CONTAINER_multipeermap_iterate (peers,
                                          &destroy_iterator_cb,
                                          NULL);
@@ -448,79 +628,6 @@ GCP_destroy_all_peers ()
 
 
 /**
- * This peer may no longer be needed, consider cleaning it up.
- *
- * @param cp peer to clean up
- */
-static void
-consider_peer_destroy (struct CadetPeer *cp);
-
-
-/**
- * We really no longere care about a peer, stop hogging memory with paths to 
it.
- * Afterwards, see if there is more to be cleaned up about this peer.
- *
- * @param cls a `struct CadetPeer`.
- */
-static void
-drop_paths (void *cls)
-{
-  struct CadetPeer *cp = cls;
-  struct CadetPeerPath *path;
-
-  cp->destroy_task = NULL;
-  while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
-    GCPP_release (path);
-  consider_peer_destroy (cp);
-}
-
-
-/**
- * This peer may no longer be needed, consider cleaning it up.
- *
- * @param cp peer to clean up
- */
-static void
-consider_peer_destroy (struct CadetPeer *cp)
-{
-  struct GNUNET_TIME_Relative exp;
-
-  if (NULL != cp->destroy_task)
-  {
-    GNUNET_SCHEDULER_cancel (cp->destroy_task);
-    cp->destroy_task = NULL;
-  }
-  if (NULL != cp->t)
-    return; /* still relevant! */
-  if (NULL != cp->core_mq)
-    return; /* still relevant! */
-  if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
-    return; /* still relevant! */
-  if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap))
-  {
-    cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
-                                                     &drop_paths,
-                                                     cp);
-    return;
-  }
-  if (0 < cp->path_dll_length)
-    return; /* still relevant! */
-  if (NULL != cp->hello)
-  {
-    /* relevant only until HELLO expires */
-    exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration 
(cp->hello));
-    cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
-                                                     &destroy_peer,
-                                                     cp);
-    return;
-  }
-  cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
-                                                   &destroy_peer,
-                                                   cp);
-}
-
-
-/**
  * Add an entry to the DLL of all of the paths that this peer is on.
  *
  * @param cp peer to modify
@@ -532,6 +639,11 @@ GCP_path_entry_add (struct CadetPeer *cp,
                     struct CadetPeerPathEntry *entry,
                     unsigned int off)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Discovered that peer %s is on path %s at offset %u\n",
+       GCP_2s (cp),
+       GCPP_2s (entry->path),
+       off);
   if (off >= cp->path_dll_length)
   {
     unsigned int len = cp->path_dll_length;
@@ -554,6 +666,14 @@ GCP_path_entry_add (struct CadetPeer *cp,
     GCT_consider_path (cp->t,
                        entry->path,
                        off);
+
+  if ( (NULL != cp->search_h) &&
+       (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths) )
+  {
+    /* Now I have enough paths, stop search */
+    GCD_search_stop (cp->search_h);
+    cp->search_h = NULL;
+  }
 }
 
 
@@ -569,11 +689,22 @@ GCP_path_entry_remove (struct CadetPeer *cp,
                        struct CadetPeerPathEntry *entry,
                        unsigned int off)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Removing knowledge about peer %s beging on path %s at offset %u\n",
+       GCP_2s (cp),
+       GCPP_2s (entry->path),
+       off);
   GNUNET_CONTAINER_DLL_remove (cp->path_heads[off],
                                cp->path_tails[off],
                                entry);
   GNUNET_assert (0 < cp->num_paths);
   cp->num_paths--;
+  if ( (NULL == cp->core_mq) &&
+       (NULL != cp->t) &&
+       (NULL == cp->search_h) &&
+       (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
+    cp->search_h
+      = GCD_search (&cp->pid);
 }
 
 
@@ -599,10 +730,10 @@ GCP_attach_path (struct CadetPeer *cp,
   GNUNET_CONTAINER_HeapCostType root_desirability;
   struct GNUNET_CONTAINER_HeapNode *hn;
 
+  desirability = GCPP_get_desirability (path);
   if (GNUNET_NO == force)
   {
     /* FIXME: desirability is not yet initialized; tricky! */
-    desirability = GCPP_get_desirability (path);
     if (GNUNET_NO ==
         GNUNET_CONTAINER_heap_peek2 (cp->path_heap,
                                      (void **) &root,
@@ -614,12 +745,24 @@ GCP_attach_path (struct CadetPeer *cp,
 
     if ( (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) &&
          (desirability < root_desirability) )
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Decided to not attach path %p to peer %s due to undesirability\n",
+           GCPP_2s (path),
+           GCP_2s (cp));
       return NULL;
+    }
   }
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Attaching path %p to peer %s (%s)\n",
+       GCPP_2s (path),
+       GCP_2s (cp),
+       (GNUNET_NO == force) ? "desirable" : "forced");
+
   /* Yes, we'd like to add this path, add to our heap */
   hn = GNUNET_CONTAINER_heap_insert (cp->path_heap,
-                                     (void *) cp,
+                                     path,
                                      desirability);
 
   /* Consider maybe dropping other paths because of the new one */
@@ -662,6 +805,10 @@ GCP_detach_path (struct CadetPeer *cp,
                  struct CadetPeerPath *path,
                  struct GNUNET_CONTAINER_HeapNode *hn)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Detatching path %p from peer %s\n",
+       GCPP_2s (path),
+       GCP_2s (cp));
   GNUNET_assert (path ==
                  GNUNET_CONTAINER_heap_remove_node (hn));
 }
@@ -677,6 +824,10 @@ void
 GCP_add_connection (struct CadetPeer *cp,
                     struct CadetConnection *cc)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Adding connection %s to peer %s\n",
+       GCC_2s (cc),
+       GCP_2s (cp));
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONTAINER_multishortmap_put (cp->connections,
                                                      &GCC_get_id 
(cc)->connection_of_tunnel,
@@ -695,6 +846,10 @@ void
 GCP_remove_connection (struct CadetPeer *cp,
                        struct CadetConnection *cc)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Removing connection %s from peer %s\n",
+       GCC_2s (cc),
+       GCP_2s (cp));
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multishortmap_remove (cp->connections,
                                                         &GCC_get_id 
(cc)->connection_of_tunnel,
@@ -703,67 +858,6 @@ GCP_remove_connection (struct CadetPeer *cp,
 
 
 /**
- * This peer is now on more "active" duty, activate processes related to it.
- *
- * @param cp the more-active peer
- */
-static void
-consider_peer_activate (struct CadetPeer *cp)
-{
-  uint32_t strength;
-
-  if (NULL != cp->destroy_task)
-  {
-    /* It's active, do not destory! */
-    GNUNET_SCHEDULER_cancel (cp->destroy_task);
-    cp->destroy_task = NULL;
-  }
-  if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
-       (NULL == cp->t) )
-  {
-    /* We're just on a path or directly connected; don't bother too much */
-    if (NULL != cp->connectivity_suggestion)
-    {
-      GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
-      cp->connectivity_suggestion = NULL;
-    }
-    if (NULL != cp->search_h)
-    {
-      GCD_search_stop (cp->search_h);
-      cp->search_h = NULL;
-    }
-    return;
-  }
-  if (NULL == cp->core_mq)
-  {
-    /* Lacks direct connection, try to create one by querying the DHT */
-    if ( (NULL == cp->search_h) &&
-         (DESIRED_CONNECTIONS_PER_TUNNEL < cp->num_paths) )
-      cp->search_h
-        = GCD_search (&cp->pid);
-  }
-  else
-  {
-    /* Have direct connection, stop DHT search if active */
-    if (NULL != cp->search_h)
-    {
-      GCD_search_stop (cp->search_h);
-      cp->search_h = NULL;
-    }
-  }
-
-  /* If we have a tunnel, our urge for connections is much bigger */
-  strength = (NULL != cp->t) ? 32 : 1;
-  if (NULL != cp->connectivity_suggestion)
-    GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
-  cp->connectivity_suggestion
-    = GNUNET_ATS_connectivity_suggest (ats_ch,
-                                       &cp->pid,
-                                       strength);
-}
-
-
-/**
  * Retrieve the CadetPeer stucture associated with the
  * peer. Optionally create one and insert it in the appropriate
  * structures if the peer is not known yet.
@@ -796,6 +890,9 @@ GCP_get (const struct GNUNET_PeerIdentity *peer_id,
                                                     &cp->pid,
                                                     cp,
                                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Creating peer %s\n",
+       GCP_2s (cp));
   return cp;
 }
 
@@ -832,43 +929,60 @@ GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
 /**
  * Count the number of known paths toward the peer.
  *
- * @param peer Peer to get path info.
+ * @param cp Peer to get path info.
  * @return Number of known paths.
  */
 unsigned int
-GCP_count_paths (const struct CadetPeer *peer)
+GCP_count_paths (const struct CadetPeer *cp)
 {
-  return peer->num_paths;
+  return cp->num_paths;
 }
 
 
 /**
  * Iterate over the paths to a peer.
  *
- * @param peer Peer to get path info.
+ * @param cp Peer to get path info.
  * @param callback Function to call for every path.
  * @param callback_cls Closure for @a callback.
  * @return Number of iterated paths.
  */
 unsigned int
-GCP_iterate_paths (struct CadetPeer *peer,
+GCP_iterate_paths (struct CadetPeer *cp,
                    GCP_PathIterator callback,
                    void *callback_cls)
 {
   unsigned int ret = 0;
 
-  for (unsigned int i=0;i<peer->path_dll_length;i++)
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Iterating over paths to peer %s%s\n",
+       GCP_2s (cp),
+       (NULL == cp->core_mq) ? "" : " including direct link");
+  if (NULL != cp->core_mq)
+  {
+    struct CadetPeerPath *path;
+
+    path = GCPP_get_path_from_route (1,
+                                     &cp->pid);
+    ret++;
+    if (GNUNET_NO ==
+        callback (callback_cls,
+                  path,
+                  1))
+      return ret;
+  }
+  for (unsigned int i=0;i<cp->path_dll_length;i++)
   {
-    for (struct CadetPeerPathEntry *pe = peer->path_heads[i];
+    for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
          NULL != pe;
          pe = pe->next)
     {
+      ret++;
       if (GNUNET_NO ==
           callback (callback_cls,
                     pe->path,
                     i))
         return ret;
-      ret++;
     }
   }
   return ret;
@@ -876,26 +990,26 @@ GCP_iterate_paths (struct CadetPeer *peer,
 
 
 /**
- * Iterate over the paths to @a peer where
- * @a peer is at distance @a dist from us.
+ * Iterate over the paths to @a cp where
+ * @a cp is at distance @a dist from us.
  *
- * @param peer Peer to get path info.
- * @param dist desired distance of @a peer to us on the path
+ * @param cp Peer to get path info.
+ * @param dist desired distance of @a cp to us on the path
  * @param callback Function to call for every path.
  * @param callback_cls Closure for @a callback.
  * @return Number of iterated paths.
  */
 unsigned int
-GCP_iterate_paths_at (struct CadetPeer *peer,
+GCP_iterate_paths_at (struct CadetPeer *cp,
                       unsigned int dist,
                       GCP_PathIterator callback,
                       void *callback_cls)
 {
   unsigned int ret = 0;
 
-  if (dist<peer->path_dll_length)
+  if (dist <= cp->path_dll_length)
     return 0;
-  for (struct CadetPeerPathEntry *pe = peer->path_heads[dist];
+  for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
        NULL != pe;
        pe = pe->next)
   {
@@ -960,6 +1074,10 @@ GCP_set_hello (struct CadetPeer *cp,
 {
   struct GNUNET_HELLO_Message *mrg;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Got %u byte HELLO for peer %s\n",
+       (unsigned int) GNUNET_HELLO_size (hello),
+       GCP_2s (cp));
   if (NULL != cp->hello_offer)
   {
     GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
@@ -998,6 +1116,10 @@ void
 GCP_drop_tunnel (struct CadetPeer *cp,
                  struct CadetTunnel *t)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Dropping tunnel %s to peer %s\n",
+       GCT_2s (t),
+       GCP_2s (cp));
   GNUNET_assert (cp->t == t);
   cp->t = NULL;
   consider_peer_destroy (cp);
@@ -1039,6 +1161,10 @@ GCP_request_mq (struct CadetPeer *cp,
   GNUNET_CONTAINER_DLL_insert (cp->mqm_head,
                                cp->mqm_tail,
                                mqm);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Creating MQM %p for peer %s\n",
+       mqm,
+       GCP_2s (cp));
   if (NULL != cp->core_mq)
     cb (cb_cls,
         GNUNET_YES);
@@ -1058,6 +1184,11 @@ GCP_request_mq_cancel (struct GCP_MessageQueueManager 
*mqm,
 {
   struct CadetPeer *cp = mqm->cp;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Destroying MQM %p for peer %s%s\n",
+       mqm,
+       GCP_2s (cp),
+       (NULL == last_env) ? "" : " with last ditch transmission");
   if (NULL != mqm->env)
     GNUNET_MQ_discard (mqm->env);
   if (NULL != last_env)
@@ -1088,6 +1219,9 @@ void
 GCP_send_ooo (struct CadetPeer *cp,
               struct GNUNET_MQ_Envelope *env)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Sending message to %s out of management\n",
+       GCP_2s (cp));
   if (NULL == cp->core_mq)
   {
     GNUNET_MQ_discard (env);
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c 
b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 178577b46..d63da29d4 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -407,11 +407,10 @@ GCT_2s (const struct CadetTunnel *t)
 
   if (NULL == t)
     return "T(NULL)";
-
   GNUNET_snprintf (buf,
                    sizeof (buf),
                    "T(%s)",
-                   GCP_2s (t->destination));
+                   GNUNET_i2s (GCP_get_id (t->destination)));
   return buf;
 }
 
@@ -1174,6 +1173,27 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t,
 
 
 /**
+ * Our tunnel became ready for the first time, notify channels
+ * that have been waiting.
+ *
+ * @param cls our tunnel, not used
+ * @param key unique ID of the channel, not used
+ * @param value the `struct CadetChannel` to notify
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+notify_tunnel_up_cb (void *cls,
+                     uint32_t key,
+                     void *value)
+{
+  struct CadetChannel *ch = value;
+
+  GCCH_tunnel_up (ch);
+  return GNUNET_OK;
+}
+
+
+/**
  * Change the tunnel encryption state.
  * If the encryption state changes to OK, stop the rekey task.
  *
@@ -1201,6 +1221,14 @@ GCT_change_estate (struct CadetTunnel *t,
       GNUNET_SCHEDULER_cancel (t->kx_task);
       t->kx_task = NULL;
     }
+    if (CADET_TUNNEL_KEY_REKEY != old)
+    {
+      /* notify all channels that have been waiting */
+      GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
+                                               &notify_tunnel_up_cb,
+                                               t);
+    }
+
     /* FIXME: schedule rekey task! */
   }
 }
@@ -1454,7 +1482,9 @@ get_next_free_ctn (struct CadetTunnel *t)
 
 
 /**
- * Add a channel to a tunnel.
+ * Add a channel to a tunnel, and notify channel that we are ready
+ * for transmission if we are already up.  Otherwise that notification
+ * will be done later in #notify_tunnel_up_cb().
  *
  * @param t Tunnel.
  * @param ch Channel
@@ -1476,6 +1506,9 @@ GCT_add_channel (struct CadetTunnel *t,
               "Adding channel %s to tunnel %s\n",
               GCCH_2s (ch),
               GCT_2s (t));
+  if ( (CADET_TUNNEL_KEY_OK == t->estate) ||
+       (CADET_TUNNEL_KEY_REKEY == t->estate) )
+    GCCH_tunnel_up (ch);
   return ctn;
 }
 
@@ -1518,6 +1551,11 @@ destroy_tunnel (void *cls)
   }
   GNUNET_MST_destroy (t->mst);
   GNUNET_MQ_destroy (t->mq);
+  while (NULL != t->ax.skipped_head)
+    delete_skipped_key (t,
+                        t->ax.skipped_head);
+  GNUNET_assert (0 == t->ax.skipped);
+  GNUNET_free_non_null (t->ax.kx_0);
   GNUNET_free_non_null (t->ax.DHRs);
   GNUNET_free (t);
 }
@@ -1715,29 +1753,6 @@ trigger_transmissions (struct CadetTunnel *t)
 
 
 /**
- * Function called to maintain the connections underlying our tunnel.
- * Tries to maintain (incl. tear down) connections for the tunnel, and
- * if there is a significant change, may trigger transmissions.
- *
- * Basically, needs to check if there are connections that perform
- * badly, and if so eventually kill them and trigger a replacement.
- * The strategy is to open one more connection than
- * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the
- * least-performing one, and then inquire for new ones.
- *
- * @param cls the `struct CadetTunnel`
- */
-static void
-maintain_connections_cb (void *cls)
-{
-  struct CadetTunnel *t = cls;
-
-  t->maintain_connections_task = NULL;
-  GNUNET_break (0); // FIXME: implement!
-}
-
-
-/**
  * Consider using the path @a p for the tunnel @a t.
  * The tunnel destination is at offset @a off in path @a p.
  *
@@ -1765,7 +1780,13 @@ consider_path_cb (void *cls,
 
     ps = GCC_get_path (ct->cc);
     if (ps == path)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Ignoring duplicate path %s for tunnel %s.\n",
+                  GCPP_2s (path),
+                  GCT_2s (t));
       return GNUNET_YES; /* duplicate */
+    }
     min_length = GNUNET_MIN (min_length,
                              GCPP_get_length (ps));
     max_desire = GNUNET_MAX (max_desire,
@@ -1828,6 +1849,37 @@ consider_path_cb (void *cls,
 
 
 /**
+ * Function called to maintain the connections underlying our tunnel.
+ * Tries to maintain (incl. tear down) connections for the tunnel, and
+ * if there is a significant change, may trigger transmissions.
+ *
+ * Basically, needs to check if there are connections that perform
+ * badly, and if so eventually kill them and trigger a replacement.
+ * The strategy is to open one more connection than
+ * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the
+ * least-performing one, and then inquire for new ones.
+ *
+ * @param cls the `struct CadetTunnel`
+ */
+static void
+maintain_connections_cb (void *cls)
+{
+  struct CadetTunnel *t = cls;
+
+  t->maintain_connections_task = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Performing connection maintenance for tunnel %s.\n",
+              GCT_2s (t));
+
+  (void) GCP_iterate_paths (t->destination,
+                            &consider_path_cb,
+                            t);
+
+  GNUNET_break (0); // FIXME: implement!
+}
+
+
+/**
  * Consider using the path @a p for the tunnel @a t.
  * The tunnel destination is at offset @a off in path @a p.
  *
@@ -2138,11 +2190,9 @@ GCT_create_tunnel (struct CadetPeer *destination)
 
   t = GNUNET_new (struct CadetTunnel);
   new_ephemeral (t);
+  t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create ();
   t->destination = destination;
   t->channels = GNUNET_CONTAINER_multihashmap32_create (8);
-  (void) GCP_iterate_paths (destination,
-                            &consider_path_cb,
-                            t);
   t->maintain_connections_task
     = GNUNET_SCHEDULER_add_now (&maintain_connections_cb,
                                 t);
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index cf18b8a90..db19db4ed 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -599,11 +599,12 @@ tmt_rdy (void *cls, size_t size, void *buf)
  * @param channel connection to the other end
  * @param channel_ctx place to store local state associated with the channel
  * @param message the actual message
- * @return GNUNET_OK to keep the connection open,
- *         GNUNET_SYSERR to close it (signal serious error)
+ * @return #GNUNET_OK to keep the connection open,
+ *         #GNUNET_SYSERR to close it (signal serious error)
  */
-int
-data_callback (void *cls, struct GNUNET_CADET_Channel *channel,
+static int
+data_callback (void *cls,
+               struct GNUNET_CADET_Channel *channel,
                void **channel_ctx,
                const struct GNUNET_MessageHeader *message)
 {
@@ -764,10 +765,11 @@ static struct GNUNET_CADET_MessageHandler handlers[] = {
  *         (can be NULL -- that's not an error).
  */
 static void *
-incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel,
-                 const struct GNUNET_PeerIdentity *initiator,
-                 const struct GNUNET_HashCode *port,
-                 enum GNUNET_CADET_ChannelOption options)
+incoming_channel (void *cls,
+                  struct GNUNET_CADET_Channel *channel,
+                  const struct GNUNET_PeerIdentity *initiator,
+                  const struct GNUNET_HashCode *port,
+                  enum GNUNET_CADET_ChannelOption options)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Incoming channel from %s to peer %d:%s\n",
@@ -804,7 +806,8 @@ incoming_channel (void *cls, struct GNUNET_CADET_Channel 
*channel,
  *                   with the channel is stored
  */
 static void
-channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel,
+channel_cleaner (void *cls,
+                 const struct GNUNET_CADET_Channel *channel,
                  void *channel_ctx)
 {
   long i = (long) cls;
@@ -857,8 +860,8 @@ do_test (void *cls)
   enum GNUNET_CADET_ChannelOption flags;
 
   test_task = NULL;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "do_test\n");
-
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "do_test\n");
   if (NULL != disconnect_task)
   {
     GNUNET_SCHEDULER_cancel (disconnect_task);
@@ -872,20 +875,27 @@ do_test (void *cls)
     flags |= GNUNET_CADET_OPTION_RELIABLE;
   }
 
-  ch = GNUNET_CADET_channel_create (h1, NULL, p_id[1], &port, flags);
+  ch = GNUNET_CADET_channel_create (h1,
+                                    NULL,
+                                    p_id[1],
+                                    &port,
+                                    flags);
 
-  disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
-                                                  &gather_stats_and_exit,
-                                                  (void *) __LINE__);
+  disconnect_task
+    = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
+                                    &gather_stats_and_exit,
+                                    (void *) __LINE__);
   if (KEEPALIVE == test)
     return; /* Don't send any data. */
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending data initializer...\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending data initializer...\n");
   data_received = 0;
   data_sent = 0;
   ack_received = 0;
   ack_sent = 0;
-  th = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO,
+  th = GNUNET_CADET_notify_transmit_ready (ch,
+                                           GNUNET_NO,
                                            GNUNET_TIME_UNIT_FOREVER_REL,
                                            size_payload + 1000,
                                            &tmt_rdy, (void *) 0L);
@@ -909,24 +919,31 @@ pi_cb (void *cls,
 {
   long i = (long) cls;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "id callback for %ld\n", i);
 
-  if (NULL == pinfo || NULL != emsg)
+  if ( (NULL == pinfo) ||
+       (NULL != emsg) )
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "pi_cb: %s\n", emsg);
     abort_test (__LINE__);
     return;
   }
   p_id[i] = pinfo->result.id;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  id: %s\n", GNUNET_i2s (p_id[i]));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "  id: %s\n", GNUNET_i2s (p_id[i]));
   p_ids++;
   if (p_ids < 2)
     return;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got all IDs, starting test\n");
   test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
-                                            &do_test, NULL);
+                                            &do_test,
+                                            NULL);
 }
 
+
 /**
  * test main: start test when all peers are connected
  *
diff --git a/src/cadet/test_cadet.conf b/src/cadet/test_cadet.conf
index e0c00858e..b6e6c6ae3 100644
--- a/src/cadet/test_cadet.conf
+++ b/src/cadet/test_cadet.conf
@@ -32,6 +32,8 @@ NEIGHBOUR_LIMIT = 50
 #MANIPULATE_DELAY_IN = 10 ms
 #MANIPULATE_DELAY_OUT = 10 ms
 
+[nat]
+ENABLE_UPNP = NO
 
 [ats]
 # Network specific inbound/outbound quotas
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 9ad604711..fdcae66fa 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -614,6 +614,22 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid);
  * @ingroup logging
  * Convert a peer identity to a string (for printing debug messages).
  * This is one of the very few calls in the entire API that is
+ * NOT reentrant!  Identical to #GNUNET_i2s(), except that another
+ * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be
+ * used within the same log statement.
+ *
+ * @param pid the peer identity
+ * @return string form of the pid; will be overwritten by next
+ *         call to #GNUNET_i2s().
+ */
+const char *
+GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid);
+
+
+/**
+ * @ingroup logging
+ * Convert a peer identity to a string (for printing debug messages).
+ * This is one of the very few calls in the entire API that is
  * NOT reentrant!
  *
  * @param pid the peer identity
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index ce229826e..7d5b50b8b 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -1164,7 +1164,7 @@ GNUNET_h2s (const struct GNUNET_HashCode * hc)
 const char *
 GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc)
 {
-  static char buf[32];
+  static char buf[64];
 
   GNUNET_STRINGS_data_to_string (shc,
                                  sizeof (*shc),
@@ -1209,8 +1209,39 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid)
   static char buf[256];
   char *ret;
 
+  if (NULL == pid)
+    return "NULL";
   ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
-  strcpy (buf, ret);
+  strcpy (buf,
+          ret);
+  GNUNET_free (ret);
+  buf[4] = '\0';
+  return buf;
+}
+
+
+/**
+ * Convert a peer identity to a string (for printing debug messages).
+ * This is one of the very few calls in the entire API that is
+ * NOT reentrant!  Identical to #GNUNET_i2s(), except that another
+ * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be
+ * used within the same log statement.
+ *
+ * @param pid the peer identity
+ * @return string form of the pid; will be overwritten by next
+ *         call to #GNUNET_i2s.
+ */
+const char *
+GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid)
+{
+  static char buf[256];
+  char *ret;
+
+  if (NULL == pid)
+    return "NULL";
+  ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&pid->public_key);
+  strcpy (buf,
+          ret);
   GNUNET_free (ret);
   buf[4] = '\0';
   return buf;
diff --git a/src/util/strings.c b/src/util/strings.c
index 46eab856f..2b51d3e52 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -1354,7 +1354,7 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
 
 
 /**
- * Parse an address given as a string into a 
+ * Parse an address given as a string into a
  * `struct sockaddr`.
  *
  * @param addr the address
@@ -1372,7 +1372,7 @@ GNUNET_STRINGS_parse_socket_addr (const char *addr,
   *af = AF_UNSPEC;
   if ('[' == *addr)
   {
-    /* IPv6 */    
+    /* IPv6 */
     *sa = GNUNET_malloc (sizeof (struct sockaddr_in6));
     if (GNUNET_OK !=
        GNUNET_STRINGS_to_address_ipv6 (cp,

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



reply via email to

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