bugfixes and redesigning scheduler API
[oweals/gnunet.git] / src / transport / gnunet-service-transport.c
index f0fff02a7e4ba7b38215d69646fd39c3f2a1aedb..efe53e0215388c90c214f377540e225ca77e5ed1 100644 (file)
 
 /**
  * How long until a HELLO verification attempt should time out?
+ * Must be rather small, otherwise a partially successful HELLO
+ * validation (some addresses working) might not be available
+ * before a client's request for a connection fails for good.
+ * Besides, if a single request to an address takes a long time,
+ * then the peer is unlikely worthwhile anyway.
  */
-#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_UNIT_MINUTES
+#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
 
 /**
  * How often do we re-add (cheaper) plugins to our list of plugins
@@ -547,7 +552,7 @@ struct GNUNET_SCHEDULER_Handle *sched;
 /**
  * Our configuration.
  */
-struct GNUNET_CONFIGURATION_Handle *cfg;
+const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
  * Linked list of all clients to this service.
@@ -667,7 +672,7 @@ transmit_to_client_callback (void *cls, size_t size, void *buf)
   uint16_t msize;
   size_t tsize;
   const struct GNUNET_MessageHeader *msg;
-  struct GNUNET_NETWORK_TransmitHandle *th;
+  struct GNUNET_CONNECTION_TransmitHandle *th;
   char *cbuf;
 
   if (buf == NULL)
@@ -692,6 +697,11 @@ transmit_to_client_callback (void *cls, size_t size, void *buf)
       msize = ntohs (msg->size);
       if (msize + tsize > size)
         break;
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Transmitting message of type %u to client.\n",
+                 ntohs (msg->type));
+#endif
       client->message_queue_head = q->next;
       if (q->next == NULL)
         client->message_queue_tail = NULL;
@@ -700,9 +710,9 @@ transmit_to_client_callback (void *cls, size_t size, void *buf)
       GNUNET_free (q);
       client->message_count--;
     }
