stuff
[oweals/gnunet.git] / src / transport / plugin_transport_http.c
index ba58f9ea74b404d5c26301571b88a6d050610a35..e63549784728e1842e1920f04f4d1feff41e9cd8 100644 (file)
@@ -37,6 +37,7 @@
 #include "gnunet_container_lib.h"
 #include "gnunet_transport_plugin.h"
 #include "gnunet_os_lib.h"
+#include "gnunet_nat_lib.h"
 #include "microhttpd.h"
 #include <curl/curl.h>
 
  */
 #define HTTP_CONNECT_TIMEOUT 30
 
-
 /**
  * Network format for IPv4 addresses.
  */
 struct IPv4HttpAddress
 {
-  /**
-   * Linked list next
-   */
-  struct IPv4HttpAddress * next;
-
-  /**
-   * Linked list previous
-   */
-  struct IPv4HttpAddress * prev;
-
   /**
    * IPv4 address, in network byte order.
    */
@@ -113,26 +103,32 @@ struct IPv4HttpAddress
   /**
    * Port number, in network byte order.
    */
-  uint16_t u_port GNUNET_PACKED;
-
+  uint16_t port GNUNET_PACKED;
 };
 
-
 /**
- * Network format for IPv6 addresses.
+ * Wrapper to manage IPv4 addresses
  */
-struct IPv6HttpAddress
+struct IPv4HttpAddressWrapper
 {
   /**
    * Linked list next
    */
-  struct IPv6HttpAddress * next;
+  struct IPv4HttpAddressWrapper * next;
 
   /**
    * Linked list previous
    */
-  struct IPv6HttpAddress * prev;
+  struct IPv4HttpAddressWrapper * prev;
+
+  struct IPv4HttpAddress * addr;
+};
 
+/**
+ * Network format for IPv6 addresses.
+ */
+struct IPv6HttpAddress
+{
   /**
    * IPv6 address.
    */
@@ -141,10 +137,27 @@ struct IPv6HttpAddress
   /**
    * Port number, in network byte order.
    */
-  uint16_t u6_port GNUNET_PACKED;
+  uint16_t port GNUNET_PACKED;
 
 };
 
+/**
+ * Wrapper for IPv4 addresses.
+ */
+struct IPv6HttpAddressWrapper
+{
+  /**
+   * Linked list next
+   */
+  struct IPv6HttpAddressWrapper * next;
+
+  /**
+   * Linked list previous
+   */
+  struct IPv6HttpAddressWrapper * prev;
+
+  struct IPv6HttpAddress * addr;
+};
 
 /**
  *  Message to send using http
@@ -412,25 +425,30 @@ struct Plugin
    */
   CURLM * multi_handle;
 
+  /**
+   * Our handle to the NAT module.
+   */
+  struct GNUNET_NAT_Handle *nat;
+
   /**
    * ipv4 DLL head
    */
-  struct IPv4HttpAddress * ipv4_addr_head;
+  struct IPv4HttpAddressWrapper * ipv4_addr_head;
 
   /**
    * ipv4 DLL tail
    */
-  struct IPv4HttpAddress * ipv4_addr_tail;
+  struct IPv4HttpAddressWrapper * ipv4_addr_tail;
 
   /**
    * ipv6 DLL head
    */
-  struct IPv6HttpAddress * ipv6_addr_head;
+  struct IPv6HttpAddressWrapper * ipv6_addr_head;
 
   /**
    * ipv6 DLL tail
    */
-  struct IPv6HttpAddress * ipv6_addr_tail;
+  struct IPv6HttpAddressWrapper * ipv6_addr_tail;
 
   /**
    * Our ASCII encoded, hashed peer identity
@@ -468,6 +486,16 @@ struct Plugin
    */
   int use_localaddresses;
 
+  /**
+   * maximum number of connections
+   */
+  int max_connect_per_transport;
+
+  /**
+   * Current number of connections;
+   */
+  int current_connections;
+
   /**
    * Closure passed by MHD to the mhd_logger function
    */
@@ -486,6 +514,27 @@ struct Plugin
 #endif
 };
 
