gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r19983 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r19983 - gnunet/src/transport
Date: Thu, 23 Feb 2012 18:35:38 +0100

Author: wachs
Date: 2012-02-23 18:35:38 +0100 (Thu, 23 Feb 2012)
New Revision: 19983

Modified:
   gnunet/src/transport/plugin_transport_udp.c
   gnunet/src/transport/plugin_transport_udp.h
Log:
splitted ipv4 and ipv6 socket select scheduling
removed looping for write select
improved ipv4/v6 en/disabling
session management


Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2012-02-23 17:31:14 UTC (rev 
19982)
+++ gnunet/src/transport/plugin_transport_udp.c 2012-02-23 17:35:38 UTC (rev 
19983)
@@ -289,7 +289,27 @@
 
 };
 
+/**
+ * We have been notified that our readset has something to read.  We don't
+ * know which socket needs to be read, so we have to check each one
+ * Then reschedule this function to be called again once more is available.
+ *
+ * @param cls the plugin handle
+ * @param tc the scheduling context (for rescheduling this function again)
+ */
+static void
+udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
 
+/**
+ * We have been notified that our readset has something to read.  We don't
+ * know which socket needs to be read, so we have to check each one
+ * Then reschedule this function to be called again once more is available.
+ *
+ * @param cls the plugin handle
+ * @param tc the scheduling context (for rescheduling this function again)
+ */
+static void
+udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext 
*tc);
 
 /**
  * Function called for a quick conversion of the binary address to
@@ -746,6 +766,7 @@
   GNUNET_assert (plugin != NULL);
   GNUNET_assert (address != NULL);
 
+
   if ((address->address == NULL) ||
       ((address->address_length != sizeof (struct IPv4UdpAddress)) &&
       (address->address_length != sizeof (struct IPv6UdpAddress))))
@@ -754,6 +775,15 @@
     return NULL;
   }
 
+  if ((address->address_length == sizeof (struct IPv4UdpAddress)) &&
+      (plugin->sockv4 == NULL))
+    return NULL;
+
+  if ((address->address_length == sizeof (struct IPv6UdpAddress)) &&
+      (plugin->sockv6 == NULL))
+    return NULL;
+
+
   /* check if session already exists */
   struct SessionCompareContext cctx;
   cctx.addr = address;
@@ -816,6 +846,7 @@
   struct FragmentationContext *frag_ctx = cls;
   struct Plugin *plugin = frag_ctx->plugin;
   struct UDPMessageWrapper * udpw;
+  struct Session *s;
 
   size_t msg_len = ntohs (msg->size);
 
@@ -825,6 +856,7 @@
 
   udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + msg_len);
   udpw->session = frag_ctx->session;
+  s = udpw->session;
   udpw->udp = (char *) &udpw[1];
 
   udpw->msg_size = msg_len;
@@ -836,9 +868,48 @@
 
   enqueue (plugin, udpw);
 
+
+  if (s->addrlen == sizeof (struct sockaddr_in))
+  {
+    if (plugin->with_v4_ws == GNUNET_NO)
+    {
+      if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
+        GNUNET_SCHEDULER_cancel(plugin->select_task);
+
+      plugin->select_task =
+          GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                       GNUNET_SCHEDULER_NO_TASK,
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       plugin->rs_v4,
+                                       plugin->ws_v4,
+                                       &udp_plugin_select, plugin);
+      plugin->with_v4_ws = GNUNET_YES;
+    }
+  }
+
+  else if (s->addrlen == sizeof (struct sockaddr_in6))
+  {
+    if (plugin->with_v6_ws == GNUNET_NO)
+    {
+      if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
+        GNUNET_SCHEDULER_cancel(plugin->select_task_v6);
+
+      plugin->select_task_v6 =
+          GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                       GNUNET_SCHEDULER_NO_TASK,
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       plugin->rs_v6,
+                                       plugin->ws_v6,
+                                       &udp_plugin_select_v6, plugin);
+      plugin->with_v6_ws = GNUNET_YES;
+    }
+  }
+
 }
 
 