-  GNUNET_assert (tsize > 0);
   if (NULL != q)
     {
+      GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
       th = GNUNET_SERVER_notify_transmit_ready (client->client,
                                                 msize,
                                                 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -730,7 +740,7 @@ transmit_to_client (struct TransportClient *client,
 {
   struct ClientMessageQueueEntry *q;
   uint16_t msize;
-  struct GNUNET_NETWORK_TransmitHandle *th;
+  struct GNUNET_CONNECTION_TransmitHandle *th;
 
   if ((client->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop))
     {
@@ -743,6 +753,7 @@ transmit_to_client (struct TransportClient *client,
     }
   client->message_count++;
   msize = ntohs (msg->size);
+  GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
   q = GNUNET_malloc (sizeof (struct ClientMessageQueueEntry) + msize);
   memcpy (&q[1], msg, msize);
   /* append to message queue */
@@ -798,24 +809,32 @@ try_alternative_plugins (struct NeighbourList *neighbour)
 
 
 /**
- * Check the ready list for the given neighbour and
- * if a plugin is ready for transmission (and if we
- * have a message), do so!
+ * The peer specified by the given neighbour has timed-out or a plugin
+ * has disconnected.  We may either need to do nothing (other plugins
+ * still up), or trigger a full disconnect and clean up.  This
+ * function updates our state and do the necessary notifications.
+ * Also notifies our clients that the neighbour is now officially
+ * gone.
  *
- * @param neighbour target peer for which to check the plugins
+ * @param n the neighbour list entry for the peer
+ * @param check should we just check if all plugins
+ *        disconnected or must we ask all plugins to
+ *        disconnect?
  */
-static void try_transmission_to_peer (struct NeighbourList *neighbour);
+static void
+disconnect_neighbour (struct NeighbourList *n,
+                     int check);
 
 
 /**
- * The peer specified by the given neighbour has timed-out.  Update
- * our state and do the necessary notifications.  Also notifies
- * our clients that the neighbour is now officially gone.
+ * Check the ready list for the given neighbour and
+ * if a plugin is ready for transmission (and if we
+ * have a message), do so!
  *
- * @param n the neighbour list entry for the peer
+ * @param neighbour target peer for which to check the plugins
  */
-static void
-disconnect_neighbour (struct NeighbourList *n);
+static void 
+try_transmission_to_peer (struct NeighbourList *neighbour);
 
 
 /**
@@ -868,11 +887,16 @@ transmit_send_continuation (void *cls,
                  "Transmission to peer `%s' failed, marking connection as down.\n",
                  GNUNET_i2s(target));
       rl->connected = GNUNET_NO;
+      rl->plugin_handle = NULL;
     }
   if (!mq->internal_msg)
     rl->transmit_ready = GNUNET_YES;
   if (mq->client != NULL)
     {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Notifying client %p about failed transission to peer `%4s'.\n",
+                 mq->client,
+                 GNUNET_i2s(target));
       send_ok_msg.header.size = htons (sizeof (send_ok_msg));
       send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
       send_ok_msg.success = htonl (result);
@@ -885,8 +909,8 @@ transmit_send_continuation (void *cls,
      another message (if available) */
   if (result == GNUNET_OK)
     try_transmission_to_peer (n);
-  else
-    disconnect_neighbour (n);
+  else    
+    disconnect_neighbour (n, GNUNET_YES); 
 }
 
 
@@ -1159,9 +1183,9 @@ update_addresses (struct TransportPlugin *plugin, int fresh)
   struct AddressList *next;
   int expired;
 
-  if (plugin->address_update_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
+  if (plugin->address_update_task != GNUNET_SCHEDULER_NO_TASK)
     GNUNET_SCHEDULER_cancel (plugin->env.sched, plugin->address_update_task);
-  plugin->address_update_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
+  plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
   now = GNUNET_TIME_absolute_get ();
   min_remaining = GNUNET_TIME_UNIT_FOREVER_REL;
   expired = GNUNET_NO;
@@ -1194,9 +1218,6 @@ update_addresses (struct TransportPlugin *plugin, int fresh)
   if (min_remaining.value < GNUNET_TIME_UNIT_FOREVER_REL.value)
     plugin->address_update_task
       = GNUNET_SCHEDULER_add_delayed (plugin->env.sched,
-                                      GNUNET_NO,
-                                      GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                      GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
                                       min_remaining,
                                       &expire_address_task, plugin);
 
@@ -1213,7 +1234,7 @@ static void
 expire_address_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct TransportPlugin *plugin = cls;
-  plugin->address_update_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
+  plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK;
   update_addresses (plugin, GNUNET_NO);
 }
 
@@ -1438,6 +1459,7 @@ cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct ValidationList *pos;
   struct ValidationList *prev;
   struct GNUNET_TIME_Absolute now;
+  struct GNUNET_TIME_Absolute first;
   struct GNUNET_HELLO_Message *hello;
   struct GNUNET_PeerIdentity pid;
   struct NeighbourList *n;
@@ -1493,16 +1515,19 @@ cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
   /* finally, reschedule cleanup if needed; list is
      ordered by timeout, so we need the last element... */
-  pos = pending_validations;
-  while ((pos != NULL) && (pos->next != NULL))
-    pos = pos->next;
-  if (NULL != pos)
-    GNUNET_SCHEDULER_add_delayed (sched,
-                                  GNUNET_NO,
-                                  GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                  GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
-                                  GNUNET_TIME_absolute_get_remaining
-                                  (pos->timeout), &cleanup_validation, NULL);
+  if (NULL != pending_validations)
+    {
+      first = pending_validations->timeout;
+      pos = pending_validations;
+      while (pos != NULL) 
+       {
+         first = GNUNET_TIME_absolute_min (first, pos->timeout);
+         pos = pos->next;
+       }
+      GNUNET_SCHEDULER_add_delayed (sched,
+                                   GNUNET_TIME_absolute_get_remaining (first),
+                                   &cleanup_validation, NULL);
+    }
 }
 
 
@@ -1530,7 +1555,7 @@ plugin_env_notify_validation (void *cls,
                              uint32_t challenge,
                              const char *sender_addr)
 {
-  int all_done;
+  unsigned int not_done;
   int matched;
   struct ValidationList *pos;
   struct ValidationAddress *va;
@@ -1557,7 +1582,7 @@ plugin_env_notify_validation (void *cls,
                  GNUNET_i2s(peer));
       return;
     }
-  all_done = GNUNET_YES;
+  not_done = 0;
   matched = GNUNET_NO;
   va = pos->addresses;
   while (va != NULL)
@@ -1566,7 +1591,10 @@ plugin_env_notify_validation (void *cls,
        {
 #if DEBUG_TRANSPORT
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Confirmed validity of peer address.\n");
+                     "Confirmed validity of address, peer `%4s' has address `%s'.\n",
+                     GNUNET_i2s (peer),
+                     GNUNET_a2s ((const struct sockaddr*) &va[1], 
+                                 va->addr_len));
 #endif
          GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
                      _("Another peer saw us using the address `%s' via `%s'. If this is not plausible, this address should be listed in the configuration as implausible to avoid MiM attacks.\n"),
@@ -1578,7 +1606,7 @@ plugin_env_notify_validation (void *cls,
          matched = GNUNET_YES;
        }        
       if (va->ok != GNUNET_YES)
-        all_done = GNUNET_NO;
+        not_done++;
       va = va->next;
     }
   if (GNUNET_NO == matched)
@@ -1589,15 +1617,29 @@ plugin_env_notify_validation (void *cls,
                   ("Received `%s' message but have no record of a matching `%s' message. Ignoring.\n"),
                   "PONG", "PING");
     }
-  if (GNUNET_YES == all_done)
+  if (0 == not_done)
     {
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "All addresses validated, will now construct `%s' for `%4s'.\n",
+                 "HELLO",
+                 GNUNET_i2s (peer));
+#endif
       pos->timeout.value = 0;
-      GNUNET_SCHEDULER_add_delayed (sched,
-                                    GNUNET_NO,
-                                    GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                    GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
-                                    GNUNET_TIME_UNIT_ZERO,
-                                    &cleanup_validation, NULL);
+      GNUNET_SCHEDULER_add_with_priority (sched,
+                                         GNUNET_SCHEDULER_PRIORITY_IDLE,
+                                         &cleanup_validation, NULL);
+    }
+  else
+    {
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Still waiting for %u additional `%s' messages before constructing `%s' for `%4s'.\n",
+                 not_done,
+                 "PONG",
+                 "HELLO",
+                 GNUNET_i2s (peer));
+#endif
     }
 }
 