+/**
+ * Context for address to string conversion.
+ */
+struct PrettyPrinterContext
+{
+  /**
+   * Function to call with the result.
+   */
+  GNUNET_TRANSPORT_AddressStringCallback asc;
+
+  /**
+   * Clsoure for 'asc'.
+   */
+  void *asc_cls;
+
+  /**
+   * Port to add after the IP address.
+   */
+  uint16_t port;
+};
+
 
 /**
  * Function called for a quick conversion of the binary address to
@@ -570,7 +619,6 @@ create_url(struct Plugin *plugin,
   GNUNET_asprintf(&url,
                   "%s://%s/%s;%u", PROTOCOL_PREFIX, addr_str,
                   (char *) (&plugin->my_ascii_hash_ident),id);
-  GNUNET_free_non_null(addr_str);
   return url;
 }
 
@@ -616,7 +664,10 @@ remove_peer_context_Iterator (void *cls,
              "Freeing context for peer `%s'\n",
              GNUNET_i2s(&pc->identity));
 #endif
-  GNUNET_CONTAINER_multihashmap_remove (plugin->peers, &pc->identity.hashPubKey, pc);
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_remove (plugin->peers, 
+                                                      &pc->identity.hashPubKey, 
+                                                      pc));
   while (ps!=NULL)
     {
       plugin->env->session_end(plugin, &pc->identity, ps);
@@ -731,6 +782,8 @@ remove_session (struct HTTP_PeerContext * pc,
   return GNUNET_OK;
 }
 
+
+#if 0
 static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
 {
        uint32_t res = 0;
@@ -770,6 +823,7 @@ static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen)
        return local;
 }
 
+
 /**
  * Add the IP of our network interface to the list of
  * our external IP addresses.
@@ -819,30 +873,28 @@ process_interfaces (void *cls,
 
 
       t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
-      t4->u_port = htons (plugin->port_inbound);
+      t4->port = htons (plugin->port_inbound);
       if (plugin->bind4_address != NULL) {
-         if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr)))
-             {
-             GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,
-                                                                                 plugin->ipv4_addr_tail,t4);
-                         plugin->env->notify_address(plugin->env->cls,
-                                                                                 PROTOCOL_PREFIX,
-                                                                                 t4, sizeof (struct IPv4HttpAddress),
-                                                                                 GNUNET_TIME_UNIT_FOREVER_REL);
-                         return GNUNET_OK;
-             }
-         GNUNET_free (t4);
-         return GNUNET_OK;
+       if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr)))
+         {
+           GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,
+                                       plugin->ipv4_addr_tail,t4);
+                 plugin->env->notify_address(plugin->env->cls,
+                                             GNUNET_YES,
+                                             t4, sizeof (struct IPv4HttpAddress));
+           return GNUNET_OK;
          }
+       GNUNET_free (t4);
+       return GNUNET_OK;
+      }
       else
          {
           GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head,
                                       plugin->ipv4_addr_tail,
                                       t4);
-         plugin->env->notify_address (plugin->env->cls,
-                                      PROTOCOL_PREFIX,
-                                      t4, sizeof (struct IPv4HttpAddress), 
-                                      GNUNET_TIME_UNIT_FOREVER_REL);
+          plugin->env->notify_address(plugin->env->cls,
+                                      GNUNET_YES,
+                                      t4, sizeof (struct IPv4HttpAddress));
          return GNUNET_OK;
          }
    }
@@ -862,11 +914,10 @@ process_interfaces (void *cls,
              memcpy (&t6->ipv6_addr,
                      &((struct sockaddr_in6 *) addr)->sin6_addr,
                      sizeof (struct in6_addr));
-             t6->u6_port = htons (plugin->port_inbound);
+             t6->port = htons (plugin->port_inbound);
              plugin->env->notify_address(plugin->env->cls,
-                                         PROTOCOL_PREFIX, t6,
-                                         sizeof (struct IPv6HttpAddress), 
-                                         GNUNET_TIME_UNIT_FOREVER_REL);
+                                         GNUNET_YES,
+                                         t6, sizeof (struct IPv6HttpAddress));
              GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,
                                          plugin->ipv6_addr_tail,
                                          t6);
@@ -878,16 +929,16 @@ process_interfaces (void *cls,
       memcpy (&t6->ipv6_addr,
                  &((struct sockaddr_in6 *) addr)->sin6_addr,
                  sizeof (struct in6_addr));
-      t6->u6_port = htons (plugin->port_inbound);
+      t6->port = htons (plugin->port_inbound);
       GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6);
+
       plugin->env->notify_address(plugin->env->cls,
-                                 PROTOCOL_PREFIX,
-                                 t6, sizeof (struct IPv6HttpAddress), 
-                                 GNUNET_TIME_UNIT_FOREVER_REL);
+                                  GNUNET_YES,
+                                 t6, sizeof (struct IPv6HttpAddress));
   }
   return GNUNET_OK;
 }
-
+#endif
 
 /**
  * External logging function for MHD
@@ -919,7 +970,11 @@ mhd_termination_cb (void *cls,
   if (ps == NULL)
     return;
   struct HTTP_PeerContext * pc = ps->peercontext;
-        
+  struct Plugin *plugin = cls;
+
+  GNUNET_assert (cls != NULL);
+    plugin->current_connections--;
+
   if (connection==ps->recv_endpoint)
     {
 #if DEBUG_CONNECTIONS
@@ -970,10 +1025,11 @@ mhd_write_mst_cb (void *cls,
                  const struct GNUNET_MessageHeader *message)
 {
   struct Session *ps  = cls; 
-  struct HTTP_PeerContext *pc = ps->peercontext;
+  struct HTTP_PeerContext *pc;
   struct GNUNET_TIME_Relative delay;
 
   GNUNET_assert(ps != NULL);
+  pc = ps->peercontext;
   GNUNET_assert(pc != NULL);
 #if DEBUG_HTTP
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1028,11 +1084,15 @@ mhd_accept_cb (void *cls,
               const struct sockaddr *addr, 
               socklen_t addr_len)
 {
-#if 0
   struct Plugin *plugin = cls;
-#endif
-  /* Every connection is accepted, nothing more to do here */
-  return MHD_YES;
+  GNUNET_assert (cls != NULL);
+
+  if (plugin->max_connect_per_transport > plugin->current_connections)
+  {
+    plugin->current_connections ++;
+    return MHD_YES;
+  }
+  else return MHD_NO;
 }
 
 
