remove output
[oweals/gnunet.git] / src / transport / plugin_transport_udp.c
index 228eaeb6cff00a4b44d85f1420f3d85bdff27f9b..be19c5de3005ae5c1259859153051267d4149b62 100644 (file)
@@ -42,6 +42,7 @@
 
 #define LOG(kind,...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__)
 
+#define PLUGIN_NAME "udp"
 
 /**
  * Number of messages we can defragment in parallel.  We only really
  */
 #define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128
 
+/**
+ * Running pretty printers: head
+ */
+static struct PrettyPrinterContext *ppc_dll_head;
 
-#define DEBUG_MALLOC GNUNET_NO
+/**
+ * Running pretty printers: tail
+ */
+static struct PrettyPrinterContext *ppc_dll_tail;
 
 /**
  * Closure for 'append_port'.
  */
 struct PrettyPrinterContext
 {
+       /**
+        * DLL
+        */
+       struct PrettyPrinterContext *next;
+
+       /**
+        * DLL
+        */
+       struct PrettyPrinterContext *prev;
+
+       /**
+        * Timeout task
+        */
+       GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+       /**
+        * Resolver handle
+        */
+       struct GNUNET_RESOLVER_RequestHandle *resolver_handle;
+
   /**
    * Function to call with the result.
    */
@@ -84,6 +112,17 @@ struct PrettyPrinterContext
    * Port to add after the IP address.
    */
   uint16_t port;
+
+  /**
+   * IPv6 address
+   */
+
+  int ipv6;
+
+  /**
+   * Options
+   */
+  uint32_t options;
 };
 
 
@@ -144,6 +183,8 @@ struct Session
   unsigned int rc;
 
   int in_destroy;
+
+  int inbound;
 };
 
 
@@ -386,6 +427,12 @@ struct UDP_ACK_Message
 
 };
 
+/**
+ * Address options
+ */
+static uint32_t myoptions;
+
+
 /**
  * Encapsulation of all of the state of the plugin.
  */
@@ -434,176 +481,6 @@ reschedule_session_timeout (struct Session *s);
 static void
 stop_session_timeout (struct Session *s);
 
-#if DEBUG_MALLOC
-
-struct Allocator
-{
-  struct Allocator *prev;
-  struct Allocator *next;
-
-  unsigned int bytes_alloced;
-  unsigned int max_alloced;
-  unsigned int diff;
-  unsigned int line;
-
-  struct GNUNET_TIME_Absolute max_alloced_when;
-  struct GNUNET_TIME_Absolute last_alloced_when;
-
-};
-
-struct Allocator *aehead;
-struct Allocator *aetail;
-
-struct Allocation
-{
-  struct Allocation *prev;
-  struct Allocation *next;
-
-  struct Allocator *alloc;
-  unsigned int bytes_alloced;
-  void *p;
-  unsigned int line;
-};
-
-struct Allocation *ahead;
-struct Allocation *atail;
-
-static int bytes_alloced;
-
-static struct Allocator *
-find_allocator (int line)
-{
-  struct Allocator *cur = aehead;
-  while (NULL != cur)
-  {
-      if (line == cur->line)
-        return cur;
-      cur = cur->next;
-  }
-  return cur;
-}
-
-static void
-print_allocators ()
-{
-  static int start = GNUNET_YES;
-  static struct GNUNET_TIME_Absolute next;
-  static struct GNUNET_TIME_Relative rem;
-  struct Allocator *cur = aehead;
-  if (start)
-  {
-      next = GNUNET_TIME_UNIT_ZERO_ABS;
-      start = GNUNET_NO;
-  }
-  if (0 == (rem = GNUNET_TIME_absolute_get_remaining(next)).rel_value)
-  {
-      fprintf (stderr, "Allocated in `%s' total: %5u bytes\n", __FILE__, bytes_alloced);
-      while (NULL != cur)
-      {
-          char *last_alloc = GNUNET_strdup (GNUNET_STRINGS_absolute_time_to_string(cur->max_alloced_when));
-          fprintf (stderr, "Allocated from line %4u :%5u bytes (diff %5i bytes, max alloc: %5u @ %s, last alloc %s)\n",
-              cur->line, cur->bytes_alloced, cur->diff, cur->max_alloced,
-              last_alloc,
-              GNUNET_STRINGS_absolute_time_to_string(cur->last_alloced_when));
-          GNUNET_free (last_alloc);
-          cur->diff = 0;
-          cur = cur->next;
-      }
-      fprintf (stderr, "\n");
-    next = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS);
-  }
-}
-
-#endif
-
-static void
-MEMDEBUG_add_alloc (void *p, size_t size, int line)
-{
-#if DEBUG_MALLOC
-  struct Allocation *alloc = GNUNET_malloc (sizeof (struct Allocation));
-  struct Allocator *allocator = find_allocator(line);
-  if (NULL == allocator)
-  {
-      allocator = GNUNET_malloc (sizeof (struct Allocator));
-      allocator->line = line;
-      GNUNET_CONTAINER_DLL_insert (aehead, aetail, allocator);
-  }
-  alloc->alloc = allocator;
-  alloc->p = p;
-  alloc->line = line;
-  alloc->bytes_alloced = size;
-  allocator->bytes_alloced += size;
-  allocator->last_alloced_when = GNUNET_TIME_absolute_get();
-  if (allocator->bytes_alloced >= allocator->max_alloced)
-  {
-      allocator->max_alloced = allocator->bytes_alloced;
-      allocator->max_alloced_when = allocator->last_alloced_when;
-  }
-  allocator->diff += size;
-  GNUNET_CONTAINER_DLL_insert (ahead, atail, alloc);
-  print_allocators ();
-  bytes_alloced += size;
-#endif
-}
-
-
-static void *
-MEMDEBUG_malloc (size_t size, int line)
-{
-  void * ret;
-
-  ret = GNUNET_malloc (size);
-#if DEBUG_MALLOC
-  if (NULL != ret)
-      MEMDEBUG_add_alloc (ret, size, line);
-#endif
-  return ret;
-
-}
-
-static void
-MEMDEBUG_free (void * alloc, int line)
-{
-#if DEBUG_MALLOC
-  struct Allocation *cur;
-  struct Allocator *allocator;
-  cur = ahead;
-  while (NULL != cur)
-  {
-      if (alloc == cur->p)
-        break;
-      cur = cur->next;
-  }
-  if (NULL == cur)
-  {
-    fprintf (stderr, "Unmonitored free from line %4u\n", line);
-    GNUNET_break (0);
-    return;
-  }
-  allocator = cur->alloc;
-  if (NULL == allocator)
-  {
-      GNUNET_break (0);
-  }
-  GNUNET_CONTAINER_DLL_remove (ahead, atail, cur);
-  allocator->bytes_alloced -= cur->bytes_alloced;
-  allocator->diff -= cur->bytes_alloced;
-  GNUNET_assert (allocator->bytes_alloced >= 0);
-  bytes_alloced -= cur->bytes_alloced;
-  GNUNET_assert (bytes_alloced >= 0);
-  GNUNET_free (cur);
-#endif
-  GNUNET_free (alloc);
-}
-
-static void
-MEMDEBUG_free_non_null (void * alloc, int line)
-{
-  if (alloc != NULL)
-    MEMDEBUG_free (alloc, line);
-}
-
-
 /**
  * (re)schedule select tasks for this plugin.
  *
@@ -615,7 +492,7 @@ schedule_select (struct Plugin *plugin)
   struct GNUNET_TIME_Relative min_delay;
   struct UDP_MessageWrapper *udpw;
 
-  if (NULL != plugin->sockv4)
+  if ((GNUNET_YES == plugin->enable_ipv4) && (NULL != plugin->sockv4))
   {
     /* Find a message ready to send:
      * Flow delay from other peer is expired or not set (0) */
