gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r15414 - gnunet/src/transport
Date: Sat, 4 Jun 2011 15:00:16 +0200

Author: grothoff
Date: 2011-06-04 15:00:16 +0200 (Sat, 04 Jun 2011)
New Revision: 15414

Modified:
   gnunet/src/transport/transport_api_new.c
Log:
fixes

Modified: gnunet/src/transport/transport_api_new.c
===================================================================
--- gnunet/src/transport/transport_api_new.c    2011-06-03 22:26:48 UTC (rev 
15413)
+++ gnunet/src/transport/transport_api_new.c    2011-06-04 13:00:16 UTC (rev 
15414)
@@ -24,8 +24,6 @@
  * @author Christian Grothoff
  *
  * TODO:
- * - support 'try connect' in transport service
- * - add timeout (see FIXME)
  * - adjust testcases to use new 'try connect' style (should be easy, breaks 
API compatibility!)
  * - adjust core service to use new 'try connect' style (should be MUCH nicer 
there as well!)
  * - test test test
@@ -69,7 +67,7 @@
   /**
    * Neighbour for this handle, NULL for control messages.
    */
-  struct NeighbourList *neighbour;
+  struct Neighbour *neighbour;
 
   /**
    * Function to call when notify_size bytes are available
@@ -88,6 +86,12 @@
   struct GNUNET_TIME_Absolute timeout;
 
   /**
+   * Task to trigger request timeout if the request is stalled due to 
+   * congestion.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+  /**
    * How many bytes is our notify callback waiting for?
    */
   size_t notify_size;
@@ -399,7 +403,7 @@
   const struct SendOkMessage *okm;
   struct HelloWaitList *hwl;
   struct HelloWaitList *next_hwl;
-  struct NeighbourList *n;
+  struct Neighbour *n;
   struct GNUNET_PeerIdentity me;
   uint16_t size;
   uint32_t ats_count;
@@ -525,6 +529,9 @@
       if ( (n->th != NULL) &&
           (n->hn == NULL) )
        {
+         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->th->timeout_task);
+         GNUNET_SCHEDULER_cancel (n->th->timeout_task);
+         n->th->timeout_task = GNUNET_SCHEDULER_NO_TASK;
          /* we've been waiting for this (congestion, not quota, 
             caused delayed transmission) */
          n->hn = GNUNET_CONTAINER_heap_insert (h->ready_heap,
@@ -581,6 +588,29 @@
 
 
 /**
+ * A transmission request could not be satisfied because of
+ * network congestion.  Notify the initiator and clean up.
+ *
+ * @param cls the 'struct GNUNET_TRANSPORT_TransmitHandle'
+ * @param tc scheduler context
+ */
+static void
+timeout_request_due_to_congestion (void *cls,
+                                  const struct GNUNET_SCHEDULER_TaskContext 
*tc)
+{
+  struct GNUNET_TRANSPORT_TransmitHandle *th = cls;
+  struct Neighbour *n = th->neighbour;
+
+  n->th->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  GNUNET_assert (th == n->th);
+  GNUNET_assert (NULL == n->hn);
+  n->th = NULL;
+  th->notify (th->notify_cls, 0, NULL);
+  GNUNET_free (th);
+}
+
+
+/**
  * Transmit message(s) to service.
  *
  * @param cls handle to transport
@@ -592,11 +622,13 @@
 transport_notify_ready (void *cls, size_t size, void *buf)
 {
   struct GNUNET_TRANSPORT_Handle *h = cls;
-  size_t ssize;
   struct GNUNET_TRANSPORT_TransmitHandle *th;
   struct Neighbour *n;
   char *cbuf;
+  struct OutboundMessage obm;
   size_t ret;
+  size_t nret;
+  size_t mret;
 
   GNUNET_assert (NULL != h->client);
   h->cth = NULL;
@@ -637,8 +669,10 @@
          /* peer not ready, wait for notification! */
          GNUNET_CONTAINER_heap_remove_node (n->hn);
          n->hn = NULL;
-         /* FIXME: hitting transport-level congestion, add
-            a timeout task for 'th' in this case! */
+         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == n->th->timeout_task);
+         n->th->timeout_task = GNUNET_SCHEDULER_add_delayed 
(GNUNET_TIME_absolute_get_remaining (n->th->timeout),
+                                                             
&timeout_request_due_to_congestion,
+                                                             n->th);
          continue;
        }
       th = n->th;
@@ -848,7 +882,6 @@
           const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_TRANSPORT_Handle *h = cls;
-  struct ControlMessage *pos;
 
   h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
   if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