@@ -1068,6 +1128,7 @@ mhd_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
   
   if (msg!=NULL)
     {
+      /* sending */
       if ((msg->size-msg->pos) <= max)
        {
          memcpy(buf,&msg->buf[msg->pos],(msg->size-msg->pos));
@@ -1081,6 +1142,7 @@ mhd_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
          bytes_read = max;
        }
       
+      /* removing message */
       if (msg->pos==msg->size)
        {
          if (NULL!=msg->transmit_cont)
@@ -1208,7 +1270,7 @@ mhd_access_cb (void *cls,
          addrin = (const struct sockaddr_in*) client_addr;
          inet_ntop(addrin->sin_family, &(addrin->sin_addr),address,INET_ADDRSTRLEN);
          memcpy(&ipv4addr.ipv4_addr,&(addrin->sin_addr),sizeof(struct in_addr));
-         ipv4addr.u_port = addrin->sin_port;
+         ipv4addr.port = addrin->sin_port;
          addr = &ipv4addr;
          addr_len = sizeof(struct IPv4HttpAddress);
        }
@@ -1218,7 +1280,7 @@ mhd_access_cb (void *cls,
          addrin6 = (const struct sockaddr_in6 *) client_addr;
          inet_ntop(addrin6->sin6_family, &(addrin6->sin6_addr),address,INET6_ADDRSTRLEN);
          memcpy(&ipv6addr.ipv6_addr,&(addrin6->sin6_addr),sizeof(struct in6_addr));
-         ipv6addr.u6_port = addrin6->sin6_port;
+         ipv6addr.port = addrin6->sin6_port;
          addr = &ipv6addr;
          addr_len = sizeof(struct IPv6HttpAddress);
        }
@@ -1875,8 +1937,6 @@ curl_handle_finished (struct Plugin *plugin)
                  ps->send_connected = GNUNET_NO;
                  ps->send_active = GNUNET_NO;
                  curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
-                 //curl_easy_cleanup(ps->send_endpoint);
-                 //ps->send_endpoint=NULL;
                  while (ps->pending_msgs_tail != NULL)
                    {
                      cur_msg = ps->pending_msgs_tail;
@@ -1901,8 +1961,6 @@ curl_handle_finished (struct Plugin *plugin)
                  ps->recv_connected = GNUNET_NO;
                  ps->recv_active = GNUNET_NO;
                  curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
-                 //curl_easy_cleanup(ps->recv_endpoint);
-                 //ps->recv_endpoint=NULL;
                }
            }
          else
@@ -1941,8 +1999,6 @@ curl_handle_finished (struct Plugin *plugin)
                  ps->send_connected = GNUNET_NO;
                  ps->send_active = GNUNET_NO;
                  curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
-                 //curl_easy_cleanup(ps->send_endpoint);
-                 //ps->send_endpoint =NULL;
                }
              if (msg->easy_handle == ps->recv_endpoint)
                {
@@ -1957,9 +2013,8 @@ curl_handle_finished (struct Plugin *plugin)
                  ps->recv_connected = GNUNET_NO;
                  ps->recv_active = GNUNET_NO;
                  curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
-                 //curl_easy_cleanup(ps->recv_endpoint);
-                 //ps->recv_endpoint=NULL;
                }
+             plugin->current_connections--;
            }
          if ((ps->recv_connected == GNUNET_NO) && (ps->send_connected == GNUNET_NO))
            remove_session (pc, ps, GNUNET_YES, GNUNET_SYSERR);
@@ -2121,10 +2176,11 @@ send_check_connections (struct Plugin *plugin,
   CURLMcode mret;
   struct GNUNET_TIME_Relative timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT;
 
-  if (ps->direction == OUTBOUND)
+  if ((ps->direction == OUTBOUND) && (plugin->current_connections < plugin->max_connect_per_transport))
     {
       /* RECV DIRECTION */
       /* Check if session is connected to receive data, otherwise connect to peer */
+
       if (ps->recv_connected == GNUNET_NO)
        {
          int fresh = GNUNET_NO;
@@ -2139,7 +2195,7 @@ send_check_connections (struct Plugin *plugin,
          curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGDATA , ps->recv_endpoint);
 #endif
 #if BUILD_HTTPS
-         curl_easy_setopt (ps->recv_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
+         curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
          curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYPEER, 0);
          curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYHOST, 0);
 #endif
@@ -2170,11 +2226,12 @@ send_check_connections (struct Plugin *plugin,
                  return GNUNET_SYSERR;
                }
            }
-         if (plugin->http_curl_task !=  GNUNET_SCHEDULER_NO_TASK)
+         if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
            {
              GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
              plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
            }
+         plugin->current_connections ++;
          plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin);
        }
       
@@ -2218,7 +2275,7 @@ send_check_connections (struct Plugin *plugin,
            }
        }
       /* not connected, initiate connection */
-      if (ps->send_connected==GNUNET_NO)
+      if ((ps->send_connected==GNUNET_NO) && (plugin->current_connections < plugin->max_connect_per_transport))
        {
          int fresh = GNUNET_NO;
          if (NULL == ps->send_endpoint)
@@ -2279,6 +2336,7 @@ send_check_connections (struct Plugin *plugin,
          GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
          plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
        }
+      plugin->current_connections++;
       plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin);
       return GNUNET_YES;
     }