@@ -637,7 +514,7 @@ schedule_select (struct Plugin *plugin)
                                   (0 == min_delay.rel_value) ? plugin->ws_v4 : NULL,
                                   &udp_plugin_select, plugin);  
   }
-  if (NULL != plugin->sockv6)
+  if ((GNUNET_YES == plugin->enable_ipv6) && (NULL != plugin->sockv6))
   {
     min_delay = GNUNET_TIME_UNIT_FOREVER_REL;
     for (udpw = plugin->ipv6_queue_head; NULL != udpw; udpw = udpw->next)
@@ -679,11 +556,14 @@ udp_address_to_string (void *cls, const void *addr, size_t addrlen)
   const struct IPv6UdpAddress *t6;
   int af;
   uint16_t port;
+  uint32_t options;
 
+  options = 0;
   if (addrlen == sizeof (struct IPv6UdpAddress))
   {
     t6 = addr;
     af = AF_INET6;
+    options = ntohl (t6->options);
     port = ntohs (t6->u6_port);
     memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
     sb = &a6;
@@ -692,18 +572,24 @@ udp_address_to_string (void *cls, const void *addr, size_t addrlen)
   {
     t4 = addr;
     af = AF_INET;
+    options = ntohl (t4->options);
     port = ntohs (t4->u4_port);
     memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
     sb = &a4;
   }
+  else if (addrlen == 0)
+       {
+               GNUNET_snprintf (rbuf, sizeof (rbuf), "%s", TRANSPORT_SESSION_INBOUND_STRING);
+               return rbuf;
+       }
   else
   {
-    GNUNET_break_op (0);
     return NULL;
   }
   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
-  GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "[%s]:%u" : "%s:%u",
-                   buf, port);
+
+  GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "%s.%u.[%s]:%u" : "%s.%u.%s:%u",
+                   PLUGIN_NAME, options, buf, port);
   return rbuf;
 }
 
@@ -725,36 +611,71 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
     void **buf, size_t *added)
 {
   struct sockaddr_storage socket_address;
-  
-  if ((NULL == addr) || (0 == addrlen))
+  char *address;
+  char *plugin;
+  char *optionstr;
+  uint32_t options;
+
+  /* Format tcp.options.address:port */
+  address = NULL;
+  plugin = NULL;
+  optionstr = NULL;
+  options = 0;
+  if ((NULL == addr) || (addrlen == 0))
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-
   if ('\0' != addr[addrlen - 1])
   {
+    GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-
   if (strlen (addr) != addrlen - 1)
   {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  plugin = GNUNET_strdup (addr);
+  optionstr = strchr (plugin, '.');
+  if (NULL == optionstr)
+  {
+    GNUNET_break (0);
+    GNUNET_free (plugin);
     return GNUNET_SYSERR;
   }
+  optionstr[0] = '\0';
+  optionstr ++;
+  options = atol (optionstr);
+  address = strchr (optionstr, '.');
+  if (NULL == address)
+  {
+    GNUNET_break (0);
+    GNUNET_free (plugin);
+    return GNUNET_SYSERR;
+  }
+  address[0] = '\0';
+  address ++;
 
-  if (GNUNET_OK != GNUNET_STRINGS_to_address_ip (addr, strlen (addr),
-                                                &socket_address))
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_to_address_ip (address, strlen (address),
+                                   &socket_address))
   {
+    GNUNET_break (0);
+    GNUNET_free (plugin);
     return GNUNET_SYSERR;
   }
 
+  GNUNET_free (plugin);
+
   switch (socket_address.ss_family)
   {
   case AF_INET:
     {
       struct IPv4UdpAddress *u4;
       struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address;
-      u4 = MEMDEBUG_malloc (sizeof (struct IPv4UdpAddress), __LINE__ );
+      u4 = GNUNET_malloc (sizeof (struct IPv4UdpAddress));
+      u4->options =  htonl (options);
       u4->ipv4_addr = in4->sin_addr.s_addr;
       u4->u4_port = in4->sin_port;
       *buf = u4;
@@ -765,7 +686,8 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
     {
       struct IPv6UdpAddress *u6;
       struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address;
-      u6 = MEMDEBUG_malloc (sizeof (struct IPv6UdpAddress),  __LINE__ );
+      u6 = GNUNET_malloc (sizeof (struct IPv6UdpAddress));
+      u6->options =  htonl (options);
       u6->ipv6_addr = in6->sin6_addr;
       u6->u6_port = in6->sin6_port;
       *buf = u6;
@@ -779,6 +701,23 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
 }
 
 
+void
+ppc_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+       struct PrettyPrinterContext *ppc = cls;
+       /* GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PPC %p was not removed!\n", ppc); */
+       ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+       if (NULL != ppc->resolver_handle)
+       {
+               GNUNET_RESOLVER_request_cancel (ppc->resolver_handle);
+               ppc->resolver_handle = NULL;
+       }
+
+       GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc);
+       GNUNET_free (ppc);
+}
+
+
 /**
  * Append our port and forward the result.
  *
@@ -789,21 +728,39 @@ static void
 append_port (void *cls, const char *hostname)
 {
   struct PrettyPrinterContext *ppc = cls;
+  struct PrettyPrinterContext *cur;
   char *ret;
-
+       /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC callback: %p `%s'\n",ppc, hostname); */
   if (hostname == NULL)
   {
     ppc->asc (ppc->asc_cls, NULL);
-    MEMDEBUG_free (ppc, __LINE__);
+    GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc);
+    GNUNET_SCHEDULER_cancel (ppc->timeout_task);
+    ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+    ppc->resolver_handle = NULL;
+       /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was removed!\n", ppc); */
+    GNUNET_free (ppc);
     return;
   }
-  GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
-  MEMDEBUG_add_alloc (ret, strlen (ret)+ 1, __LINE__);
+  for (cur = ppc_dll_head; (NULL != cur); cur = cur->next)
+  {
+       if (cur == ppc)
+               break;
+  }
+  if (NULL == cur)
+  {
+       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid callback for PPC %p \n", ppc);
+       return;
+  }
+
+  if (GNUNET_YES == ppc->ipv6)
+    GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port);
+  else
+    GNUNET_asprintf (&ret, "%s.%u.%s:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port);
   ppc->asc (ppc->asc_cls, ret);
-  MEMDEBUG_free (ret, __LINE__);
+  GNUNET_free (ret);
 }
 