@@ -1718,14 +1760,21 @@ check_hello_validated (void *cls,
   GNUNET_assert (GNUNET_OK ==
                 GNUNET_HELLO_get_id (chvc->hello,
                                      &apeer));
+#if DEBUG_TRANSPORT
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Ready to validate addresses from `%s' message for peer `%4s'\n",
+             "HELLO", GNUNET_i2s (&apeer));
+#endif
   va = chvc->e->addresses;
   while (va != NULL)
     {
 #if DEBUG_TRANSPORT
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "Establishing `%s' connection to validate `%s' of `%4s'\n",
+                  "Establishing `%s' connection to validate `%s' address `%s' of `%4s'\n",
                   va->transport_name,
                   "HELLO",
+                 GNUNET_a2s ((const struct sockaddr*) &va[1], 
+                             va->addr_len),
                  GNUNET_i2s (&apeer));
 #endif
       tp = find_transport (va->transport_name);
@@ -1740,14 +1789,9 @@ check_hello_validated (void *cls,
         va->ok = GNUNET_SYSERR;
       va = va->next;
     }
-  if (chvc->e->next == NULL)
-    GNUNET_SCHEDULER_add_delayed (sched,
-                                  GNUNET_NO,
-                                  GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                  GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
-                                  GNUNET_TIME_absolute_get_remaining
-                                  (chvc->e->timeout), &cleanup_validation,
-                                  NULL);
+  GNUNET_SCHEDULER_add_delayed (sched,
+                               GNUNET_TIME_absolute_get_remaining (chvc->e->timeout), 
+                               &cleanup_validation, NULL);
   GNUNET_free (chvc);
 }
 