@@ -2555,7 +2613,7 @@ http_plugin_send (void *cls,
          ps->send_force_disconnect = GNUNET_NO;
          ps->pending_msgs_head = NULL;
          ps->pending_msgs_tail = NULL;
-         ps->peercontext=pc;
+         ps->peercontext = pc;
          ps->session_id = pc->session_id_counter;
          ps->queue_length_cur = 0;
          ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE;
@@ -2668,6 +2726,32 @@ http_plugin_disconnect (void *cls,
 }
 
 
+/**
+ * Append our port and forward the result.
+ *
+ * @param cls the 'struct PrettyPrinterContext*'
+ * @param hostname hostname part of the address
+ */
+static void
+append_port (void *cls, const char *hostname)
+{
+  struct PrettyPrinterContext *ppc = cls;
+  char *ret;
+
+  if (hostname == NULL)
+    {
+      ppc->asc (ppc->asc_cls, NULL);
+      GNUNET_free (ppc);
+      return;
+    }
+  GNUNET_asprintf (&ret, "%s://%s:%d", PROTOCOL_PREFIX, hostname, ppc->port);
+
+  ppc->asc (ppc->asc_cls, ret);
+  GNUNET_free (ret);
+}
+
+
+
 /**
  * Convert the transports address to a nice, human-readable
  * format.
@@ -2692,31 +2776,38 @@ http_plugin_address_pretty_printer (void *cls,
                                         GNUNET_TRANSPORT_AddressStringCallback
                                         asc, void *asc_cls)
 {
+  struct PrettyPrinterContext *ppc;
+  const void *sb;
+  size_t sbs;
+  struct sockaddr_in  a4;
+  struct sockaddr_in6 a6;
   const struct IPv4HttpAddress *t4;
   const struct IPv6HttpAddress *t6;
-  struct sockaddr_in a4;
-  struct sockaddr_in6 a6;
-  char * address;
-  char * ret;
-  unsigned int port;
-  unsigned int res;
+  uint16_t port;
 
-  GNUNET_assert(cls !=NULL);
   if (addrlen == sizeof (struct IPv6HttpAddress))
     {
-      address = GNUNET_malloc (INET6_ADDRSTRLEN);
       t6 = addr;
-      a6.sin6_addr = t6->ipv6_addr;
-      inet_ntop(AF_INET6, &(a6.sin6_addr),address,INET6_ADDRSTRLEN);
-      port = ntohs(t6->u6_port);
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = t6->port;
+      memcpy (&a6.sin6_addr,
+              &t6->ipv6_addr,
+              sizeof (struct in6_addr));
+      port = ntohs (t6->port);
+      sb = &a6;
+      sbs = sizeof (a6);
     }
   else if (addrlen == sizeof (struct IPv4HttpAddress))
     {
-      address = GNUNET_malloc (INET_ADDRSTRLEN);
       t4 = addr;
-      a4.sin_addr.s_addr =  t4->ipv4_addr;
-      inet_ntop(AF_INET, &(a4.sin_addr),address,INET_ADDRSTRLEN);
-      port = ntohs(t4->u_port);
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = t4->port;
+      a4.sin_addr.s_addr = t4->ipv4_addr;
+      port = ntohs (t4->ipv4_addr);
+      sb = &a4;
+      sbs = sizeof (a4);
     }
   else
     {
@@ -2725,11 +2816,13 @@ http_plugin_address_pretty_printer (void *cls,
       asc (asc_cls, NULL);
       return;
     }
-  res = GNUNET_asprintf(&ret,"%s://%s:%u/", PROTOCOL_PREFIX, address, port);
-  GNUNET_free (address);
-  GNUNET_assert(res != 0);
-  asc (asc_cls, ret);
-  GNUNET_free_non_null (ret);
+  ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
+  ppc->asc = asc;
+  ppc->asc_cls = asc_cls;
+  ppc->port = port;
+  GNUNET_RESOLVER_hostname_get (sb,
+                                sbs,
+                                !numeric, timeout, &append_port, ppc);
 }
 
 
@@ -2753,8 +2846,8 @@ http_plugin_address_suggested (void *cls,
   struct Plugin *plugin = cls;
   struct IPv4HttpAddress *v4;
   struct IPv6HttpAddress *v6;
-  struct IPv4HttpAddress *tv4 = plugin->ipv4_addr_head;
-  struct IPv6HttpAddress *tv6 = plugin->ipv6_addr_head;
+  struct IPv4HttpAddressWrapper *w_tv4 = plugin->ipv4_addr_head;
+  struct IPv6HttpAddressWrapper *w_tv6 = plugin->ipv6_addr_head;
 
   GNUNET_assert(cls !=NULL);
   if ((addrlen != sizeof (struct IPv4HttpAddress)) &&
@@ -2770,13 +2863,13 @@ http_plugin_address_suggested (void *cls,
          else
            return GNUNET_SYSERR;
        }
-      while (tv4!=NULL)
+      while (w_tv4!=NULL)
        {
-         if (0==memcmp (&tv4->ipv4_addr, &v4->ipv4_addr, sizeof(uint32_t)))
+         if (0==memcmp (&w_tv4->addr->ipv4_addr, &v4->ipv4_addr, sizeof(uint32_t)))
            break;
-         tv4 = tv4->next;
+         w_tv4 = w_tv4->next;
        }
-      if (tv4 != NULL)
+      if (w_tv4 != NULL)
         return GNUNET_OK;
       else
        return GNUNET_SYSERR;
@@ -2791,13 +2884,13 @@ http_plugin_address_suggested (void *cls,
          else
            return GNUNET_SYSERR;
        }
-      while (tv6!=NULL)
+      while (w_tv6!=NULL)
        {
-         if (0 == memcmp (&tv6->ipv6_addr, &v6->ipv6_addr, sizeof(struct in6_addr)))
+         if (0 == memcmp (&w_tv6->addr->ipv6_addr, &v6->ipv6_addr, sizeof(struct in6_addr)))
            break;
-         tv6 = tv6->next;
+         w_tv6 = w_tv6->next;
        }
-      if (tv6 !=NULL)
+      if (w_tv6 !=NULL)
         return GNUNET_OK;
       else
        return GNUNET_SYSERR;
@@ -2827,9 +2920,9 @@ http_plugin_address_to_string (void *cls,
   struct sockaddr_in a4;
   struct sockaddr_in6 a6;
   char * address;
-  char * ret;
+  static char rbuf[INET6_ADDRSTRLEN + 13];
   uint16_t port;
-  unsigned int res;
+  int res;
 
   if (addrlen == sizeof (struct IPv6HttpAddress))
     {
@@ -2837,7 +2930,7 @@ http_plugin_address_to_string (void *cls,
       t6 = addr;
       a6.sin6_addr = t6->ipv6_addr;
       inet_ntop(AF_INET6, &(a6.sin6_addr),address,INET6_ADDRSTRLEN);
-      port = ntohs(t6->u6_port);
+      port = ntohs(t6->port);
     }
   else if (addrlen == sizeof (struct IPv4HttpAddress))
     {
@@ -2845,19 +2938,221 @@ http_plugin_address_to_string (void *cls,
       t4 = addr;
       a4.sin_addr.s_addr =  t4->ipv4_addr;
       inet_ntop(AF_INET, &(a4.sin_addr),address,INET_ADDRSTRLEN);
-      port = ntohs(t4->u_port);
+      port = ntohs(t4->port);
     }
   else
     {
       /* invalid address */
       return NULL;
     }