-
 /**
  * Convert the transports address to a nice, human-readable
  * format.
@@ -834,7 +791,9 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
   const struct IPv4UdpAddress *u4;
   const struct IPv6UdpAddress *u6;
   uint16_t port;
+  uint32_t options;
 
+  options = 0;
   if (addrlen == sizeof (struct IPv6UdpAddress))
   {
     u6 = addr;
@@ -846,6 +805,7 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
     a6.sin6_port = u6->u6_port;
     memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof (struct in6_addr));
     port = ntohs (u6->u6_port);
+    options = ntohl (u6->options);
     sb = &a6;
     sbs = sizeof (a6);
   }
@@ -860,12 +820,13 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
     a4.sin_port = u4->u4_port;
     a4.sin_addr.s_addr = u4->ipv4_addr;
     port = ntohs (u4->u4_port);
+    options = ntohl (u4->options);
     sb = &a4;
     sbs = sizeof (a4);
   }
   else if (0 == addrlen)
   {
-    asc (asc_cls, "<inbound connection>");
+    asc (asc_cls, TRANSPORT_SESSION_INBOUND_STRING);
     asc (asc_cls, NULL);
     return;
   }
@@ -876,11 +837,21 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
     asc (asc_cls, NULL);
     return;
   }
-  ppc = MEMDEBUG_malloc (sizeof (struct PrettyPrinterContext),  __LINE__ );
+  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);
+  ppc->options = options;
+  if (addrlen == sizeof (struct IPv6UdpAddress))
+    ppc->ipv6 = GNUNET_YES;
+  else
+    ppc->ipv6 = GNUNET_NO;
+  ppc->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(timeout, 2),
+               &ppc_cancel_task, ppc);
+  GNUNET_CONTAINER_DLL_insert (ppc_dll_head, ppc_dll_tail, ppc);
+       /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was created!\n", ppc); */
+  ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
+
 }
 
 
@@ -1097,7 +1068,6 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
   if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
       (addrlen != sizeof (struct IPv6UdpAddress)))
   {
-    GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
   if (addrlen == sizeof (struct IPv4UdpAddress))
@@ -1140,10 +1110,10 @@ free_session (struct Session *s)
   if (NULL != s->frag_ctx)
   {
     GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag, NULL, NULL);
-    MEMDEBUG_free (s->frag_ctx, __LINE__);
+    GNUNET_free (s->frag_ctx);
     s->frag_ctx = NULL;
   }
-  MEMDEBUG_free (s, __LINE__);
+  GNUNET_free (s);
 }
 
 
@@ -1203,7 +1173,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc, int result)
       {
         dequeue (plugin, udpw);
         call_continuation (udpw, GNUNET_SYSERR);
-        MEMDEBUG_free (udpw, __LINE__);
+        GNUNET_free (udpw);
       }
       udpw = tmp;
     }
@@ -1218,7 +1188,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc, int result)
       {
         dequeue (plugin, udpw);
         call_continuation (udpw, GNUNET_SYSERR);
-        MEMDEBUG_free (udpw, __LINE__);
+        GNUNET_free (udpw);
       }
       udpw = tmp;
     }
@@ -1229,7 +1199,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc, int result)
                                      &s->last_expected_msg_delay,
                                      &s->last_expected_ack_delay);
   s->frag_ctx = NULL;
-  MEMDEBUG_free (fc , __LINE__);
+  GNUNET_free (fc );
 }
 
 /**
@@ -1267,7 +1237,7 @@ disconnect_session (struct Session *s)
     {
       dequeue (plugin, udpw);
       call_continuation(udpw, GNUNET_SYSERR);
-      MEMDEBUG_free (udpw, __LINE__);
+      GNUNET_free (udpw);
     }
   }
   next = plugin->ipv6_queue_head;
@@ -1278,7 +1248,7 @@ disconnect_session (struct Session *s)
     {
       dequeue (plugin, udpw);
       call_continuation(udpw, GNUNET_SYSERR);
-      MEMDEBUG_free (udpw, __LINE__);
+      GNUNET_free (udpw);
     }
     udpw = next;
   }
@@ -1437,10 +1407,14 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
   case sizeof (struct IPv4UdpAddress):
     if (NULL == plugin->sockv4)
     {
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Could not create session for peer `%s' address `%s': IPv4 is not enabled\n",
+           GNUNET_i2s(target),
+           udp_address_to_string(NULL, addr, addrlen));
       return NULL;
     }
     t4 = addr;
-    s = MEMDEBUG_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in),  __LINE__ );
+    s = GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in));
     len = sizeof (struct sockaddr_in);
     v4 = (struct sockaddr_in *) &s[1];
     v4->sin_family = AF_INET;
@@ -1454,11 +1428,15 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
   case sizeof (struct IPv6UdpAddress):
     if (NULL == plugin->sockv6)
     {
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           "Could not create session for peer `%s' address `%s': IPv6 is not enabled\n",
+           GNUNET_i2s(target),
+           udp_address_to_string(NULL, addr, addrlen));
       return NULL;
     }
     t6 = addr;
     s =
-        MEMDEBUG_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6),  __LINE__ );
+        GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6));
     len = sizeof (struct sockaddr_in6);
     v6 = (struct sockaddr_in6 *) &s[1];
     v6->sin6_family = AF_INET6;
@@ -1471,7 +1449,10 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
     break;
   default:
     /* Must have a valid address to send to */