+
+
 /**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.   Note that in the case of a
@@ -883,6 +954,13 @@
   GNUNET_assert (plugin != NULL);
   GNUNET_assert (s != NULL);
 
+  if ((s->addrlen == sizeof (struct sockaddr_in6)) && (plugin->sockv6 == NULL))
+    return GNUNET_SYSERR;
+
+   if ((s->addrlen == sizeof (struct sockaddr_in)) && (plugin->sockv4 == NULL))
+     return GNUNET_SYSERR;
+
+
   if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
   {
     GNUNET_break (0);
@@ -950,6 +1028,43 @@
     s->frag_ctx = frag_ctx;
 
   }
+
+  if (s->addrlen == sizeof (struct sockaddr_in))
+  {
+    if (plugin->with_v4_ws == GNUNET_NO)
+    {
+      if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
+        GNUNET_SCHEDULER_cancel(plugin->select_task);
+
+      plugin->select_task =
+          GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                       GNUNET_SCHEDULER_NO_TASK,
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       plugin->rs_v4,
+                                       plugin->ws_v4,
+                                       &udp_plugin_select, plugin);
+      plugin->with_v4_ws = GNUNET_YES;
+    }
+  }
+
+  else if (s->addrlen == sizeof (struct sockaddr_in6))
+  {
+    if (plugin->with_v6_ws == GNUNET_NO)
+    {
+      if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
+        GNUNET_SCHEDULER_cancel(plugin->select_task_v6);
+
+      plugin->select_task_v6 =
+        GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                     GNUNET_SCHEDULER_NO_TASK,
+                                     GNUNET_TIME_UNIT_FOREVER_REL,
+                                     plugin->rs_v6,
+                                     plugin->ws_v6,
+                                     &udp_plugin_select_v6, plugin);
+      plugin->with_v6_ws = GNUNET_YES;
+    }
+  }
+
   return mlen;
 }
 
@@ -1648,15 +1763,14 @@
   plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
     return;
+  plugin->with_v4_ws = GNUNET_NO;
 
   if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0)
   {
     if ((NULL != plugin->sockv4) &&
       (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4)))
         udp_select_read (plugin, plugin->sockv4);
-    if ((NULL != plugin->sockv6) &&
-      (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
-        udp_select_read (plugin, plugin->sockv6);
+
   }
 
   if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0)
@@ -1666,18 +1780,68 @@
       {
         udp_select_send (plugin, plugin->sockv4);
       }
+  }
+
+  if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (plugin->select_task);
+  plugin->select_task = GNUNET_SCHEDULER_add_select 
(GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                   GNUNET_SCHEDULER_NO_TASK,
+                                   GNUNET_TIME_UNIT_FOREVER_REL,
+                                   plugin->rs_v4,
+                                   (plugin->ipv4_queue_head != NULL) ? 
plugin->ws_v4 : NULL,
+                                   &udp_plugin_select, plugin);
+  if (plugin->ipv4_queue_head != NULL)
+    plugin->with_v4_ws = GNUNET_YES;
+  else
+    plugin->with_v4_ws = GNUNET_NO;
+}
+
+
+/**
+ * We have been notified that our readset has something to read.  We don't
+ * know which socket needs to be read, so we have to check each one
+ * Then reschedule this function to be called again once more is available.
+ *
+ * @param cls the plugin handle
+ * @param tc the scheduling context (for rescheduling this function again)
+ */
+static void
+udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Plugin *plugin = cls;
+
+  plugin->select_task_v6 = GNUNET_SCHEDULER_NO_TASK;
+  if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
+    return;
+
+  plugin->with_v6_ws = GNUNET_NO;
+  if ((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0)
+  {
+    if ((NULL != plugin->sockv6) &&
+      (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
+        udp_select_read (plugin, plugin->sockv6);
+  }
+
+  if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0)
+  {
     if ((NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL) &&
       (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6)))
       {
         udp_select_send (plugin, plugin->sockv6);
       }
   }
-
-  plugin->select_task = GNUNET_SCHEDULER_add_select 
(GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+  if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (plugin->select_task_v6);
+  plugin->select_task_v6 = GNUNET_SCHEDULER_add_select 
(GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                                    GNUNET_SCHEDULER_NO_TASK,
-                                   GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
-                                   plugin->ws, &udp_plugin_select, plugin);
-
+                                   GNUNET_TIME_UNIT_FOREVER_REL,
+                                   plugin->rs_v6,
+                                   (plugin->ipv6_queue_head != NULL) ? 
plugin->ws_v6 : NULL,
+                                   &udp_plugin_select_v6, plugin);
+  if (plugin->ipv6_queue_head != NULL)
+    plugin->with_v6_ws = GNUNET_YES;
+  else
+    plugin->with_v6_ws = GNUNET_NO;
 }
 
 
@@ -1793,20 +1957,15 @@
   }
 
   /* Create file descriptors */