-  res = GNUNET_asprintf(&ret,"%s:%u",address,port);
+
+  res = GNUNET_snprintf (rbuf,
+                   sizeof (rbuf),
+                   "%s:%u",
+                   address,
+                   port);
+
   GNUNET_free (address);
   GNUNET_assert(res != 0);
-  return ret;
+  return rbuf;
 }
 
+/**
+ * Function called by the NAT subsystem suggesting another peer wants
+ * to connect to us via connection reversal.  Try to connect back to the
+ * given IP.
+ *
+ * @param cls closure
+ * @param addr address to try
+ * @param addrlen number of bytes in addr
+ */
+static void
+try_connection_reversal (void *cls,
+                         const struct sockaddr *addr,
+                         socklen_t addrlen)
+{
+
+}
+
+static void
+tcp_nat_cb_add_addr (void *cls,
+                         int add_remove,
+                         const struct sockaddr *addr,
+                         socklen_t addrlen)
+{
+  struct Plugin *plugin = cls;
+  struct IPv4HttpAddress * t4 = NULL;
+  struct IPv4HttpAddressWrapper * w_t4 = NULL;
+  struct IPv6HttpAddress * t6 = NULL;
+  struct IPv6HttpAddressWrapper * w_t6 = NULL;
+  int af;
+
+  af = addr->sa_family;
+  switch (af)
+  {
+  case AF_INET:
+    w_t4 = plugin->ipv4_addr_head;
+    while (w_t4 != NULL)
+    {
+      int res = memcmp(&w_t4->addr->ipv4_addr,
+                       &((struct sockaddr_in *) addr)->sin_addr,
+                       sizeof (struct in_addr));
+      if (0 == res)
+        break;
+      w_t4 = w_t4->next;
+    }
+    if (w_t4 == NULL)
+    {
+      w_t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddressWrapper));
+      t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress));
+      memcpy (&t4->ipv4_addr,
+            &((struct sockaddr_in *) addr)->sin_addr,
+            sizeof (struct in_addr));
+      t4->port = htons (plugin->port_inbound);
+
+      w_t4->addr = t4;
+
+      GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,
+                                  plugin->ipv4_addr_tail,w_t4);
+    }
+    plugin->env->notify_address(plugin->env->cls,
+                                add_remove,
+                                w_t4->addr, sizeof (struct IPv4HttpAddress));
+
+    break;
+  case AF_INET6:
+    w_t6 = plugin->ipv6_addr_head;
+    while (w_t6)
+    {
+      int res = memcmp(&w_t6->addr->ipv6_addr,
+                       &((struct sockaddr_in6 *) addr)->sin6_addr,
+                       sizeof (struct in6_addr));
+      if (0 == res)
+        break;
+      w_t6 = w_t6->next;
+    }
+    if (w_t6 == NULL)
+    {
+    w_t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddressWrapper));
+    t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress));
+
+    memcpy (&t6->ipv6_addr,
+            &((struct sockaddr_in6 *) addr)->sin6_addr,
+            sizeof (struct in6_addr));
+    t6->port = htons (plugin->port_inbound);
+
+    w_t6->addr = t6;
+
+    GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,
+                                plugin->ipv6_addr_tail,w_t6);
+    }
+    plugin->env->notify_address(plugin->env->cls,
+                                add_remove,
+                                w_t6->addr, sizeof (struct IPv6HttpAddress));
+    break;
+  default:
+    return;
+  }
+
+}
+
+static void
+tcp_nat_cb_remove_addr (void *cls,
+                         int add_remove,
+                         const struct sockaddr *addr,
+                         socklen_t addrlen)
+{
+  struct Plugin *plugin = cls;
+  struct IPv4HttpAddressWrapper * w_t4 = NULL;
+  struct IPv6HttpAddressWrapper * w_t6 = NULL;
+  int af;
+
+  af = addr->sa_family;
+  switch (af)
+  {
+  case AF_INET:
+    w_t4 = plugin->ipv4_addr_head;
+      while (w_t4 != NULL)
+      {
+        int res = memcmp(&w_t4->addr->ipv4_addr,
+                         &((struct sockaddr_in *) addr)->sin_addr,
+                         sizeof (struct in_addr));
+        if (0 == res)
+          break;
+        w_t4 = w_t4->next;
+      }
+      if (w_t4 == NULL)
+        return;
+      plugin->env->notify_address(plugin->env->cls,
+                                add_remove,
+                                w_t4->addr, sizeof (struct IPv4HttpAddress));
+
+      GNUNET_CONTAINER_DLL_remove(plugin->ipv4_addr_head,
+                                  plugin->ipv4_addr_tail,w_t4);
+      GNUNET_free (w_t4->addr);
+      GNUNET_free (w_t4);
+    break;
+  case AF_INET6:
+    w_t6 = plugin->ipv6_addr_head;
+    while (w_t6 != NULL)
+    {
+      int res = memcmp(&w_t6->addr->ipv6_addr,
+                       &((struct sockaddr_in6 *) addr)->sin6_addr,
+                       sizeof (struct in6_addr));
+      if (0 == res)
+        break;
+      w_t6 = w_t6->next;
+    }
+    if (w_t6 == NULL)
+      return;
+    plugin->env->notify_address(plugin->env->cls,
+                              add_remove,
+                              w_t6->addr, sizeof (struct IPv6HttpAddress));
+
+    GNUNET_CONTAINER_DLL_remove(plugin->ipv6_addr_head,
+                                plugin->ipv6_addr_tail,w_t6);
+    GNUNET_free (w_t6->addr);
+    GNUNET_free (w_t6);
+    break;
+  default:
+    return;
+  }
+
+}
+
+/**
+ * Our external IP address/port mapping has changed.
+ *
+ * @param cls closure, the 'struct LocalAddrList'
+ * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean
+ *     the previous (now invalid) one
+ * @param addr either the previous or the new public IP address
+ * @param addrlen actual lenght of the address
+ */
+static void
+tcp_nat_port_map_callback (void *cls,
+                           int add_remove,
+                           const struct sockaddr *addr,
+                           socklen_t addrlen)
+{
+  GNUNET_assert(cls !=NULL );
+#if DEBUG_HTTP
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+                   "NPMC called to %s address `%s'\n",
+                   (add_remove == GNUNET_YES) ? "remove" : "add",
+                   GNUNET_a2s (addr, addrlen));
+#endif
+  /* convert 'addr' to our internal format */
+  switch (add_remove)
+  {
+  case GNUNET_YES:
+    tcp_nat_cb_add_addr (cls, add_remove, addr, addrlen);
+    break;
+  case GNUNET_NO:
+    tcp_nat_cb_remove_addr (cls, add_remove, addr, addrlen);
+    break;
+  }
+}
 
 /**
  * Exit point from the plugin.
@@ -2868,10 +3163,13 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
   struct Plugin *plugin = api->cls;
   CURLMcode mret;
-  struct IPv4HttpAddress * ipv4addr;
-  struct IPv6HttpAddress * ipv6addr;
+  struct IPv4HttpAddressWrapper * w_t4;
+  struct IPv6HttpAddressWrapper * w_t6;
   GNUNET_assert(cls !=NULL);
 
+  if (plugin->nat != NULL)
+    GNUNET_NAT_unregister (plugin->nat);
+
   if (plugin->http_server_daemon_v4 != NULL)
     {
       MHD_stop_daemon (plugin->http_server_daemon_v4);
@@ -2892,19 +3190,21 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
       GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6);
       plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK;
     }
-  
+
   while (plugin->ipv4_addr_head!=NULL)
     {
-      ipv4addr = plugin->ipv4_addr_head;
-      GNUNET_CONTAINER_DLL_remove(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,ipv4addr);
-      GNUNET_free(ipv4addr);
+      w_t4 = plugin->ipv4_addr_head;
+      GNUNET_CONTAINER_DLL_remove(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,w_t4);
+      GNUNET_free(w_t4->addr);
+      GNUNET_free(w_t4);
     }
   
   while (plugin->ipv6_addr_head!=NULL)
     {
-      ipv6addr = plugin->ipv6_addr_head;
-      GNUNET_CONTAINER_DLL_remove(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,ipv6addr);
-      GNUNET_free(ipv6addr);
+      w_t6 = plugin->ipv6_addr_head;
+      GNUNET_CONTAINER_DLL_remove(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,w_t6);
+      GNUNET_free(w_t6->addr);
+      GNUNET_free(w_t6);
     }
   
   /* free all peer information */