-    GNUNET_break_op (0);
+    GNUNET_STATISTICS_update (plugin->env->stats,
+                              gettext_noop
+                              ("# requests to create session with invalid address"),
+                              1, GNUNET_NO);
     return NULL;
   }
   s->addrlen = len;
@@ -1481,6 +1462,7 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
   s->last_expected_msg_delay = GNUNET_TIME_UNIT_MILLISECONDS;
   s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS;
   s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO;
+  s->inbound = GNUNET_NO;
   start_session_timeout (s);
   return s;
 }
@@ -1531,6 +1513,21 @@ session_cmp_it (void *cls,
 }
 
 
+/**
+ * Function obtain the network type for a session
+ *
+ * @param cls closure ('struct Plugin*')
+ * @param session the session
+ * @return the network type in HBO or GNUNET_SYSERR
+ */
+static enum GNUNET_ATS_Network_Type
+udp_get_network (void *cls, 
+                struct Session *session)
+{
+  return ntohl (session->ats.value);
+}
+
+
 /**
  * Creates a new outbound session the transport service will use to send data to the
  * peer
@@ -1540,10 +1537,9 @@ session_cmp_it (void *cls,
  * @return the session or NULL of max connections exceeded
  */
 static struct Session *
-udp_plugin_get_session (void *cls,
-                  const struct GNUNET_HELLO_Address *address)
+udp_plugin_lookup_session (void *cls,
+                 const struct GNUNET_HELLO_Address *address)
 {
-  struct Session * s = NULL;
   struct Plugin * plugin = cls;
   struct IPv6UdpAddress * udp_a6;
   struct IPv4UdpAddress * udp_a4;
@@ -1556,7 +1552,11 @@ udp_plugin_get_session (void *cls,
       ((address->address_length != sizeof (struct IPv4UdpAddress)) &&
       (address->address_length != sizeof (struct IPv6UdpAddress))))
   {
-    GNUNET_break (0);
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+       _("Trying to create session for address of unexpected length %u (should be %u or %u)\n"),
+       address->address_length,
+       sizeof (struct IPv4UdpAddress),
+       sizeof (struct IPv6UdpAddress));
     return NULL;
   }
 
@@ -1592,6 +1592,14 @@ udp_plugin_get_session (void *cls,
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Found existing session %p\n", cctx.res);
     return cctx.res;
   }
+  return NULL;
+}
+
+static struct Session *
+udp_plugin_create_session (void *cls,
+                  const struct GNUNET_HELLO_Address *address)
+{
+  struct Session * s = NULL;
 
   /* otherwise create new */
   s = create_session (plugin,
@@ -1599,6 +1607,8 @@ udp_plugin_get_session (void *cls,
       address->address,
       address->address_length,
       NULL, NULL);
+  if (NULL == s)
+       return NULL; /* protocol not supported or address invalid */
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Creating new session %p for peer `%s' address `%s'\n",
        s,
@@ -1616,6 +1626,39 @@ udp_plugin_get_session (void *cls,
   return s;
 }
 
+
+
+/**
+ * Creates a new outbound session the transport service will use to send data to the
+ * peer
+ *
+ * @param cls the plugin
+ * @param address the address
+ * @return the session or NULL of max connections exceeded
+ */
+static struct Session *
+udp_plugin_get_session (void *cls,
+                  const struct GNUNET_HELLO_Address *address)
+{
+  struct Session * s = NULL;
+
+  if (NULL == address)
+  {
+       GNUNET_break (0);
+       return NULL;
+  }
+  if ((address->address_length != sizeof (struct IPv4UdpAddress)) &&
+               (address->address_length != sizeof (struct IPv6UdpAddress)))
+               return NULL;
+
+  /* otherwise create new */
+  if (NULL != (s = udp_plugin_lookup_session(cls, address)))
+       return s;
+  else
+       return udp_plugin_create_session (cls, address);
+}
+
+
 static void 
 enqueue (struct Plugin *plugin, struct UDP_MessageWrapper * udpw)
 {
@@ -1681,7 +1724,7 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
   LOG (GNUNET_ERROR_TYPE_DEBUG, 
        "Enqueuing fragment with %u bytes\n", msg_len);
   frag_ctx->fragments_used ++;
-  udpw = MEMDEBUG_malloc (sizeof (struct UDP_MessageWrapper) + msg_len,  __LINE__ );
+  udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msg_len);
   udpw->session = frag_ctx->session;
   udpw->msg_buf = (char *) &udpw[1];
   udpw->msg_size = msg_len;
@@ -1773,7 +1816,7 @@ udp_plugin_send (void *cls,
   if (udpmlen <= UDP_MTU)
   {
     /* unfragmented message */
-    udpw = MEMDEBUG_malloc (sizeof (struct UDP_MessageWrapper) + udpmlen,  __LINE__ );
+    udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + udpmlen);
     udpw->session = s;
     udpw->msg_buf = (char *) &udpw[1];
     udpw->msg_size = udpmlen; /* message size with UDP overhead */
@@ -1800,7 +1843,7 @@ udp_plugin_send (void *cls,
     if  (s->frag_ctx != NULL)
       return GNUNET_SYSERR;
     memcpy (&udp[1], msgbuf, msgbuf_size);
-    frag_ctx = MEMDEBUG_malloc (sizeof (struct UDP_FragmentationContext), __LINE__ );
+    frag_ctx = GNUNET_malloc (sizeof (struct UDP_FragmentationContext));
     frag_ctx->plugin = plugin;
     frag_ctx->session = s;
     frag_ctx->cont = cont;
@@ -1861,18 +1904,26 @@ udp_nat_port_map_callback (void *cls, int add_remove,
   {
   case AF_INET:
     GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
+    memset (&u4, 0, sizeof (u4));
+    u4.options = htonl(myoptions);
     u4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
     u4.u4_port = ((struct sockaddr_in *) addr)->sin_port;
+    if (0 == ((struct sockaddr_in *) addr)->sin_port)
+       return;
     arg = &u4;
-    args = sizeof (u4);
+    args = sizeof (struct IPv4UdpAddress);
     break;
   case AF_INET6:
     GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
+    memset (&u4, 0, sizeof (u4));
+    u6.options = htonl(myoptions);
+    if (0 == ((struct sockaddr_in6 *) addr)->sin6_port)
+       return;
     memcpy (&u6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr,
             sizeof (struct in6_addr));
     u6.u6_port = ((struct sockaddr_in6 *) addr)->sin6_port;
     arg = &u6;
-    args = sizeof (u6);
+    args = sizeof (struct IPv6UdpAddress);
     break;
   default:
     GNUNET_break (0);
@@ -1909,13 +1960,13 @@ process_inbound_tokenized_messages (void *cls, void *client,
                                &si->sender,
                                hdr,
                                si->session,
-                               si->arg,
-                               si->args);
+                (GNUNET_YES == si->session->inbound) ? NULL : si->arg,
+                (GNUNET_YES == si->session->inbound) ? 0 : si->args);
 
   plugin->env->update_address_metrics (plugin->env->cls,
                                       &si->sender,
-                                      si->arg,
-                                      si->args,
+                                        (GNUNET_YES == si->session->inbound) ? NULL : si->arg,
+                                        (GNUNET_YES == si->session->inbound) ? 0 : si->args,
                                       si->session,
                                       &si->session->ats, 1);
 
@@ -1962,6 +2013,8 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
   {
   case AF_INET:
     GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in));
+    memset (&u4, 0, sizeof (u4));
+    u6.options = htonl (0);
     u4.ipv4_addr = ((struct sockaddr_in *) sender_addr)->sin_addr.s_addr;
     u4.u4_port = ((struct sockaddr_in *) sender_addr)->sin_port;
     arg = &u4;
@@ -1969,6 +2022,8 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
     break;
   case AF_INET6:
     GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in6));
+    memset (&u6, 0, sizeof (u6));
+    u6.options = htonl (0);
     u6.ipv6_addr = ((struct sockaddr_in6 *) sender_addr)->sin6_addr;
     u6.u6_port = ((struct sockaddr_in6 *) sender_addr)->sin6_port;
     arg = &u6;
@@ -1984,9 +2039,16 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
        GNUNET_a2s (sender_addr, sender_addr_len));
 
   struct GNUNET_HELLO_Address * address = GNUNET_HELLO_address_allocate(&msg->sender, "udp", arg, args);
-  MEMDEBUG_add_alloc (address, GNUNET_HELLO_address_get_size(address), __LINE__);
-  s = udp_plugin_get_session(plugin, address);
-  MEMDEBUG_free (address, __LINE__);
+  if (NULL == (s = udp_plugin_lookup_session (plugin, address)))
+  {
+               s = udp_plugin_create_session(plugin, address);
+               s->inbound = GNUNET_YES;
+         plugin->env->session_start (NULL, &address->peer, PLUGIN_NAME,
+                       (GNUNET_YES == s->inbound) ? NULL : address->address,
+                       (GNUNET_YES == s->inbound) ? 0 : address->address_length,
+                 s, NULL, 0);
+  }
+  GNUNET_free (address);
 
   /* iterate over all embedded messages */
   si.session = s;
@@ -2121,7 +2183,7 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
                     AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct
                                                                      sockaddr_in6)),
        delay);