-  plugin->rs = GNUNET_NETWORK_fdset_create ();
-  plugin->ws = GNUNET_NETWORK_fdset_create ();
-  GNUNET_NETWORK_fdset_zero (plugin->rs);
-  GNUNET_NETWORK_fdset_zero (plugin->ws);
+  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, plugin->sockv4);
-    GNUNET_NETWORK_fdset_set (plugin->ws, plugin->sockv4);
+    GNUNET_NETWORK_fdset_set (plugin->rs_v4, plugin->sockv4);
+    GNUNET_NETWORK_fdset_set (plugin->ws_v4, plugin->sockv4);
   }
-  if (NULL != plugin->sockv6)
-  {
-    GNUNET_NETWORK_fdset_set (plugin->rs, plugin->sockv6);
-    GNUNET_NETWORK_fdset_set (plugin->ws, plugin->sockv6);
-  }
 
   if (sockets_created == 0)
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n"));
@@ -1814,9 +1973,34 @@
   plugin->select_task =
       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                                    GNUNET_SCHEDULER_NO_TASK,
-                                   GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
-                                   plugin->ws, &udp_plugin_select, plugin);
+                                   GNUNET_TIME_UNIT_FOREVER_REL,
+                                   plugin->rs_v4,
+                                   NULL,
+                                   &udp_plugin_select, plugin);
+  plugin->with_v4_ws = GNUNET_NO;
 
+  if (plugin->enable_ipv6 == GNUNET_YES)
+  {
+    plugin->rs_v6 = GNUNET_NETWORK_fdset_create ();
+    plugin->ws_v6 = GNUNET_NETWORK_fdset_create ();
+    GNUNET_NETWORK_fdset_zero (plugin->rs_v6);
+    GNUNET_NETWORK_fdset_zero (plugin->ws_v6);
+    if (NULL != plugin->sockv6)
+    {
+      GNUNET_NETWORK_fdset_set (plugin->rs_v6, plugin->sockv6);
+      GNUNET_NETWORK_fdset_set (plugin->ws_v6, plugin->sockv6);
+    }
+
+    plugin->select_task_v6 =
+        GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                     GNUNET_SCHEDULER_NO_TASK,
+                                     GNUNET_TIME_UNIT_FOREVER_REL,
+                                     plugin->rs_v6,
+                                     NULL,
+                                     &udp_plugin_select_v6, plugin);
+    plugin->with_v6_ws = GNUNET_NO;
+  }
+
   plugin->nat = GNUNET_NAT_register (plugin->env->cfg,
                            GNUNET_NO, plugin->port,
                            sockets_created,
@@ -2019,6 +2203,11 @@
     GNUNET_SCHEDULER_cancel (plugin->select_task);
     plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
   }
+  if (plugin->select_task_v6 != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel (plugin->select_task_v6);
+    plugin->select_task_v6 = GNUNET_SCHEDULER_NO_TASK;
+  }
 
   /* Closing sockets */
   if (plugin->sockv4 != NULL)
@@ -2026,13 +2215,18 @@
     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);
+
   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);
-  GNUNET_NETWORK_fdset_destroy (plugin->ws);
+
   GNUNET_NAT_unregister (plugin->nat);
 
   if (plugin->defrag_ctxs != NULL)

Modified: gnunet/src/transport/plugin_transport_udp.h
===================================================================
--- gnunet/src/transport/plugin_transport_udp.h 2012-02-23 17:31:14 UTC (rev 
19982)
+++ gnunet/src/transport/plugin_transport_udp.h 2012-02-23 17:35:38 UTC (rev 
19983)
@@ -137,6 +137,7 @@
    * ID of select task
    */
   GNUNET_SCHEDULER_TaskIdentifier select_task;
+  GNUNET_SCHEDULER_TaskIdentifier select_task_v6;
 
   /**
    * Tokenizer for inbound messages.
@@ -166,19 +167,35 @@
   /**
    * FD Read set
    */
-  struct GNUNET_NETWORK_FDSet *rs;
+  struct GNUNET_NETWORK_FDSet *rs_v4;
 
   /**
    * FD Write set
    */
-  struct GNUNET_NETWORK_FDSet *ws;
+  struct GNUNET_NETWORK_FDSet *ws_v4;
 
+
+  int with_v4_ws;
+
   /**
    * The read socket for IPv4
    */
   struct GNUNET_NETWORK_Handle *sockv4;
 
+
   /**
+   * FD Read set
+   */
+  struct GNUNET_NETWORK_FDSet *rs_v6;
+
+  /**
+   * FD Write set
+   */
+  struct GNUNET_NETWORK_FDSet *ws_v6;
+
+  int with_v6_ws;
+
+  /**
    * The read socket for IPv6
    */
   struct GNUNET_NETWORK_Handle *sockv6;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]