remove output
[oweals/gnunet.git] / src / transport / plugin_transport_udp.c
index 421da9812ca266ec27c56635503bc0333766deb0..be19c5de3005ae5c1259859153051267d4149b62 100644 (file)
  */
 #define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128
 
+/**
+ * Running pretty printers: head
+ */
+static struct PrettyPrinterContext *ppc_dll_head;
+
+/**
+ * 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.
    */
@@ -554,7 +584,6 @@ udp_address_to_string (void *cls, const void *addr, size_t addrlen)
        }
   else
   {
-    GNUNET_break_op (0);
     return NULL;
   }
   inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
@@ -672,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.
  *
@@ -682,14 +728,31 @@ 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);
+    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;
   }
+  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
@@ -698,7 +761,6 @@ append_port (void *cls, const char *hostname)
   GNUNET_free (ret);
 }
 
-
 /**
  * Convert the transports address to a nice, human-readable
  * format.
@@ -784,7 +846,12 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
     ppc->ipv6 = GNUNET_YES;
   else
     ppc->ipv6 = GNUNET_NO;
-  GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
+  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);
+
 }
 
 
@@ -1001,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))
@@ -1383,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;
@@ -1443,6 +1512,7 @@ session_cmp_it (void *cls,
   return GNUNET_YES;
 }
 
+
 /**
  * Function obtain the network type for a session
  *
@@ -1451,13 +1521,13 @@ session_cmp_it (void *cls,
  * @return the network type in HBO or GNUNET_SYSERR
  */
 static enum GNUNET_ATS_Network_Type
-udp_get_network (void *cls, void *session)
+udp_get_network (void *cls, 
+                struct Session *session)
 {
-       struct Session *s = (struct Session *) session;
-
-       return ntohl(s->ats.value);
+  return ntohl (session->ats.value);
 }
 
+
 /**
  * Creates a new outbound session the transport service will use to send data to the
  * peer
@@ -1838,6 +1908,8 @@ udp_nat_port_map_callback (void *cls, int add_remove,
     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 (struct IPv4UdpAddress);
     break;
@@ -1845,6 +1917,8 @@ udp_nat_port_map_callback (void *cls, int add_remove,
     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;
@@ -3082,6 +3156,8 @@ 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)
   {
@@ -3168,6 +3244,17 @@ 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;
   GNUNET_free (plugin);
   GNUNET_free (api);