-  udpw = MEMDEBUG_malloc (sizeof (struct UDP_MessageWrapper) + msize,  __LINE__ );
+  udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msize);
   udpw->msg_size = msize;
   udpw->payload_size = 0;
   udpw->session = s;
@@ -2250,7 +2312,7 @@ read_process_fragment (struct Plugin *plugin,
   if (d_ctx == NULL)
   {
     /* Create a new defragmentation context */
-    d_ctx = MEMDEBUG_malloc (sizeof (struct DefragContext) + fromlen,  __LINE__ );
+    d_ctx = GNUNET_malloc (sizeof (struct DefragContext) + fromlen);
     memcpy (&d_ctx[1], addr, fromlen);
     d_ctx->src_addr = (const struct sockaddr *) &d_ctx[1];
     d_ctx->addr_len = fromlen;
@@ -2290,7 +2352,7 @@ read_process_fragment (struct Plugin *plugin,
     d_ctx = GNUNET_CONTAINER_heap_remove_root (plugin->defrag_ctxs);
     GNUNET_assert (NULL != d_ctx);
     GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag);
-    MEMDEBUG_free (d_ctx, __LINE__);
+    GNUNET_free (d_ctx);
   }
 }
 
@@ -2421,7 +2483,7 @@ remove_timeout_messages_and_select (struct UDP_MessageWrapper *head,
           call_continuation (udpw, GNUNET_SYSERR);
           /* Remove message */
           dequeue (plugin, udpw);
-          MEMDEBUG_free (udpw, __LINE__);
+          GNUNET_free (udpw);
           break;
         case MSG_FRAGMENTED:
           /* Fragmented message */
@@ -2458,7 +2520,7 @@ remove_timeout_messages_and_select (struct UDP_MessageWrapper *head,
                GNUNET_i2s(&udpw->session->target), udpw->payload_size);
           call_continuation (udpw, GNUNET_SYSERR);
           dequeue (plugin, udpw);
-          MEMDEBUG_free (udpw, __LINE__);
+          GNUNET_free (udpw);
           break;
         default:
           break;
@@ -2600,7 +2662,7 @@ udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock)
     call_continuation (udpw, GNUNET_OK);
   }
   dequeue (plugin, udpw);
-  MEMDEBUG_free (udpw, __LINE__);
+  GNUNET_free (udpw);
   udpw = NULL;
 
   return sent;
@@ -2664,8 +2726,14 @@ udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 }
 
 
+/**
+ *
+ * @return number of sockets that were successfully bound
+ */
 static int
-setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct sockaddr_in *bind_v4)
+setup_sockets (struct Plugin *plugin, 
+              const struct sockaddr_in6 *bind_v6,
+              const struct sockaddr_in *bind_v4)
 {
   int tries;
   int sockets_created = 0;
@@ -2675,13 +2743,16 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct socka
   struct sockaddr *addrs[2];
   socklen_t addrlens[2];
   socklen_t addrlen;
+  int eno;
 
   /* Create IPv6 socket */
+  eno = EINVAL;
   if (plugin->enable_ipv6 == GNUNET_YES)
   {
     plugin->sockv6 = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0);
     if (NULL == plugin->sockv6)
     {
+       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
       LOG (GNUNET_ERROR_TYPE_WARNING, "Disabling IPv6 since it is not supported on this system!\n");
       plugin->enable_ipv6 = GNUNET_NO;
     }
@@ -2697,40 +2768,36 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct socka
       else
        serverAddrv6.sin6_addr = in6addr_any;
 
-      if (0 == plugin->port)
-               /* autodetect */
+      if (0 == plugin->port) /* autodetect */
                serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);
       else
                serverAddrv6.sin6_port = htons (plugin->port);
-
-
       addrlen = sizeof (struct sockaddr_in6);
       serverAddr = (struct sockaddr *) &serverAddrv6;
 
       tries = 0;
       while (tries < 10)
       {
-          LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 `%s'\n",
-               GNUNET_a2s (serverAddr, addrlen));
-
-          /* binding */
-          if (GNUNET_OK == GNUNET_NETWORK_socket_bind (plugin->sockv6, serverAddr, addrlen))
-                       break;
-
+               LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv6 `%s'\n",
+                                GNUNET_a2s (serverAddr, addrlen));
+               /* binding */
+               if (GNUNET_OK == GNUNET_NETWORK_socket_bind (plugin->sockv6,
+                                                            serverAddr, addrlen, 0))
+                       break;
+               eno = errno;
                if (0 != plugin->port)
                {
-                       tries = 10; /* fail */
-                       break; /* bind failed on specific port */
+                               tries = 10; /* fail */
+                               break; /* bind failed on specific port */
                }
-
                /* autodetect */
                serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);
                tries ++;
       }
-
       if (tries >= 10)
       {
         GNUNET_NETWORK_socket_close (plugin->sockv6);
+        plugin->enable_ipv6 = GNUNET_NO;
         plugin->sockv6 = NULL;
       }
 
@@ -2746,98 +2813,109 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct socka
       else
       {
           LOG (GNUNET_ERROR_TYPE_ERROR,
-               "Failed to create IPv6 socket created on %s\n",
-               GNUNET_a2s (serverAddr, addrlen));
+               "Failed to bind UDP socket to %s: %s\n",
+               GNUNET_a2s (serverAddr, addrlen),
+              STRERROR (eno));
       }
     }
   }
 
   /* Create IPv4 socket */
-       plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
-       if (NULL == plugin->sockv4)
-       {
-               LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create IPv4 socket!\n");
-               return sockets_created;
-       }
-       else
-       {
-               memset (&serverAddrv4, '\0', sizeof (struct sockaddr_in));
+  eno = EINVAL;
+  plugin->sockv4 = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0);
+  if (NULL == plugin->sockv4)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
+    LOG (GNUNET_ERROR_TYPE_WARNING, "Disabling IPv4 since it is not supported on this system!\n");
+    plugin->enable_ipv4 = GNUNET_NO;
+  }
+  else
+  {
+    memset (&serverAddrv4, '\0', sizeof (struct sockaddr_in));
 #if HAVE_SOCKADDR_IN_SIN_LEN
-               serverAddrv4.sin_len = sizeof (struct sockaddr_in);
+    serverAddrv4.sin_len = sizeof (struct sockaddr_in);
 #endif
-               serverAddrv4.sin_family = AF_INET;
-               if (NULL != bind_v4)
-                       serverAddrv4.sin_addr = bind_v4->sin_addr;
-               else
-                       serverAddrv4.sin_addr.s_addr = INADDR_ANY;
-
-               if (0 == plugin->port)
-                               /* autodetect */
-                               serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);
-               else
-                               serverAddrv4.sin_port = htons (plugin->port);
-
-
-               addrlen = sizeof (struct sockaddr_in);
-               serverAddr = (struct sockaddr *) &serverAddrv4;
-
-               tries = 0;
-               while (tries < 10)
-               {
-                               LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv4 `%s'\n",
-                                                GNUNET_a2s (serverAddr, addrlen));
-
-                               /* binding */
-                               if (GNUNET_OK == GNUNET_NETWORK_socket_bind (plugin->sockv4, serverAddr, addrlen))
-                                               break;
-
-                               if (0 != plugin->port)
-                               {
-                                       tries = 10; /* fail */
-                                       break; /* bind failed on specific port */
-                               }
-
-                               /* autodetect */
-                               serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);
-                               tries ++;
-               }
-
-               if (tries >= 10)
-               {
-                       GNUNET_NETWORK_socket_close (plugin->sockv4);
-                       plugin->sockv4 = NULL;
-               }
-
-               if (plugin->sockv4 != NULL)
-               {
-                       LOG (GNUNET_ERROR_TYPE_DEBUG,
-                                        "IPv4 socket created on port %s\n",
-                                        GNUNET_a2s (serverAddr, addrlen));
-                       addrs[sockets_created] = (struct sockaddr *) &serverAddrv4;
-                       addrlens[sockets_created] = sizeof (struct sockaddr_in);
-                       sockets_created++;
-               }
-               else
-               {
-                               LOG (GNUNET_ERROR_TYPE_ERROR,
-                                                "Failed to create IPv4 socket created on %s\n",
-                                                GNUNET_a2s (serverAddr, addrlen));
-               }
-       }
+    serverAddrv4.sin_family = AF_INET;
+    if (NULL != bind_v4)
+      serverAddrv4.sin_addr = bind_v4->sin_addr;
+    else
+      serverAddrv4.sin_addr.s_addr = INADDR_ANY;
+    
+    if (0 == plugin->port)
+      /* autodetect */
+      serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);
+    else
+      serverAddrv4.sin_port = htons (plugin->port);
+    
+    
+    addrlen = sizeof (struct sockaddr_in);
+    serverAddr = (struct sockaddr *) &serverAddrv4;
+    
+    tries = 0;
+    while (tries < 10)
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "Binding to IPv4 `%s'\n",
+                       GNUNET_a2s (serverAddr, addrlen));
+      
+      /* binding */
+      if (GNUNET_OK == GNUNET_NETWORK_socket_bind (plugin->sockv4,
+                                                   serverAddr, addrlen, 0))
+               break;
+      eno = errno;
+      if (0 != plugin->port)
+      {
+               tries = 10; /* fail */
+               break; /* bind failed on specific port */
+      }
+      
+      /* autodetect */
+      serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000);
+      tries ++;
+    }
+    
+    if (tries >= 10)
+    {
+      GNUNET_NETWORK_socket_close (plugin->sockv4);
+      plugin->enable_ipv4 = GNUNET_NO;
+      plugin->sockv4 = NULL;
+    }
+    
+    if (plugin->sockv4 != NULL)
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+               "IPv4 socket created on port %s\n", GNUNET_a2s (serverAddr, addrlen));
+      addrs[sockets_created] = (struct sockaddr *) &serverAddrv4;
+      addrlens[sockets_created] = sizeof (struct sockaddr_in);
+      sockets_created++;
+    }
+    else
+    {            
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+               "Failed to bind UDP socket to %s: %s\n",
+               GNUNET_a2s (serverAddr, addrlen), STRERROR (eno));
+    }
+  }
+  
+  if (0 == sockets_created)
+  {
+               LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n"));
+               return 0; /* No sockets created, return */
+  }
 
   /* Create file descriptors */