@@ -2931,9 +3231,10 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
       plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
     }
   
+
   GNUNET_free_non_null (plugin->bind4_address);
   GNUNET_free_non_null (plugin->bind6_address);
-  GNUNET_free_non_null(plugin->bind_hostname);
+  GNUNET_free_non_null (plugin->bind_hostname);
 #if BUILD_HTTPS
   GNUNET_free_non_null (plugin->crypto_init);
   GNUNET_free_non_null (plugin->cert);
@@ -2957,8 +3258,8 @@ load_certificate( const char * file )
   struct stat fstat;
   char * text = NULL;
 
-  if (0!=STAT(file, &fstat))
-         return NULL;
+  if (0 != STAT(file, &fstat))
+    return NULL;
   text = GNUNET_malloc (fstat.st_size+1);
   gn_file = GNUNET_DISK_file_open(file, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ);
   if (gn_file==NULL)
@@ -2966,14 +3267,14 @@ load_certificate( const char * file )
       GNUNET_free(text);
       return NULL;
     }
-  if (GNUNET_SYSERR == GNUNET_DISK_file_read(gn_file, text, fstat.st_size))
+  if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fstat.st_size))
     {
-      GNUNET_free(text);
-      GNUNET_DISK_file_close(gn_file);
+      GNUNET_free (text);
+      GNUNET_DISK_file_close (gn_file);
       return NULL;
     }
   text[fstat.st_size] = '\0';