@@ -1833,19 +1877,37 @@ process_hello (struct TransportPlugin *plugin,
 
 
 /**
- * The peer specified by the given neighbour has timed-out.  Update
- * our state and do the necessary notifications.  Also notifies
- * our clients that the neighbour is now officially gone.
+ * The peer specified by the given neighbour has timed-out or a plugin
+ * has disconnected.  We may either need to do nothing (other plugins
+ * still up), or trigger a full disconnect and clean up.  This
+ * function updates our state and do the necessary notifications.
+ * Also notifies our clients that the neighbour is now officially
+ * gone.
  *
  * @param n the neighbour list entry for the peer
+ * @param check should we just check if all plugins
+ *        disconnected or must we ask all plugins to
+ *        disconnect?
  */
 static void
-disconnect_neighbour (struct NeighbourList *n)
+disconnect_neighbour (struct NeighbourList *n,
+                     int check)
 {
   struct ReadyList *rpos;
   struct NeighbourList *npos;
   struct NeighbourList *nprev;
   struct MessageQueue *mq;
+  
+  if (GNUNET_YES == check)
+    {
+      rpos = n->plugins;
+      while (NULL != rpos)
+       {
+         if (GNUNET_YES == rpos->connected)
+           return; /* still connected */
+         rpos = rpos->next;
+       }
+    }
 
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
@@ -1869,13 +1931,16 @@ disconnect_neighbour (struct NeighbourList *n)
   /* notify all clients about disconnect */
   notify_clients_disconnect (&n->id);
 
-  /* clean up all plugins, cancel connections & pending transmissions */
+  /* clean up all plugins, cancel connections and pending transmissions */
   while (NULL != (rpos = n->plugins))
     {
       n->plugins = rpos->next;
       GNUNET_assert (rpos->neighbour == n);
-      rpos->plugin->api->cancel (rpos->plugin->api->cls,
-                                 rpos->plugin_handle, rpos, &n->id);
+      if (GNUNET_YES == rpos->connected)
+       rpos->plugin->api->cancel (rpos->plugin->api->cls,
+                                  rpos->plugin_handle,
+                                  rpos,
+                                  &n->id);
       GNUNET_free (rpos);
     }
 
@@ -1886,7 +1951,9 @@ disconnect_neighbour (struct NeighbourList *n)
       GNUNET_assert (mq->neighbour == n);
       GNUNET_free (mq);
     }
-
+  if (n->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (sched,
+                            n->timeout_task);
   /* finally, free n itself */
   GNUNET_free (n);
 }
@@ -1935,8 +2002,8 @@ neighbour_timeout_task (void *cls,
               "Neighbour `%4s' has timed out!\n",
              GNUNET_i2s(&n->id));
 #endif
-  n->timeout_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
-  disconnect_neighbour (n);
+  n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  disconnect_neighbour (n, GNUNET_NO);
 }
 
 
@@ -1969,9 +2036,6 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer)
   n->quota_in = (GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT + 59999) / (60 * 1000);
   add_plugins (n);
   n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                                  GNUNET_NO,
-                                                  GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                                  GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
                                                   GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                                   &neighbour_timeout_task, n);
   transmit_to_peer (NULL, 0,
@@ -1988,6 +2052,7 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer)
  * reducing the rate at which they read from the socket
  * and generally forward to our receive callback.
  *
+ * @param cls the "struct TransportPlugin *" we gave to the plugin
  * @param plugin_context value to pass to this plugin
  *        to respond to the given peer (use is optional,
  *        but may speed up processing)
@@ -2042,13 +2107,19 @@ plugin_env_receive (void *cls,
     }
   if (message == NULL)
     {
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+                 "Receive failed from `%4s', triggering disconnect\n",
+                 GNUNET_i2s(&n->id));
+#endif
+      /* TODO: call stats */
       if ((service_context != NULL) &&
           (service_context->plugin_handle == plugin_context))
         {
           service_context->connected = GNUNET_NO;
           service_context->plugin_handle = NULL;
         }
-      /* TODO: call stats */
+      disconnect_neighbour (n, GNUNET_YES);
       return NULL;
     }
 #if DEBUG_TRANSPORT
@@ -2076,9 +2147,7 @@ plugin_env_receive (void *cls,
   n->peer_timeout =
     GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
   n->timeout_task =
-    GNUNET_SCHEDULER_add_delayed (sched, GNUNET_NO,
-                                  GNUNET_SCHEDULER_PRIORITY_IDLE,
-                                  GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
+    GNUNET_SCHEDULER_add_delayed (sched, 
                                   GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                                   &neighbour_timeout_task, n);
   update_quota (n);
@@ -2090,7 +2159,8 @@ plugin_env_receive (void *cls,
                   _
                   ("Dropping incoming message due to repeated bandwidth quota violations.\n"));
       /* TODO: call stats */
-      GNUNET_assert (NULL != service_context->neighbour);
+      GNUNET_assert ( (service_context == NULL) ||
+                     (NULL != service_context->neighbour) );
       return service_context;
     }
   switch (ntohs (message->type))
@@ -2135,7 +2205,8 @@ plugin_env_receive (void *cls,
         }
       GNUNET_free (im);
     }