@@ -882,33 +915,35 @@
 static void
 disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h)
 {
+  struct GNUNET_TRANSPORT_TransmitHandle *th;
+
   GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
   /* Forget about all neighbours that we used to be connected to */
   GNUNET_CONTAINER_multihashmap_iterate(h->neighbours, 
                                        &neighbour_delete, 
                                        NULL);
-  if (NULL != handle->cth)
+  if (NULL != h->cth)
     {
-      GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
-      handle->cth = NULL;
+      GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
+      h->cth = NULL;
     }
-  if (NULL != handle->client)
+  if (NULL != h->client)
     {
-      GNUNET_CLIENT_disconnect (handle->client, GNUNET_YES);
-      handle->client = NULL;
+      GNUNET_CLIENT_disconnect (h->client, GNUNET_YES);
+      h->client = NULL;
     }
   if (h->quota_task != GNUNET_SCHEDULER_NO_TASK)
     {
       GNUNET_SCHEDULER_cancel (h->quota_task);
       h->quota_task = GNUNET_SCHEDULER_NO_TASK;
     }
-  while ( (NULL != (th = handle->control_head)))
+  while ( (NULL != (th = h->control_head)))
     {
-      GNUNET_CONTAINER_DLL_remove (handle->control_head,
-                                   handle->control_tail,
-                                   cm);
-      cm->notify (cm->notify_cls, 0, NULL);
-      GNUNET_free (cm);
+      GNUNET_CONTAINER_DLL_remove (h->control_head,
+                                   h->control_tail,
+                                   th);
+      th->notify (th->notify_cls, 0, NULL);
+      GNUNET_free (th);
     }
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1037,7 +1072,7 @@
 
 
 /**
- * Send TRY_CONNECT message to the service.
+ * Send REQUEST_CONNECT message to the service.
  *
  * @param cls the 'struct GNUNET_PeerIdentity'
  * @param size number of bytes available in buf
@@ -1048,7 +1083,7 @@
 send_try_connect (void *cls, size_t size, void *buf)
 {
   struct GNUNET_PeerIdentity *pid = cls;
-  struct TryConnectMessage msg;
+  struct TransportRequestConnectMessage msg;
 
   if (buf == NULL)
     {
@@ -1058,17 +1093,17 @@
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Transmitting `%s' request with respect to `%4s'.\n",
-              "TRY_CONNECT",
+              "REQUEST_CONNECT",
              GNUNET_i2s (&sqc->target));
 #endif
-  GNUNET_assert (size >= sizeof (struct TryConnectMessage));
-  msg.header.size = htons (sizeof (struct TryConnectMessage));
-  msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT);
+  GNUNET_assert (size >= sizeof (struct TransportRequestConnectMessage));
+  msg.header.size = htons (sizeof (struct TransportRequestConnectMessage));
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT);
   msg.reserved = htonl (0);
   msg.peer = *pid;
   memcpy (buf, &msg, sizeof (msg));
   GNUNET_free (pid);
-  return sizeof (struct TryConnectMessage);
+  return sizeof (struct TransportRequestConnectMessage);
 }
 
 
@@ -1088,7 +1123,7 @@
   pid = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
   *pid = *target;
   schedule_control_transmit (handle,
-                             sizeof (struct TryConnectMessage),
+                             sizeof (struct TransportRequestConnectMessage),
                              &send_try_connect, pid);
 }
 
@@ -1272,7 +1307,7 @@
   ret->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
   ret->neighbours = 
GNUNET_CONTAINER_multihashmap_create(STARTING_NEIGHBOURS_SIZE);
   ret->ready_heap = GNUNET_CONTAINER_heap_create 
(GNUNET_CONTAINER_HEAP_ORDER_MIN);
-  ret->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h);
+  ret->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, ret);
   return ret;
 }
 
@@ -1285,8 +1320,6 @@
 void
 GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle)
 {
-  struct GNUNET_TRANSPORT_TransmitHandle *cm;
-
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
              "Transport disconnect called!\n");
@@ -1370,13 +1403,13 @@
   th->priority = priority;
   n->th = th;
   /* calculate when our transmission should be ready */
-  delay = GNUNET_BANDWIDTH_tracker_get_delay (n->out_tracker, size);
+  delay = GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker, size);
   if (delay.rel_value > timeout.rel_value)
     delay.rel_value = 0; /* notify immediately (with failure) */
-  n->hn = GNUNET_CONTAINER_heap_insert (h->ready_heap,
+  n->hn = GNUNET_CONTAINER_heap_insert (handle->ready_heap,
                                        n, 
                                        delay.rel_value);
-  schedule_transmission (h);
+  schedule_transmission (handle);
   return th;
 }
 
@@ -1401,6 +1434,12 @@
       GNUNET_CONTAINER_heap_remove_node (n->hn);
       n->hn = NULL;
     }
+  else
+    {
+      GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != th->timeout_task);
+      GNUNET_SCHEDULER_cancel (th->timeout_task);
+      th->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+    }
   GNUNET_free (th);                                        
 }
 




reply via email to

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