-  GNUNET_DISK_file_close(gn_file);
+  GNUNET_DISK_file_close (gn_file);
   return text;
 }
 #endif
@@ -2990,6 +3291,10 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
   struct GNUNET_TRANSPORT_PluginFunctions *api;
   struct GNUNET_TIME_Relative gn_timeout;
   long long unsigned int port;
+  unsigned long long tneigh;
+  struct sockaddr **addrs;
+  socklen_t *addrlens;
+  int ret;
   char * component_name;
 #if BUILD_HTTPS
   char * key_file = NULL;
@@ -3028,6 +3333,16 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
   GNUNET_CRYPTO_hash_to_enc (&(plugin->env->my_identity->hashPubKey), 
                             &plugin->my_ascii_hash_ident);
 
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_number (env->cfg,
+                                            component_name,
+                                            "MAX_CONNECTIONS",
+                                            &tneigh))
+    tneigh = 128;
+  plugin->max_connect_per_transport = tneigh;
+
+
   /* Use IPv6? */
   if (GNUNET_CONFIGURATION_have_value (env->cfg,
                                       component_name, "USE_IPv6"))
@@ -3129,96 +3444,94 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
   
 #if BUILD_HTTPS
   /* Reading HTTPS crypto related configuration */
-  /* Get crypto init string from config */
-  if (GNUNET_CONFIGURATION_have_value (env->cfg,
-                                      "transport-https", "CRYPTO_INIT"))
-    {
-      GNUNET_CONFIGURATION_get_value_string (env->cfg,
-                                            "transport-https",
-                                            "CRYPTO_INIT",
-                                            &plugin->crypto_init);
-    }
-  else
-    {
-      GNUNET_asprintf(&plugin->crypto_init,"NORMAL");
-    }
-  
-  /* Get private key file from config */
-  if (GNUNET_CONFIGURATION_have_value (env->cfg,
-                                      "transport-https", "KEY_FILE"))
-    {
-    GNUNET_CONFIGURATION_get_value_filename (env->cfg,
-                                            "transport-https",
-                                            "KEY_FILE",
-                                            &key_file);
-    }
-  if (key_file==NULL)
-    GNUNET_asprintf(&key_file,"https.key");
-  
-  /* Get private key file from config */
-  if (GNUNET_CONFIGURATION_have_value (env->cfg,"transport-https", "CERT_FILE"))
+  /* Get crypto init string from config */  
+  if ( (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_string (env->cfg,
+                                              "transport-https",
+                                              "CRYPTO_INIT",
+                                              &plugin->crypto_init)) ||
+       (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_filename (env->cfg,
+                                                "transport-https",
+                                                "KEY_FILE",
+                                                &key_file)) ||
+       (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_filename (env->cfg,
+                                                "transport-https",
+                                                "CERT_FILE",
+                                                &cert_file)) )
     {
-    GNUNET_CONFIGURATION_get_value_filename (env->cfg,
-                                            "transport-https",
-                                            "CERT_FILE",
-                                            &cert_file);
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                      "https",
+                      _("Required configuration options missing in section `%s'\n"),
+                      "transport-https");
+      GNUNET_free (component_name);
+      GNUNET_free_non_null (key_file);
+      GNUNET_free_non_null (cert_file);
+      LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
+      return NULL;   
     }
-  if (cert_file==NULL)
-    GNUNET_asprintf(&cert_file,"https.cert");
-  
   /* read key & certificates from file */
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
              "Loading TLS certificate `%s' `%s'\n", 
              key_file, cert_file);
 
-  plugin->key = load_certificate( key_file );
-  plugin->cert = load_certificate( cert_file );
+  plugin->key = load_certificate (key_file);
+  plugin->cert = load_certificate (cert_file);
 
-  if ((plugin->key==NULL) || (plugin->cert==NULL))
+  if ( (plugin->key==NULL) || (plugin->cert==NULL) )
     {
-      char * cmd;
-      int ret = 0;
-      GNUNET_asprintf(&cmd,
-                     "gnunet-transport-certificate-creation %s %s", 
-                     key_file, cert_file);
+      struct GNUNET_OS_Process *certcreation;
+
+      GNUNET_free_non_null (plugin->key);
+      plugin->key = NULL;
+      GNUNET_free_non_null (plugin->cert);
+      plugin->cert = NULL;
+#if DEBUG_HTTP
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "No usable TLS certificate found, creating certificate \n");
-      ret = system(cmd);
-      if (ret != 0)
-       {
-         GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
-                          "https",
-                          _("Could not create a new TLS certificate, shell script `%s' failed!\n"),cmd,
-                          "transport-https");
-         GNUNET_free (key_file);
-         GNUNET_free (cert_file);
-         GNUNET_free (component_name);
-         LIBGNUNET_PLUGIN_TRANSPORT_DONE(api);
-         GNUNET_free (cmd);
-         return NULL;
-       }
-      GNUNET_free (cmd);
-      plugin->key = load_certificate( key_file );
-      plugin->cert = load_certificate( cert_file );
-      if ((plugin->key==NULL) || (plugin->cert==NULL))
+                 "No usable TLS certificate found, creating certificate\n");
+#endif
+      errno = 0;
+      certcreation = GNUNET_OS_start_process (NULL, NULL,
+                                             "gnunet-transport-certificate-creation", 
+                                             "gnunet-transport-certificate-creation", 
+                                             key_file, cert_file,
+                                             NULL);
+      if (certcreation == NULL) 
        {
          GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
                           "https",
-                          _("No usable TLS certificate found and creating one failed! \n"),
-                          "transport-https");
+                          _("Could not create a new TLS certificate, program `gnunet-transport-certificate-creation' could not be started!\n"));
          GNUNET_free (key_file);
          GNUNET_free (cert_file);
          GNUNET_free (component_name);
