(no commit message)
[oweals/gnunet.git] / src / transport / gnunet-service-transport.c
index de25666fa1d9a270482b15ebbcfa1fbf5b4c85a7..e2168b9709aa87f8ad381ae3bfa4a1eb6fda3a49 100644 (file)
 #include "gnunet_protocols.h"
 #include "gnunet_service_lib.h"
 #include "gnunet_signatures.h"
-#include "plugin_transport.h"
+#include "gnunet_transport_plugin.h"
 #include "transport.h"
 
-#define DEBUG_BLACKLIST GNUNET_NO
+#define DEBUG_BLACKLIST GNUNET_YES
 
-#define DEBUG_PING_PONG GNUNET_NO
+#define DEBUG_PING_PONG GNUNET_YES
 
-#define DEBUG_TRANSPORT_HELLO GNUNET_NO
+#define DEBUG_TRANSPORT_HELLO GNUNET_YES
 
 /**
  * Should we do some additional checks (to validate behavior
@@ -842,11 +842,6 @@ static struct GNUNET_PeerIdentity my_identity;
  */
 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
 
-/**
- * Our scheduler.
- */
-struct GNUNET_SCHEDULER_Handle *sched;
-
 /**
  * Our configuration.
  */
@@ -1496,7 +1491,7 @@ find_ready_address(struct NeighbourList *neighbour)
       addresses = head->addresses;
       while (addresses != NULL)
         {
-          if ( (addresses->timeout.value < now.value) &&
+          if ( (addresses->timeout.abs_value < now.abs_value) &&
               (addresses->connected == GNUNET_YES) )
             {
 #if DEBUG_TRANSPORT
@@ -1528,7 +1523,7 @@ find_ready_address(struct NeighbourList *neighbour)
                        addresses->in_transmit,
                        addresses->validated,
                        addresses->connect_attempts,
-                       (unsigned long long) addresses->timeout.value,
+                       (unsigned long long) addresses->timeout.abs_value,
                        (unsigned int) addresses->distance);
 #endif
           if ( ( (best_address == NULL) ||
@@ -1536,7 +1531,7 @@ find_ready_address(struct NeighbourList *neighbour)
                 (best_address->connected == GNUNET_NO) ) &&
               (addresses->in_transmit == GNUNET_NO) &&
               ( (best_address == NULL) ||
-                (addresses->latency.value < best_address->latency.value)) )
+                (addresses->latency.rel_value < best_address->latency.rel_value)) )
            best_address = addresses;
          /* FIXME: also give lower-latency addresses that are not
             connected a chance some times... */
@@ -1554,7 +1549,7 @@ find_ready_address(struct NeighbourList *neighbour)
                       best_address->addr,
                       best_address->addrlen)
                  : "<inbound>",
-                  best_address->latency.value);
+                  best_address->latency.rel_value);
 #endif
     }
   else
@@ -1627,7 +1622,7 @@ try_transmission_to_peer (struct NeighbourList *neighbour)
                                1,
                                GNUNET_NO);
       timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout);
-      if (timeout.value == 0)
+      if (timeout.rel_value == 0)
        {
 #if DEBUG_TRANSPORT
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1656,10 +1651,8 @@ try_transmission_to_peer (struct NeighbourList *neighbour)
                                1,
                                GNUNET_NO);
       if (neighbour->retry_task != GNUNET_SCHEDULER_NO_TASK)
-       GNUNET_SCHEDULER_cancel (sched,
-                                neighbour->retry_task);
-      neighbour->retry_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                                           timeout,
+       GNUNET_SCHEDULER_cancel (neighbour->retry_task);
+      neighbour->retry_task = GNUNET_SCHEDULER_add_delayed (timeout,
                                                            &retry_transmission_task,
                                                            neighbour);
 #if DEBUG_TRANSPORT
@@ -1667,7 +1660,7 @@ try_transmission_to_peer (struct NeighbourList *neighbour)
                  "No validated destination address available to transmit message of size %u to peer `%4s', will wait %llums to find an address.\n",
                  mq->message_buf_size,
                  GNUNET_i2s (&mq->neighbour_id),
-                 timeout.value);
+                 timeout.rel_value);
 #endif
       /* FIXME: might want to trigger peerinfo lookup here
         (unless that's already pending...) */