-  plugin->rs_v4 = GNUNET_NETWORK_fdset_create ();
-  plugin->ws_v4 = GNUNET_NETWORK_fdset_create ();
-  GNUNET_NETWORK_fdset_zero (plugin->rs_v4);
-  GNUNET_NETWORK_fdset_zero (plugin->ws_v4);
-  if (NULL != plugin->sockv4)
+  if (plugin->enable_ipv4 == GNUNET_YES)
   {
-    GNUNET_NETWORK_fdset_set (plugin->rs_v4, plugin->sockv4);
-    GNUNET_NETWORK_fdset_set (plugin->ws_v4, plugin->sockv4);
+                       plugin->rs_v4 = GNUNET_NETWORK_fdset_create ();
+                       plugin->ws_v4 = GNUNET_NETWORK_fdset_create ();
+                       GNUNET_NETWORK_fdset_zero (plugin->rs_v4);
+                       GNUNET_NETWORK_fdset_zero (plugin->ws_v4);
+                       if (NULL != plugin->sockv4)
+                       {
+                               GNUNET_NETWORK_fdset_set (plugin->rs_v4, plugin->sockv4);
+                               GNUNET_NETWORK_fdset_set (plugin->ws_v4, plugin->sockv4);
+                       }
   }
 
-  if (0 == sockets_created)
-    LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n"));
   if (plugin->enable_ipv6 == GNUNET_YES)
   {
     plugin->rs_v6 = GNUNET_NETWORK_fdset_create ();
@@ -2850,6 +2928,7 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *bind_v6, struct socka
       GNUNET_NETWORK_fdset_set (plugin->ws_v6, plugin->sockv6);
     }
   }
+
   schedule_select (plugin);
   plugin->nat = GNUNET_NAT_register (plugin->env->cfg,
                            GNUNET_NO, plugin->port,
@@ -2893,7 +2972,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
   {
     /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully
        initialze the plugin or the API */
-    api = MEMDEBUG_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions),  __LINE__ );
+    api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
     api->cls = NULL;
     api->address_pretty_printer = &udp_plugin_address_pretty_printer;
     api->address_to_string = &udp_address_to_string;
@@ -2901,7 +2980,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
     return api;
   }
 
-  GNUNET_assertNULL != env->stats);
+  GNUNET_assert (NULL != env->stats);
 
   /* Get port number: port == 0 : autodetect a port,
    *                                                                                           > 0 : use this port,
@@ -2926,9 +3005,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
   if ((GNUNET_YES ==
        GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "nat",
                                              "DISABLEV6")))
-  {
     enable_v6 = GNUNET_NO;
-  }
   else
     enable_v6 = GNUNET_YES;
 
@@ -2944,11 +3021,12 @@ libgnunet_plugin_transport_udp_init (void *cls)
          bind4_address);
     if (1 != inet_pton (AF_INET, bind4_address, &serverAddrv4.sin_addr))
     {
-      MEMDEBUG_free (bind4_address, __LINE__);
+      GNUNET_free (bind4_address);
       return NULL;
     }
     have_bind4 = GNUNET_YES;
   }
+  GNUNET_free_non_null (bind4_address);
   have_bind6 = GNUNET_NO;
   memset (&serverAddrv6, 0, sizeof (serverAddrv6));
   if (GNUNET_YES ==
@@ -2963,12 +3041,15 @@ libgnunet_plugin_transport_udp_init (void *cls)
     {
       LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid IPv6 address: `%s'\n"),
            bind6_address);
-      MEMDEBUG_free_non_null (bind4_address, __LINE__);
-      MEMDEBUG_free (bind6_address, __LINE__);
+      GNUNET_free (bind6_address);
       return NULL;
     }
     have_bind6 = GNUNET_YES;
   }
+  GNUNET_free_non_null (bind6_address);
+
+  /* Initialize my flags */
+  myoptions = 0;
 
   /* Enable neighbour discovery */
   broadcast = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "transport-udp",
@@ -2983,12 +3064,11 @@ libgnunet_plugin_transport_udp_init (void *cls)
   }
   else
   {
-     MEMDEBUG_add_alloc (fancy_interval, strlen (fancy_interval)+ 1, __LINE__);
      if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_relative(fancy_interval, &interval))
      {
        interval = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30);
      }
-     MEMDEBUG_free (fancy_interval, __LINE__);
+     GNUNET_free (fancy_interval);
   }
 
   /* Maximum datarate */
@@ -2998,51 +3078,51 @@ libgnunet_plugin_transport_udp_init (void *cls)
     udp_max_bps = 1024 * 1024 * 50;     /* 50 MB/s == infinity for practical purposes */
   }
 
-  p = MEMDEBUG_malloc (sizeof (struct Plugin),  __LINE__ );
-  api = MEMDEBUG_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions), __LINE__ );
-
-  GNUNET_BANDWIDTH_tracker_init (&p->tracker,
-                                 GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30);
-  p->sessions = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
-  p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
-  p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p);
+  p = GNUNET_malloc (sizeof (struct Plugin));
   p->port = port;
   p->aport = aport;
   p->broadcast_interval = interval;
   p->enable_ipv6 = enable_v6;
+  p->enable_ipv4 = GNUNET_YES; /* default */
   p->env = env;
-
+  p->sessions = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
+  p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
+  p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p);
+  GNUNET_BANDWIDTH_tracker_init (&p->tracker,
+                                 GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30);
   plugin = p;
 