-         
-         LIBGNUNET_PLUGIN_TRANSPORT_DONE(api);
+         LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
          return NULL;
        }
+      GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (certcreation));
+      GNUNET_OS_process_close (certcreation);
+      plugin->key = load_certificate (key_file);
+      plugin->cert = load_certificate (cert_file);
     }
+  if ( (plugin->key==NULL) || (plugin->cert==NULL) )
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                      "https",
+                      _("No usable TLS certificate found and creating one failed!\n"),
+                      "transport-https");
+      GNUNET_free (key_file);
+      GNUNET_free (cert_file);
+      GNUNET_free (component_name);      
+      LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
+      return NULL;
+    }    
   GNUNET_free (key_file);
   GNUNET_free (cert_file);
-  
-  GNUNET_assert((plugin->key!=NULL) && (plugin->cert!=NULL));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n");
+#if DEBUG_HTTP
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
+             "TLS certificate loaded\n");
+#endif
 #endif
 
   GNUNET_assert ((port > 0) && (port <= 65535));
@@ -3239,11 +3552,10 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
 #endif
                                                        MHD_USE_IPv6,
                                                        port,
-                                                       &mhd_accept_cb,
-                                                       plugin , &mhd_access_cb, plugin,
+                                                       &mhd_accept_cb, plugin,
+                                                       &mhd_access_cb, plugin,
                                                        MHD_OPTION_SOCK_ADDR, tmp,
-                                                       MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32,
-                                                       //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6,
+                                                       MHD_OPTION_CONNECTION_LIMIT, (unsigned int) plugin->max_connect_per_transport,
 #if BUILD_HTTPS
                                                        MHD_OPTION_HTTPS_PRIORITIES,  plugin->crypto_init,
                                                        MHD_OPTION_HTTPS_MEM_KEY, plugin->key,
@@ -3251,7 +3563,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
 #endif
                                                        MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout,
                                                        MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (2 * GNUNET_SERVER_MAX_MESSAGE_SIZE),
-                                                       MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL,
+                                                       MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, plugin,
                                                        MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, plugin->mhd_log,
                                                        MHD_OPTION_END);
     }
@@ -3268,19 +3580,19 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
 #endif
                                                        MHD_NO_FLAG,
                                                        port,
-                                                       &mhd_accept_cb,
-                                                       plugin , &mhd_access_cb, plugin,
-                                                       MHD_OPTION_SOCK_ADDR, (struct sockaddr_in *)plugin->bind4_address,
-                                                       MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32,
-                                                       //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6,
+                                                       &mhd_accept_cb, plugin ,
+                                                       &mhd_access_cb, plugin,
+                                                       MHD_OPTION_SOCK_ADDR, (struct sockaddr_in *) plugin->bind4_address,
+                                                        MHD_OPTION_CONNECTION_LIMIT, (unsigned int) plugin->max_connect_per_transport,
 #if BUILD_HTTPS
                                                        MHD_OPTION_HTTPS_PRIORITIES,  plugin->crypto_init,
+
                                                        MHD_OPTION_HTTPS_MEM_KEY, plugin->key,
                                                        MHD_OPTION_HTTPS_MEM_CERT, plugin->cert,
 #endif
                                                        MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout,
                                                        MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (2 * GNUNET_SERVER_MAX_MESSAGE_SIZE),
-                                                       MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL,
+                                                       MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, plugin,
                                                        MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, plugin->mhd_log,
                                                        MHD_OPTION_END);
     }
@@ -3352,10 +3664,46 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
       return NULL;
     }
   
+  ret = GNUNET_SERVICE_get_server_addresses (component_name,
+                          env->cfg,
+                          &addrs,
+                          &addrlens);
+
+  if (ret != GNUNET_SYSERR)
+  {
+    plugin->nat = GNUNET_NAT_register (env->cfg,
+                                         GNUNET_YES,
+                                         port,
+                                         (unsigned int) ret,
+                                         (const struct sockaddr **) addrs,
+                                         addrlens,
+                                         &tcp_nat_port_map_callback,
+                                         &try_connection_reversal,
+                                         plugin);
+      while (ret > 0)
+      {
+        ret--;
+        GNUNET_assert (addrs[ret] != NULL);
+        GNUNET_free (addrs[ret]);
+      }
+      GNUNET_free_non_null (addrs);
+      GNUNET_free_non_null (addrlens);
+  }
+  else
+  {
+    plugin->nat = GNUNET_NAT_register (env->cfg,
+         GNUNET_YES,
+         0,
+         0, NULL, NULL,
+         NULL,
+         &try_connection_reversal,
+         plugin);
+  }
+
   plugin->peers = GNUNET_CONTAINER_multihashmap_create (10);
-  GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
   
   GNUNET_free(component_name);
+  //GNUNET_SCHEDULER_add_now(address_notification, plugin);
   return api;
 }