@@ -1912,7 +1905,8 @@ expire_address_task (void *cls,
  *        expired
  */
 static void
-update_addresses (struct TransportPlugin *plugin, int fresh)
+update_addresses (struct TransportPlugin *plugin, 
+                 int fresh)
 {
   static struct GNUNET_TIME_Absolute last_update;
   struct GNUNET_TIME_Relative min_remaining;
@@ -1924,17 +1918,17 @@ update_addresses (struct TransportPlugin *plugin, int fresh)
   int expired;
 
   if (plugin->address_update_task != GNUNET_SCHEDULER_NO_TASK)
-    GNUNET_SCHEDULER_cancel (plugin->env.sched, plugin->address_update_task);
+    GNUNET_SCHEDULER_cancel (plugin->address_update_task);
   plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
   now = GNUNET_TIME_absolute_get ();
   min_remaining = GNUNET_TIME_UNIT_FOREVER_REL;
-  expired = (GNUNET_TIME_absolute_get_duration (last_update).value > (HELLO_ADDRESS_EXPIRATION.value / 4));
+  expired = (GNUNET_TIME_absolute_get_duration (last_update).rel_value > (HELLO_ADDRESS_EXPIRATION.rel_value / 4));
   prev = NULL;
   pos = plugin->addresses;
   while (pos != NULL)
     {
       next = pos->next;
-      if (pos->expires.value < now.value)
+      if (pos->expires.abs_value < now.abs_value)
         {
           expired = GNUNET_YES;
           if (prev == NULL)
@@ -1946,7 +1940,7 @@ update_addresses (struct TransportPlugin *plugin, int fresh)
       else
         {
           remaining = GNUNET_TIME_absolute_get_remaining (pos->expires);
-          if (remaining.value < min_remaining.value)
+          if (remaining.rel_value < min_remaining.rel_value)
             min_remaining = remaining;
           prev = pos;
         }
@@ -1962,8 +1956,7 @@ update_addresses (struct TransportPlugin *plugin, int fresh)
                                            GNUNET_TIME_relative_divide (HELLO_ADDRESS_EXPIRATION,
                                                                         2));
   plugin->address_update_task
-    = GNUNET_SCHEDULER_add_delayed (plugin->env.sched,
-                                   min_remaining,
+    = GNUNET_SCHEDULER_add_delayed (min_remaining,
                                    &expire_address_task, plugin);
 }
 
@@ -2126,8 +2119,7 @@ plugin_env_session_end  (void *cls,
     prev->next = pos->next;
   if (GNUNET_SCHEDULER_NO_TASK != pos->revalidate_task)
     {
-      GNUNET_SCHEDULER_cancel (sched,
-                              pos->revalidate_task);
+      GNUNET_SCHEDULER_cancel (pos->revalidate_task);
       pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
     }
   GNUNET_free (pos);
@@ -2190,9 +2182,9 @@ plugin_env_notify_address (void *cls,
   while (al != NULL)
     {
       if ((addrlen == al->addrlen) && (0 == memcmp (addr, &al[1], addrlen)))
-        {
-          if (al->expires.value < abex.value)
-            al->expires = abex;
+        {            
+         al->expires = abex;
+         update_addresses (p, GNUNET_NO);
           return;
         }
       al = al->next;
@@ -2518,7 +2510,7 @@ abort_validation (void *cls,
   struct ValidationEntry *va = value;
 
   if (GNUNET_SCHEDULER_NO_TASK != va->timeout_task)
-    GNUNET_SCHEDULER_cancel (sched, va->timeout_task);
+    GNUNET_SCHEDULER_cancel (va->timeout_task);
   GNUNET_free (va->transport_name);
   if (va->chvc != NULL)
     {
@@ -2625,13 +2617,13 @@ add_to_foreign_address_list (void *cls,
   fal = find_peer_address (n, tname, NULL, addr, addrlen);
   if (fal == NULL)
     {
-#if DEBUG_TRANSPORT
+#if DEBUG_TRANSPORT_HELLO
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Adding address `%s' (%s) for peer `%4s' due to PEERINFO data for %llums.\n",
                  a2s (tname, addr, addrlen),
                  tname,
                  GNUNET_i2s (&n->id),
-                 expiration.value);
+                 expiration.abs_value);
 #endif
       fal = add_peer_address (n, tname, NULL, addr, addrlen);
       if (fal == NULL)
@@ -2656,7 +2648,7 @@ add_to_foreign_address_list (void *cls,
     }
   if (fal == NULL)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  "Failed to add new address for `%4s'\n",
                  GNUNET_i2s (&n->id));
       return GNUNET_OK;
@@ -2776,13 +2768,12 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
     }
   n->latency = GNUNET_TIME_UNIT_FOREVER_REL;
   n->distance = -1;
-  n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                                  GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
+  n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                                   &neighbour_timeout_task, n);
   if (do_hello)
     {
       GNUNET_STATISTICS_update (stats,
-                                gettext_noop ("# peerinfo iterate requests"),
+                                gettext_noop ("# peerinfo new neighbor iterate requests"),
                                 1,
                                 GNUNET_NO);
       GNUNET_STATISTICS_update (stats,
@@ -2792,6 +2783,11 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
       n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer,
                                          GNUNET_TIME_UNIT_FOREVER_REL,
                                          &add_hello_for_peer, n);
+
+      GNUNET_STATISTICS_update (stats,
+                                gettext_noop ("# HELLO's sent to new neighbors"),
+                                1,
+                                GNUNET_NO);
       transmit_to_peer (NULL, NULL, 0,
                        HELLO_ADDRESS_EXPIRATION,
                        (const char *) our_hello, GNUNET_HELLO_size(our_hello),
@@ -2949,8 +2945,7 @@ transmit_blacklist_message (void *cls,
   if (size == 0)
     {
       GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK);
-      bc->task = GNUNET_SCHEDULER_add_now (sched,
-                                          &do_blacklist_check,
+      bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
                                           bc);
       return 0;
     }
@@ -3023,13 +3018,16 @@ setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer,
   n = find_neighbour(peer);
   if (n != NULL)
     {
-      cont (cont_cls, n);
+      if (cont != NULL)
+        cont (cont_cls, n);
       return;
     }
   if (bl_head == NULL)
     {
-      cont (cont_cls,
-           setup_new_neighbour (peer, do_hello));
+      if (cont != NULL)
+        cont (cont_cls, setup_new_neighbour (peer, do_hello));
+      else
+        setup_new_neighbour(peer, do_hello);
       return;
     }
   bc = GNUNET_malloc (sizeof (struct BlacklistCheck));
@@ -3039,8 +3037,7 @@ setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer,
   bc->cont = cont;
   bc->cont_cls = cont_cls;
   bc->bl_pos = bl_head;
-  bc->task = GNUNET_SCHEDULER_add_now (sched,
-                                      &do_blacklist_check,
+  bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
                                       bc);
 }
 
@@ -3112,8 +3109,7 @@ handle_blacklist_init (void *cls,
       bc->bl_pos = bl;
       if (n == neighbours) /* all would wait for the same client, no need to
                              create more than just the first task right now */
-       bc->task = GNUNET_SCHEDULER_add_now (sched,
-                                            &do_blacklist_check,
+       bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
                                             bc);
       n = n->next;
     }
@@ -3156,8 +3152,7 @@ handle_blacklist_reply (void *cls,
   else
     {
       bc->bl_pos = bc->bl_pos->next;
-      bc->task = GNUNET_SCHEDULER_add_now (sched,
-                                          &do_blacklist_check,
+      bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
                                           bc);
     }
   /* check if any other bc's are waiting for this blacklister */
@@ -3166,8 +3161,7 @@ handle_blacklist_reply (void *cls,
     {
       if ( (bc->bl_pos == bl) &&
           (GNUNET_SCHEDULER_NO_TASK == bc->task) )
-       bc->task = GNUNET_SCHEDULER_add_now (sched,
-                                            &do_blacklist_check,
+       bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
                                             bc);
       bc = bc->next;
     }
@@ -3236,7 +3230,7 @@ send_periodic_ping (void *cls,
     }
   va = GNUNET_malloc (sizeof (struct ValidationEntry) + peer_address->addrlen);
   va->transport_name = GNUNET_strdup (tp->short_name);
-  va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+  va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
                                             UINT_MAX);
   va->send_time = GNUNET_TIME_absolute_get();
   va->session = peer_address->session;
@@ -3250,16 +3244,21 @@ send_periodic_ping (void *cls,
         &neighbour->publicKey,
         sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
 
-  va->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                                   HELLO_VERIFICATION_TIMEOUT,
+  va->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT,
                                                    &timeout_hello_validation,
                                                    va);
   GNUNET_CONTAINER_multihashmap_put (validation_map,
                                      &neighbour->id.hashPubKey,
                                      va,
                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-  hello_size = GNUNET_HELLO_size(our_hello);
+
+  if (peer_address->validated != GNUNET_YES)
+    hello_size = GNUNET_HELLO_size(our_hello);
+  else
+    hello_size = 0;
+
   tsize = sizeof(struct TransportPingMessage) + hello_size;
+
   if (peer_address->addr != NULL)
     {
       slen = strlen (tp->short_name) + 1;
@@ -3273,7 +3272,11 @@ send_periodic_ping (void *cls,
   ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
   ping.challenge = htonl(va->challenge);
   memcpy(&ping.target, &neighbour->id, sizeof(struct GNUNET_PeerIdentity));
-  memcpy(message_buf, our_hello, hello_size);
+  if (peer_address->validated != GNUNET_YES)
+    {
+      memcpy(message_buf, our_hello, hello_size);
+    }
+
   if (peer_address->addr != NULL)
     {
       ping.header.size = htons(sizeof(struct TransportPingMessage) +
@@ -3290,6 +3293,7 @@ send_periodic_ping (void *cls,
     {
       ping.header.size = htons(sizeof(struct TransportPingMessage));
     }
+
   memcpy(&message_buf[hello_size],
          &ping,
          sizeof(struct TransportPingMessage));
@@ -3307,6 +3311,16 @@ send_periodic_ping (void *cls,
               "HELLO", hello_size,
               "PING");
 #endif
+  if (peer_address->validated != GNUNET_YES)
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop ("# PING with HELLO messages sent"),
+                              1,
+                              GNUNET_NO);
+  else
+    GNUNET_STATISTICS_update (stats,
+                              gettext_noop ("# PING without HELLO messages sent"),
+                              1,
+                              GNUNET_NO);
   GNUNET_STATISTICS_update (stats,
                            gettext_noop ("# PING messages sent for re-validation"),
                            1,
@@ -3335,7 +3349,7 @@ schedule_next_ping (struct ForeignAddressList *fal)
   if (fal->revalidate_task != GNUNET_SCHEDULER_NO_TASK)
     return;
   delay = GNUNET_TIME_absolute_get_remaining (fal->expires);
-  delay.value /= 2; /* do before expiration */
+  delay.rel_value /= 2; /* do before expiration */
   delay = GNUNET_TIME_relative_min (delay,
                                    LATENCY_EVALUATION_MAX_DELAY);
   if (GNUNET_YES != fal->estimated)
@@ -3354,9 +3368,8 @@ schedule_next_ping (struct ForeignAddressList *fal)
   delay = GNUNET_TIME_relative_max (delay,
                                    GNUNET_TIME_UNIT_SECONDS);
   /* randomize a bit (to avoid doing all at the same time) */
-  delay.value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000);
-  fal->revalidate_task = GNUNET_SCHEDULER_add_delayed(sched,
-                                                     delay,
+  delay.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000);
+  fal->revalidate_task = GNUNET_SCHEDULER_add_delayed(delay,
                                                      &send_periodic_ping,
                                                      fal);
 }
@@ -3394,7 +3407,7 @@ handle_payload_message (const struct GNUNET_MessageHeader *message,
     }
 
 #if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received message of type %u and size %u from `%4s', sending to all clients.\n",
              ntohs (message->type),
              ntohs (message->size),
@@ -3485,7 +3498,7 @@ check_pending_validation (void *cls,
     }
   addr = (const char*) &pong[1];
   slen = strlen (ve->transport_name) + 1;
-  if ( (ps - sizeof (struct TransportPongMessage) != ve->addrlen + slen) ||
+  if ( (ps - sizeof (struct TransportPongMessage) < slen) ||
        (ve->challenge != challenge) ||
        (addr[slen-1] != '\0') ||
        (0 != strcmp (addr, ve->transport_name)) ||
@@ -3493,7 +3506,7 @@ check_pending_validation (void *cls,
        != sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
        sizeof (uint32_t) +
        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
-       sizeof (struct GNUNET_PeerIdentity) + ve->addrlen + slen) )
+       sizeof (struct GNUNET_PeerIdentity) + ps - sizeof (struct TransportPongMessage)) )
     {
       return GNUNET_YES;
     }
@@ -3537,18 +3550,18 @@ check_pending_validation (void *cls,
 #endif
       break;
     case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING:
-      if (ve->addrlen != 0)
-        {
-          return GNUNET_YES; /* different entry, keep trying */
-        }
-      if ( (0 != memcmp (&pong->pid,
+      if (0 != memcmp (&pong->pid,
                         &my_identity,
-                        sizeof (struct GNUNET_PeerIdentity))) ||
-          (ve->addrlen != 0) )
+                        sizeof (struct GNUNET_PeerIdentity)))
        {
          GNUNET_break_op (0);
          return GNUNET_NO;
        }
+      if (ve->addrlen != 0)
+        {
+          /* must have been for a different validation entry */
+          return GNUNET_YES;
+        }
       tp = find_transport (ve->transport_name);
       if (tp == NULL)
        {
@@ -3598,7 +3611,7 @@ check_pending_validation (void *cls,
       GNUNET_break_op (0);
       return GNUNET_NO;
     }
-  if (GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (pong->expiration)).value == 0)
+  if (GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  _("Received expired signature.  Check system time.\n"));
@@ -3643,10 +3656,10 @@ check_pending_validation (void *cls,
                                GNUNET_NO);
       fal->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
       schedule_next_ping (fal);
-      if (n->latency.value == GNUNET_TIME_UNIT_FOREVER_REL.value)
+      if (n->latency.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
        n->latency = fal->latency;
       else
-       n->latency.value = (fal->latency.value + n->latency.value) / 2;
+       n->latency.rel_value = (fal->latency.rel_value + n->latency.rel_value) / 2;
 
       n->distance = fal->distance;
       if (GNUNET_NO == n->received_pong)
@@ -3662,8 +3675,7 @@ check_pending_validation (void *cls,
        }
       if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
        {
-         GNUNET_SCHEDULER_cancel (sched,
-                                  n->retry_task);
+         GNUNET_SCHEDULER_cancel (n->retry_task);
          n->retry_task = GNUNET_SCHEDULER_NO_TASK;
          try_transmission_to_peer (n);
        }
@@ -3944,7 +3956,7 @@ run_validation (void *cls,
   va->chvc = chvc;
   chvc->ve_count++;
   va->transport_name = GNUNET_strdup (tname);
-  va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+  va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
                                             UINT_MAX);
   va->send_time = GNUNET_TIME_absolute_get();
   va->addr = (const void*) &va[1];
@@ -3952,8 +3964,7 @@ run_validation (void *cls,
   va->addrlen = addrlen;
   GNUNET_HELLO_get_key (chvc->hello,
                        &va->publicKey);
-  va->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                                  HELLO_VERIFICATION_TIMEOUT,
+  va->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT,
                                                   &timeout_hello_validation,
                                                   va);
   GNUNET_CONTAINER_multihashmap_put (validation_map,
@@ -4006,7 +4017,7 @@ check_hello_validated (void *cls,
                                             NULL);
          GNUNET_PEERINFO_add_peer (peerinfo, plain_hello);
          GNUNET_free (plain_hello);
-#if DEBUG_TRANSPORT
+#if DEBUG_TRANSPORT_HELLO
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                      "PEERINFO had no `%s' message for peer `%4s', full validation needed.\n",
                      "HELLO",
@@ -4040,7 +4051,7 @@ check_hello_validated (void *cls,
     }
   if (h == NULL)
     return;
-#if DEBUG_TRANSPORT
+#if DEBUG_TRANSPORT_HELLO
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "PEERINFO had `%s' message for peer `%4s', validating only new addresses.\n",
              "HELLO",
@@ -4050,6 +4061,11 @@ check_hello_validated (void *cls,
   n = find_neighbour (peer);
   if (n != NULL)
     {
+#if DEBUG_TRANSPORT_HELLO
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Calling hello_iterate_addresses for %s!\n",
+                  GNUNET_i2s (peer));
+#endif
       GNUNET_HELLO_iterate_addresses (h,
                                      GNUNET_NO,
                                      &add_to_foreign_address_list,
@@ -4058,6 +4074,11 @@ check_hello_validated (void *cls,
     }
   else
     {
+#if DEBUG_TRANSPORT_HELLO
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "No existing neighbor record for %s!\n",
+                  GNUNET_i2s (peer));
+#endif
       GNUNET_STATISTICS_update (stats,
                                gettext_noop ("# no existing neighbour record (validating HELLO)"),
                                1,
@@ -4091,7 +4112,7 @@ process_hello (struct TransportPlugin *plugin,
   const struct GNUNET_HELLO_Message *hello;
   struct CheckHelloValidatedContext *chvc;
   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
-#if DEBUG_TRANSPORT_HELLO
+#if DEBUG_TRANSPORT_HELLO > 2
   char *my_id;
 #endif
   hsize = ntohs (message->size);
@@ -4107,8 +4128,7 @@ process_hello (struct TransportPlugin *plugin,
                            GNUNET_NO);
 
   /* first, check if load is too high */
-  if (GNUNET_SCHEDULER_get_load (sched,
-                                GNUNET_SCHEDULER_PRIORITY_BACKGROUND) > MAX_HELLO_LOAD)
+  if (GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_BACKGROUND) > MAX_HELLO_LOAD)
     {
       GNUNET_STATISTICS_update (stats,
                                gettext_noop ("# HELLOs ignored due to high load"),
@@ -4139,6 +4159,13 @@ process_hello (struct TransportPlugin *plugin,
                       sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                       &target.hashPubKey);
 
+#if DEBUG_TRANSPORT_HELLO
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received `%s' message for `%4s'\n",
+              "HELLO",
+              GNUNET_i2s (&target));
+#endif
+
   if (0 == memcmp (&my_identity,
                   &target,
                   sizeof (struct GNUNET_PeerIdentity)))
@@ -4154,9 +4181,9 @@ process_hello (struct TransportPlugin *plugin,
     {
       if (GNUNET_HELLO_equals (hello,
                               chvc->hello,
-                              GNUNET_TIME_absolute_get ()).value > 0)
+                              GNUNET_TIME_absolute_get ()).abs_value > 0)
        {
-#if DEBUG_TRANSPORT_HELLO
+#if DEBUG_TRANSPORT_HELLO > 2
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                      "Received duplicate `%s' message for `%4s'; ignored\n",
                      "HELLO",
@@ -4169,7 +4196,17 @@ process_hello (struct TransportPlugin *plugin,
                                   GNUNET_HELLO_size(hello)));
       chvc = chvc->next;
     }
-#if DEBUG_TRANSPORT_HELLO
+
+#if BREAK_TESTS
+  struct NeighbourList *temp_neighbor = find_neighbour(&target);
+  if ((NULL != temp_neighbor))
+    {
+      fprintf(stderr, "Already know peer, ignoring hello\n");
+      return GNUNET_OK;
+    }
+#endif
+
+#if DEBUG_TRANSPORT_HELLO > 2
   if (plugin != NULL)
     {
       my_id = GNUNET_strdup(GNUNET_i2s(plugin->env.my_identity));
@@ -4193,7 +4230,7 @@ process_hello (struct TransportPlugin *plugin,
   /* finally, check if HELLO was previously validated
      (continuation will then schedule actual validation) */
   GNUNET_STATISTICS_update (stats,
-                            gettext_noop ("# peerinfo iterate requests"),
+                            gettext_noop ("# peerinfo process hello iterate requests"),
                             1,
                             GNUNET_NO);
   GNUNET_STATISTICS_update (stats,
@@ -4295,8 +4332,7 @@ disconnect_neighbour (struct NeighbourList *n, int check)
                                      GNUNET_NO);
          if (GNUNET_SCHEDULER_NO_TASK != peer_pos->revalidate_task)
            {
-             GNUNET_SCHEDULER_cancel (sched,
-                                      peer_pos->revalidate_task);
+             GNUNET_SCHEDULER_cancel (peer_pos->revalidate_task);
              peer_pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
            }
           GNUNET_free(peer_pos);
@@ -4325,12 +4361,12 @@ disconnect_neighbour (struct NeighbourList *n, int check)
     }
   if (n->timeout_task != GNUNET_SCHEDULER_NO_TASK)
     {
-      GNUNET_SCHEDULER_cancel (sched, n->timeout_task);
+      GNUNET_SCHEDULER_cancel (n->timeout_task);
       n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
     }
   if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
     {
-      GNUNET_SCHEDULER_cancel (sched, n->retry_task);
+      GNUNET_SCHEDULER_cancel (n->retry_task);
       n->retry_task = GNUNET_SCHEDULER_NO_TASK;
     }
   if (n->piter != NULL)
@@ -4387,8 +4423,14 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
                    sizeof (struct GNUNET_PeerIdentity)))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("Received `%s' message not destined for me!\n"),
-                 "PING");
+                  _("Received `%s' message from `%s' destined for `%s' which is not me!\n"),
+                 "PING",
+                 (sender_address != NULL)
+                 ? a2s (plugin->short_name,
+                        (const struct sockaddr *)sender_address,
+                        sender_address_len)
+                 : "<inbound>",
+                 GNUNET_i2s (&ping->target));
       return GNUNET_SYSERR;
     }
 #if DEBUG_PING_PONG
@@ -4438,7 +4480,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
       memcpy (&((char*)&pong[1])[slen],
              sender_address,
              sender_address_len);
-      if (GNUNET_TIME_absolute_get_remaining (session_header->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4)
+      if (GNUNET_TIME_absolute_get_remaining (session_header->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4)
        {
          /* create / update cached sig */
 #if DEBUG_TRANSPORT
@@ -4506,7 +4548,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
       memcpy (&pong[1], plugin->short_name, slen);
       memcpy (&((char*)&pong[1])[slen], addr, alen);
       if ( (oal != NULL) &&
-          (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4) )
+          (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4) )
        {
          /* create / update cached sig */
 #if DEBUG_TRANSPORT
@@ -4616,7 +4658,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
  * @param session identifier used for this session (can be NULL)
  * @param sender_address binary address of the sender (if observed)
  * @param sender_address_len number of bytes in sender_address
- * @return how long the plugin should wait until receiving more data
+ * @return how long in ms the plugin should wait until receiving more data
  *         (plugins that do not support this, can ignore the return value)
  */
 static struct GNUNET_TIME_Relative
@@ -4674,11 +4716,9 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
       n->peer_timeout =
        GNUNET_TIME_relative_to_absolute
        (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
-      GNUNET_SCHEDULER_cancel (sched,
-                              n->timeout_task);
+      GNUNET_SCHEDULER_cancel (n->timeout_task);
       n->timeout_task =
-       GNUNET_SCHEDULER_add_delayed (sched,
-                                     GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
+       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                      &neighbour_timeout_task, n);
       if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD)
        {
@@ -4724,16 +4764,16 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
        }
     }
   ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0);
-  if (ret.value > 0)
+  if (ret.rel_value > 0)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Throttling read (%llu bytes excess at %u b/s), waiting %llums before reading more.\n",
                  (unsigned long long) n->in_tracker.consumption_since_last_update__,
                  (unsigned int) n->in_tracker.available_bytes_per_s__,
-                 (unsigned long long) ret.value);
+                 (unsigned long long) ret.rel_value);
       GNUNET_STATISTICS_update (stats,
                                gettext_noop ("# ms throttling suggested"),
-                               (int64_t) ret.value,
+                               (int64_t) ret.rel_value,
                                GNUNET_NO);
     }
   return ret;
@@ -4932,13 +4972,13 @@ handle_send (void *cls,
   obm = (const struct OutboundMessage *) message;
   obmm = (const struct GNUNET_MessageHeader *) &obm[1];
   msize = size - sizeof (struct OutboundMessage);
-#if DEBUG_TRANSPORT
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received `%s' request from client with target `%4s' and message of type %u and size %u\n",
               "SEND", GNUNET_i2s (&obm->peer),
               ntohs (obmm->type),
               msize);
-#endif
+
   tcmc = GNUNET_malloc (sizeof (struct TransmitClientMessageContext) + msize);
   tcmc->client = client;
   tcmc->priority = ntohl (obm->priority);
@@ -4953,6 +4993,31 @@ handle_send (void *cls,
 }
 
 
+/**
+ * Handle request connect message
+ *
+ * @param cls closure (always NULL)
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_request_connect (void *cls,
+                        struct GNUNET_SERVER_Client *client,
+                        const struct GNUNET_MessageHeader *message)
+{
+  const struct TransportRequestConnectMessage *trcm =
+    (const struct TransportRequestConnectMessage *) message;
+
+  GNUNET_STATISTICS_update (stats,
+                            gettext_noop ("# REQUEST CONNECT messages received"),
+                            1,
+                            GNUNET_NO);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a request connect message for peer %s\n", GNUNET_i2s(&trcm->peer));
+  setup_peer_check_blacklist (&trcm->peer, GNUNET_YES,
+                              NULL, NULL);
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
 /**
  * Handle SET_QUOTA-message.
  *
@@ -5104,7 +5169,6 @@ static void
 create_environment (struct TransportPlugin *plug)
 {
   plug->env.cfg = cfg;
-  plug->env.sched = sched;
   plug->env.my_identity = &my_identity;
   plug->env.our_hello = &our_hello;
   plug->env.cls = plug;
@@ -5189,8 +5253,7 @@ client_disconnect_notification (void *cls,
                      bc->th = NULL;            
                    }
                  if (bc->task == GNUNET_SCHEDULER_NO_TASK)
-                   bc->task = GNUNET_SCHEDULER_add_now (sched,
-                                                        &do_blacklist_check,
+                   bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
                                                         bc);
                  break;
                }
@@ -5272,8 +5335,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       plugins = plug->next;
       if (plug->address_update_task != GNUNET_SCHEDULER_NO_TASK)
        {
-         GNUNET_SCHEDULER_cancel (plug->env.sched,
-                                  plug->address_update_task);
+         GNUNET_SCHEDULER_cancel (plug->address_update_task);
          plug->address_update_task = GNUNET_SCHEDULER_NO_TASK;
        }
       GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
@@ -5336,13 +5398,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * Initiate transport service.
  *
  * @param cls closure
- * @param s scheduler to use
  * @param server the initialized server
  * @param c configuration to use
  */
 static void
 run (void *cls,
-     struct GNUNET_SCHEDULER_Handle *s,
      struct GNUNET_SERVER_Handle *server,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
@@ -5353,6 +5413,8 @@ run (void *cls,
      GNUNET_MESSAGE_TYPE_HELLO, 0},
     {&handle_send, NULL,
      GNUNET_MESSAGE_TYPE_TRANSPORT_SEND, 0},
+    {&handle_request_connect, NULL,
+     GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT, sizeof(struct TransportRequestConnectMessage)},
     {&handle_set_quota, NULL,
      GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA, sizeof (struct QuotaSetMessage)},
     {&handle_address_lookup, NULL,
@@ -5370,9 +5432,8 @@ run (void *cls,
   unsigned long long tneigh;
   char *keyfile;
 
-  sched = s;
   cfg = c;
-  stats = GNUNET_STATISTICS_create (sched, "transport", cfg);
+  stats = GNUNET_STATISTICS_create ("transport", cfg);
   validation_map = GNUNET_CONTAINER_multihashmap_create (64);
   /* parse configuration */
   if ((GNUNET_OK !=
@@ -5388,7 +5449,7 @@ run (void *cls,
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _
                   ("Transport service is lacking key configuration settings.  Exiting.\n"));
-      GNUNET_SCHEDULER_shutdown (s);
+      GNUNET_SCHEDULER_shutdown ();
       if (stats != NULL)
        {
          GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
@@ -5399,12 +5460,12 @@ run (void *cls,
       return;
     }
   max_connect_per_transport = (uint32_t) tneigh;
-  peerinfo = GNUNET_PEERINFO_connect (sched, cfg);
+  peerinfo = GNUNET_PEERINFO_connect (cfg);
   if (peerinfo == NULL)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Could not access PEERINFO service.  Exiting.\n")); 
-      GNUNET_SCHEDULER_shutdown (s);
+      GNUNET_SCHEDULER_shutdown ();
       if (stats != NULL)
        {
          GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
@@ -5422,7 +5483,7 @@ run (void *cls,
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _
                   ("Transport service could not access hostkey.  Exiting.\n"));
-      GNUNET_SCHEDULER_shutdown (s);
+      GNUNET_SCHEDULER_shutdown ();
       if (stats != NULL)
        {
          GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
@@ -5455,8 +5516,7 @@ run (void *cls,
         }
       GNUNET_free (plugs);
     }
-  GNUNET_SCHEDULER_add_delayed (sched,
-                                GNUNET_TIME_UNIT_FOREVER_REL,
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                 &shutdown_task, NULL);
   if (no_transports)
     refresh_hello ();