-  GNUNET_assert (NULL != service_context->neighbour);
+  GNUNET_assert ( (service_context == NULL) ||
+                 (NULL != service_context->neighbour) );
   return service_context;
 }
 
@@ -2363,8 +2434,10 @@ handle_try_connect (void *cls,
   tcm = (const struct TryConnectMessage *) message;
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Received `%s' request from client asking to connect to `%4s'\n",
-              "TRY_CONNECT", GNUNET_i2s (&tcm->peer));
+              "Received `%s' request from client %p asking to connect to `%4s'\n",
+              "TRY_CONNECT",
+             client,
+             GNUNET_i2s (&tcm->peer));
 #endif
   if (NULL == find_neighbour (&tcm->peer))
     setup_new_neighbour (&tcm->peer);
@@ -2498,6 +2571,42 @@ client_disconnect_notification (void *cls,
 }
 
 
+/**
+ * Function called when the service shuts down.  Unloads our plugins.
+ *
+ * @param cls closure, unused
+ * @param tc task context (unused)
+ */
+static void
+unload_plugins (void *cls, 
+               const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct TransportPlugin *plug;
+  struct AddressList *al;
+
+#if DEBUG_TRANSPORT
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Transport service is unloading plugins...\n");
+#endif
+  while (NULL != (plug = plugins))
+    {
+      plugins = plug->next;
+      GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
+      GNUNET_free (plug->lib_name);
+      GNUNET_free (plug->short_name);
+      while (NULL != (al = plug->addresses))
+        {
+          plug->addresses = al->next;
+          GNUNET_free (al);
+        }
+      GNUNET_free (plug);
+    }
+  if (my_private_key != NULL)
+    GNUNET_CRYPTO_rsa_key_free (my_private_key);
+  GNUNET_free_non_null (our_hello);
+}
+
+
 /**
  * Initiate transport service.
  *
@@ -2509,7 +2618,8 @@ client_disconnect_notification (void *cls,
 static void
 run (void *cls,
      struct GNUNET_SCHEDULER_Handle *s,
-     struct GNUNET_SERVER_Handle *serv, struct GNUNET_CONFIGURATION_Handle *c)
+     struct GNUNET_SERVER_Handle *serv, 
+     const struct GNUNET_CONFIGURATION_Handle *c)
 {
   char *plugs;
   char *pos;
@@ -2571,6 +2681,9 @@ run (void *cls,
         }
       GNUNET_free (plugs);
     }
+  GNUNET_SCHEDULER_add_delayed (sched,
+                                GNUNET_TIME_UNIT_FOREVER_REL,
+                                &unload_plugins, NULL);
   if (no_transports)
     refresh_hello ();
 #if DEBUG_TRANSPORT
@@ -2582,41 +2695,6 @@ run (void *cls,
 }
 
 
-/**
- * Function called when the service shuts
- * down.  Unloads our plugins.
- *
- * @param cls closure
- * @param cfg configuration to use
- */
-static void
-unload_plugins (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-  struct TransportPlugin *plug;
-  struct AddressList *al;
-
-#if DEBUG_TRANSPORT
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Transport service is unloading plugins...\n");
-#endif
-  while (NULL != (plug = plugins))
-    {
-      plugins = plug->next;
-      GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
-      GNUNET_free (plug->lib_name);
-      GNUNET_free (plug->short_name);
-      while (NULL != (al = plug->addresses))
-        {
-          plug->addresses = al->next;
-          GNUNET_free (al);
-        }
-      GNUNET_free (plug);
-    }
-  if (my_private_key != NULL)
-    GNUNET_CRYPTO_rsa_key_free (my_private_key);
-}
-
-
 /**
  * The main function for the transport service.
  *
@@ -2628,10 +2706,10 @@ int
 main (int argc, char *const *argv)
 {
   return (GNUNET_OK ==
-          GNUNET_SERVICE_run (argc,
-                              argv,
-                              "transport",
-                              &run, NULL, &unload_plugins, NULL)) ? 0 : 1;
+         GNUNET_SERVICE_run (argc,
+                             argv,
+                             "transport",
+                             &run, NULL)) ? 0 : 1;
 }
 
 /* end of gnunet-service-transport.c */