-  api->cls = p;
-  api->send = NULL;
-  api->disconnect = &udp_disconnect;
-  api->address_pretty_printer = &udp_plugin_address_pretty_printer;
-  api->address_to_string = &udp_address_to_string;
-  api->string_to_address = &udp_string_to_address;
-  api->check_address = &udp_plugin_check_address;
-  api->get_session = &udp_plugin_get_session;
-  api->send = &udp_plugin_send;
-
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n");
   res = setup_sockets (p, (GNUNET_YES == have_bind6) ? &serverAddrv6 : NULL,
-                                                                                               (GNUNET_YES == have_bind4) ? &serverAddrv4 : NULL);
+                                                                               (GNUNET_YES == have_bind4) ? &serverAddrv4 : NULL);
   if ((res == 0) || ((p->sockv4 == NULL) && (p->sockv6 == NULL)))
   {
-    LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create network sockets, plugin failed\n");
-    MEMDEBUG_free (p, __LINE__);
-    MEMDEBUG_free (api, __LINE__);
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+        _("Failed to create network sockets, plugin failed\n"));
+    GNUNET_CONTAINER_multihashmap_destroy (p->sessions);
+    GNUNET_CONTAINER_heap_destroy (p->defrag_ctxs);
+    GNUNET_SERVER_mst_destroy (p->mst);
+    GNUNET_free (p);
     return NULL;
   }
-
-  if (broadcast == GNUNET_YES)
+  else if (broadcast == GNUNET_YES)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n");
     setup_broadcast (p, &serverAddrv6, &serverAddrv4);
   }
 
-  MEMDEBUG_free_non_null (bind4_address, __LINE__);
-  MEMDEBUG_free_non_null (bind6_address, __LINE__);
+  api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
+  api->cls = p;
+  api->send = NULL;
+  api->disconnect = &udp_disconnect;
+  api->address_pretty_printer = &udp_plugin_address_pretty_printer;
+  api->address_to_string = &udp_address_to_string;
+  api->string_to_address = &udp_string_to_address;
+  api->check_address = &udp_plugin_check_address;
+  api->get_session = &udp_plugin_get_session;
+  api->send = &udp_plugin_send;
+  api->get_network = &udp_get_network;
+
   return api;
 }
 
@@ -3058,7 +3138,7 @@ heap_cleanup_iterator (void *cls,
 
   GNUNET_CONTAINER_heap_remove_node (node);
   GNUNET_DEFRAGMENT_context_destroy(d_ctx->defrag);
-  MEMDEBUG_free (d_ctx, __LINE__);
+  GNUNET_free (d_ctx);
 
   return GNUNET_YES;
 }
@@ -3076,10 +3156,12 @@ libgnunet_plugin_transport_udp_done (void *cls)
 {
   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
   struct Plugin *plugin = api->cls;
+  struct PrettyPrinterContext *cur;
+  struct PrettyPrinterContext *next;
 
   if (NULL == plugin)
   {
-    MEMDEBUG_free (api, __LINE__);
+    GNUNET_free (api);
     return NULL;
   }
 
@@ -3096,24 +3178,29 @@ libgnunet_plugin_transport_udp_done (void *cls)
   }
 
   /* Closing sockets */
-  if (plugin->sockv4 != NULL)
+  if (GNUNET_YES ==plugin->enable_ipv4)
   {
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4));
-    plugin->sockv4 = NULL;
+               if (plugin->sockv4 != NULL)
+               {
+                       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv4));
+                       plugin->sockv4 = NULL;
+               }
+               GNUNET_NETWORK_fdset_destroy (plugin->rs_v4);
+               GNUNET_NETWORK_fdset_destroy (plugin->ws_v4);
   }
-  GNUNET_NETWORK_fdset_destroy (plugin->rs_v4);
-  GNUNET_NETWORK_fdset_destroy (plugin->ws_v4);
-
-  if (plugin->sockv6 != NULL)
+  if (GNUNET_YES ==plugin->enable_ipv6)
   {
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6));
-    plugin->sockv6 = NULL;
+               if (plugin->sockv6 != NULL)
+               {
+                       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->sockv6));
+                       plugin->sockv6 = NULL;
 
-    GNUNET_NETWORK_fdset_destroy (plugin->rs_v6);
-    GNUNET_NETWORK_fdset_destroy (plugin->ws_v6);
+                       GNUNET_NETWORK_fdset_destroy (plugin->rs_v6);
+                       GNUNET_NETWORK_fdset_destroy (plugin->ws_v6);
+               }
   }
-
-  GNUNET_NAT_unregister (plugin->nat);
+  if (NULL != plugin->nat)
+       GNUNET_NAT_unregister (plugin->nat);
 
   if (plugin->defrag_ctxs != NULL)
   {
@@ -3136,7 +3223,7 @@ libgnunet_plugin_transport_udp_done (void *cls)
     struct UDP_MessageWrapper *tmp = udpw->next;
     dequeue (plugin, udpw);
     call_continuation(udpw, GNUNET_SYSERR);
-    MEMDEBUG_free (udpw, __LINE__);
+    GNUNET_free (udpw);
 
     udpw = tmp;
   }
@@ -3146,7 +3233,7 @@ libgnunet_plugin_transport_udp_done (void *cls)
     struct UDP_MessageWrapper *tmp = udpw->next;
     dequeue (plugin, udpw);
     call_continuation(udpw, GNUNET_SYSERR);
-    MEMDEBUG_free (udpw, __LINE__);
+    GNUNET_free (udpw);
 
     udpw = tmp;
   }
@@ -3157,9 +3244,20 @@ libgnunet_plugin_transport_udp_done (void *cls)
   GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &disconnect_and_free_it, plugin);
   GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions);
 
+  next = ppc_dll_head;
+  for (cur = next; NULL != cur; cur = next)
+  {
+       next = cur->next;
+       GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, cur);
+       GNUNET_RESOLVER_request_cancel (cur->resolver_handle);
+       GNUNET_SCHEDULER_cancel (cur->timeout_task);
+       GNUNET_free (cur);
+       GNUNET_break (0);
+  }
+
   plugin->nat = NULL;
-  MEMDEBUG_free (plugin, __LINE__);
-  MEMDEBUG_free (api, __LINE__);
+  GNUNET_free (plugin);
+  GNUNET_free (api);
 #if DEBUG_MALLOC
   struct Allocation *allocation;
   while (NULL != ahead)