gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28399 - gnunet/src/mesh


From: gnunet
Subject: [GNUnet-SVN] r28399 - gnunet/src/mesh
Date: Mon, 5 Aug 2013 15:39:34 +0200

Author: bartpolot
Date: 2013-08-05 15:39:34 +0200 (Mon, 05 Aug 2013)
New Revision: 28399

Modified:
   gnunet/src/mesh/gnunet-service-mesh-enc.c
   gnunet/src/mesh/mesh_protocol_enc.h
Log:
- change hop-by-hop ACK to be per-connection not per-peer


Modified: gnunet/src/mesh/gnunet-service-mesh-enc.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh-enc.c   2013-08-05 13:32:17 UTC (rev 
28398)
+++ gnunet/src/mesh/gnunet-service-mesh-enc.c   2013-08-05 13:39:34 UTC (rev 
28399)
@@ -220,9 +220,9 @@
 struct MeshFlowControl
 {
   /**
-   * Peer
+   * Connection this controls.
    */
-  struct MeshPeer *peer;
+  struct MeshConnection *c;
 
   /**
    * Transmission queue to core DLL head
@@ -297,11 +297,6 @@
   struct GNUNET_TIME_Absolute last_contact;
 
     /**
-     * Number of attempts to reconnect so far
-     */
-  int n_reconnect_attempts;
-
-    /**
      * Paths to reach the peer, ordered by ascending hop count
      */
   struct MeshPeerPath *path_head;
@@ -321,11 +316,6 @@
      */
   struct MeshTunnel2 *tunnel;
 
-    /**
-     * Flow control information for direct traffic.
-     */
-  struct MeshFlowControl *fc;
-
 };
 
 
@@ -508,6 +498,16 @@
   struct MeshTunnel2 *t;
 
   /**
+   * Flow control information for traffic fwd.
+   */
+  struct MeshFlowControl *fwd_fc;
+
+  /**
+   * Flow control information for traffic bck.
+   */
+  struct MeshFlowControl *bck_fc;
+
+  /**
    * Connection number.
    */
   uint32_t id;
@@ -1060,21 +1060,6 @@
 
 
 /**
- * @brief Get the next transmittable message from the queue.
- *
- * This will be the head, except in the case of being a data packet
- * not allowed by the destination peer.
- *
- * @param peer Destination peer.
- *
- * @return The next viable MeshPeerQueue element to send to that peer.
- *         NULL when there are no transmittable messages.
- */
-struct MeshPeerQueue *
-queue_get_next (const struct MeshPeer *peer);
-
-
-/**
  * Core callback to write a queued packet to core buffer
  *
  * @param cls Closure (peer info).
@@ -1396,27 +1381,25 @@
 {
   struct MeshConnection *c;
   struct MeshConnection *best;
-  struct MeshPeer *peer;
+  struct MeshFlowControl *fc;
   unsigned int lowest_q;
 
-
-  peer = NULL;
   best = NULL;
   lowest_q = UINT_MAX;
   for (c = t->connection_head; NULL != c; c = c->next)
   {
     if (MESH_CONNECTION_READY == c->state)
     {
-      peer = fwd ? connection_get_next_hop (c) : connection_get_prev_hop (c);
-      if (NULL == peer->fc)
+      fc = fwd ? c->fwd_fc : c->bck_fc;
+      if (NULL == fc)
       {
         GNUNET_break (0);
         continue;
       }
-      if (peer->fc->queue_n < lowest_q)
+      if (fc->queue_n < lowest_q)
       {
         best = c;
-        lowest_q = peer->fc->queue_n;
+        lowest_q = fc->queue_n;
       }
     }
   }
@@ -1595,41 +1578,6 @@
 
 
 /**
- * Sends an already built message directly to a peer.
- * Message does must not belong to a connection or channel.
- *
- * @param message Message to send. Function makes a copy of it.
- * @param peer Tunnel on which this message is transmitted.
- */
-static void
-send_prebuilt_message_peer (const struct GNUNET_MessageHeader *message,
-                            struct MeshPeer *peer)
-{
-  void *data;
-  size_t size;
-  uint16_t type;
-
-  if (NULL == peer)
-  {
-    GNUNET_break (0);
-    return;
-  }
-
-  size = ntohs (message->size);
-  data = GNUNET_malloc (size);
-  memcpy (data, message, size);
-  type = ntohs(message->type);
-
-  queue_add (data,
-             type,
-             size,
-             peer,
-             NULL,
-             NULL);
-}
-
-
-/**
  * Sends a CREATE CONNECTION message for a path to a peer.
  * Changes the connection and tunnel states if necessary.
  *
@@ -1686,21 +1634,24 @@
 
 
 /**
- * Build an ACK message and queue it to send to the given peer.
+ * Build a hop-by-hop ACK message and queue it to send for the given 
connection.
  * 
- * @param peer Peer to whom send the ACK.
+ * @param c Which connection to send the hop-by-hop ACK.
  * @param ack Value of the ACK.
+ * @param fwd Is this fwd?
  */
 static void
-send_ack (struct MeshPeer *peer, uint32_t ack)
+send_ack (struct MeshConnection *c, uint32_t ack, int fwd)
 {
   struct GNUNET_MESH_ACK msg;
 
   msg.header.size = htons (sizeof (msg));
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
   msg.ack = htonl (ack);
+  msg.tid = c->t->id;
+  msg.cid = htonl (c->id);
 
-  send_prebuilt_message_peer (&msg.header, peer);
+  send_prebuilt_message_connection (&msg.header, c, NULL, fwd);
 }
 
 
@@ -2009,31 +1960,35 @@
 
 
 /**
- * @brief Re-initiate traffic to this peer if necessary.
+ * @brief Re-initiate traffic on this connection if necessary.
  *
  * Check if there is traffic queued towards this peer
  * and the core transmit handle is NULL (traffic was stalled).
  * If so, call core tmt rdy.
  *
- * @param peer_id Short ID of peer to which initiate traffic.
+ * @param c Connection on which initiate traffic.
+ * @param fwd Is this about fwd traffic?
  */
 static void
-peer_unlock_queue (GNUNET_PEER_Id peer_id)
+connection_unlock_queue (struct MeshConnection *c, int fwd)
 {
+  struct MeshFlowControl *fc;
   struct MeshPeer *peer;
   struct MeshPeerQueue *q;
   size_t size;
 
-  peer = peer_get_short (peer_id);
-  if (NULL != peer->fc->core_transmit)
+  peer = fwd ? connection_get_next_hop(c) : connection_get_prev_hop(c);
+  fc   = fwd ? c->fwd_fc                  : c->bck_fc;
+
+  if (NULL != fc->core_transmit)
     return; /* Already unlocked */
 
-  q = queue_get_next (peer);
+  q = fc->queue_head;
   if (NULL == q)
     return; /* Nothing to transmit */
 
   size = q->size;
-  peer->fc->core_transmit =
+  fc->core_transmit =
       GNUNET_CORE_notify_transmit_ready (core_handle,
                                          GNUNET_NO,
                                          0,
@@ -2046,32 +2001,31 @@
 
 
 /**
- * Cancel all transmissions towards a neighbor that belong to
- * a certain connection.
+ * Cancel all transmissions that belong to a certain connection.
  *
- * @param peer Neighbor to whom cancel the transmissions.
  * @param c Connection which to cancel.
+ * @param fwd Cancel fwd traffic?
  */
 static void
-peer_cancel_queues (struct MeshPeer *peer, struct MeshConnection *c)
+connection_cancel_queues (struct MeshConnection *c, int fwd)
 {
   struct MeshPeerQueue *q;
   struct MeshPeerQueue *next;
   struct MeshFlowControl *fc;
 
-  if (NULL == peer || NULL == peer->fc)
+  if (NULL == c)
   {
     GNUNET_break (0);
     return;
   }
-  fc = peer->fc;
+  fc = fwd ? c->fwd_fc : c->bck_fc;
   for (q = fc->queue_head; NULL != q; q = next)
   {
     next = q->next;
     if (q->c == c)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "peer_cancel_queue %s\n",
+                  "connection_cancel_queue %s\n",
                   GNUNET_MESH_DEBUG_M2S (q->type));
       queue_destroy (q, GNUNET_YES);
     }
@@ -2301,18 +2255,18 @@
 
 
 /**
- * Function called if the connection to the peer has been stalled for a while,
- * possibly due to a missed ACK. Poll the peer about its ACK status.
+ * Function called if a connection has been stalled for a while,
+ * possibly due to a missed ACK. Poll the neighbor about its ACK status.
  *
  * @param cls Closure (poll ctx).
  * @param tc TaskContext.
  */
 static void
-peer_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct MeshFlowControl *fc = cls;
   struct GNUNET_MESH_Poll msg;
-  struct MeshPeer *peer;
+  struct MeshConnection *c;
 
   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
@@ -2320,20 +2274,19 @@
     return;
   }
 
+  c = fc->c;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
-  peer = fc->peer;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** connection %s[%X]\n", 
+              GNUNET_i2s (GNUNET_PEER_resolve2 (c->t->peer->id)), c->id);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** peer: %s!\n", 
-                GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id)));
-
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
   msg.header.size = htons (sizeof (msg));
   msg.pid = htonl (fc->last_pid_sent);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** pid (%u)!\n", fc->last_pid_sent);
-  send_prebuilt_message_peer (&msg.header, peer);
+  send_prebuilt_message_connection (&msg.header, c, NULL, fc == c->fwd_fc);
   fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
-                                                &peer_poll, fc);
+                                                &connection_poll, fc);
 }
 
 
@@ -2689,10 +2642,8 @@
 /**
  * Send an ACK informing the predecessor about the available buffer space.
  *
- * Note that although the name is fwd_ack, the FWD mean forward *traffic*,
- * the ACK itself goes "back" (towards root).
- * 
- * FIXME: use per connection ACKs istead of per-hop.
+ * Note that for fwd ack, the FWD mean forward *traffic* (root->dest),
+ * the ACK itself goes "back" (dest->root).
  *
  * @param c Connection on which to send the ACK.
  * @param fwd Is this FWD ACK? (Going dest->owner)
@@ -2702,15 +2653,11 @@
 {
   struct MeshFlowControl *next_fc;
   struct MeshFlowControl *prev_fc;
-  struct MeshPeer *next;
-  struct MeshPeer *prev;
   uint32_t ack;
   int delta;
 
-  next    = fwd ? connection_get_next_hop (c) : connection_get_prev_hop (c);
-  prev    = fwd ? connection_get_prev_hop (c) : connection_get_next_hop (c);
-  next_fc = next->fc;
-  prev_fc = prev->fc;
+  next_fc = fwd ? c->fwd_fc : c->bck_fc;
+  prev_fc = fwd ? c->bck_fc : c->fwd_fc;
 
   /* Check if we need to transmit the ACK */
   if (prev_fc->last_ack_sent - prev_fc->last_pid_recv > 3)
@@ -2737,7 +2684,7 @@
   }
 
   prev_fc->last_ack_sent = ack;
-  send_ack (prev, ack);
+  send_ack (c, ack, fwd);
 }
 
 
@@ -3145,7 +3092,7 @@
   struct MeshChannelReliability *rel = cls;
   struct MeshReliableMessage *copy;
   struct MeshPeerQueue *q;
-  struct MeshPeer *pi;
+  struct MeshFlowControl *fc;
   struct MeshChannel *ch;
   struct MeshConnection *c;
   struct GNUNET_MESH_Data *payload;
@@ -3175,9 +3122,9 @@
    */
   payload = (struct GNUNET_MESH_Data *) &copy[1];
   fwd = (rel == ch->fwd_rel);
-  c = tunnel_get_connection(ch->t, fwd);
-  pi = connection_get_next_hop (c);
-  for (q = pi->fc->queue_head; NULL != q; q = q->next)
+  c = tunnel_get_connection (ch->t, fwd);
+  fc = fwd ? c->fwd_fc : c->bck_fc;
+  for (q = fc->queue_head; NULL != q; q = q->next)
   {
     if (ntohs (payload->header.type) == q->type && ch == q->ch)
     {
@@ -3347,6 +3294,7 @@
 
   send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_YES);
   send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_NO);
+  c->destroy = GNUNET_YES;
 }
 
 
@@ -3496,8 +3444,6 @@
 static void
 connection_destroy (struct MeshConnection *c)
 {
-  struct MeshPeer *peer;
-
   if (NULL == c)
     return;
 
@@ -3505,12 +3451,8 @@
               GNUNET_i2s (GNUNET_PEER_resolve2 (c->t->peer->id)),
               c->id);
 
-  peer = connection_get_next_hop (c);
-  if (NULL != peer)
-    peer_cancel_queues (peer, c);
-  peer = connection_get_prev_hop (c);
-  if (NULL != peer)
-    peer_cancel_queues (peer, c);
+  connection_cancel_queues (c, GNUNET_YES);
+  connection_cancel_queues (c, GNUNET_NO);
 
   if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task)
     GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
@@ -3891,8 +3833,11 @@
 queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
 {
   struct MeshFlowControl *fc;
+  int fwd;
 
-  fc = queue->peer->fc;
+  fwd = (queue->peer == connection_get_next_hop (queue->c));
+  fc = fwd ? queue->c->fwd_fc : queue->c->bck_fc;
+
   if (GNUNET_YES == clear_cls)
   {
     switch (queue->type)
@@ -3929,6 +3874,7 @@
   GNUNET_free (queue);
 }
 
+
 static size_t
 queue_send (void *cls, size_t size, void *buf)
 {
@@ -3944,7 +3890,10 @@
   uint16_t type;
   int fwd;
 
-  fc = peer->fc;
+  c = queue->c;
+  fwd = (queue->peer == connection_get_next_hop (c));
+  fc = fwd ? c->fwd_fc : c->bck_fc;
+
   if (NULL == fc)
   {
     GNUNET_break (0);
@@ -3987,7 +3936,6 @@
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   size ok\n");
 
-  c = queue->c;
   t = (NULL != c) ? c->t : NULL;
   type = 0;
 
@@ -4045,12 +3993,9 @@
   queue_destroy (queue, GNUNET_NO);
 
   /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
-  fwd = GNUNET_NO;
   switch (type)
   {
     case GNUNET_MESSAGE_TYPE_MESH_FWD:
-      fwd = GNUNET_YES;
-      /* fall through */
     case GNUNET_MESSAGE_TYPE_MESH_BCK:
       pid = ntohl ( ((struct GNUNET_MESH_Encrypted *) buf)->pid );
       fc->last_pid_sent = pid;
@@ -4066,7 +4011,7 @@
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   more data!\n");
     if (NULL == fc->core_transmit) {
-      peer->fc->core_transmit =
+      fc->core_transmit =
           GNUNET_CORE_notify_transmit_ready(core_handle,
                                             0,
                                             0,
@@ -4085,7 +4030,7 @@
     {
       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "*   %s starting poll timeout\n");
       fc->poll_task =
-          GNUNET_SCHEDULER_add_delayed (fc->poll_time, &peer_poll, fc);
+          GNUNET_SCHEDULER_add_delayed (fc->poll_time, &connection_poll, fc);
     }
   }
   else
@@ -4129,8 +4074,11 @@
   struct MeshPeerQueue *queue;
   struct MeshFlowControl *fc;
   int priority;
+  int fwd;
 
-  fc = dst->fc;
+  fwd = (dst == connection_get_next_hop (c));
+  fc = fwd ? c->fwd_fc : c->bck_fc;
+
   if (NULL == fc)
   {
     GNUNET_break (0);
@@ -4163,7 +4111,7 @@
   if (GMC_is_pid_bigger(fc->last_pid_sent + 1, fc->last_ack_recv) &&
       GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
     fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
-                                                  &peer_poll,
+                                                  &connection_poll,
                                                   dst);
   queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
   queue->cls = cls;
@@ -4675,8 +4623,8 @@
 {
   struct GNUNET_MESH_ConnectionDestroy *msg;
   struct MeshConnection *c;
-  struct MeshTunnel2 *t;
-  struct MeshPeer *neighbor;
+  GNUNET_PEER_Id id;
+  int fwd;
 
   msg = (struct GNUNET_MESH_ConnectionDestroy *) message;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4696,20 +4644,18 @@
                               1, GNUNET_NO);
     return GNUNET_OK;
   }
-  neighbor = peer_get (peer);
-  if (neighbor == connection_get_prev_hop (c))
-    neighbor = connection_get_next_hop (c);
-  else if (neighbor == connection_get_next_hop (c))
-    neighbor = connection_get_prev_hop (c);
+  id = GNUNET_PEER_search (peer);
+  if (id == connection_get_prev_hop (c)->id)
+    fwd = GNUNET_YES;
+  else if (id == connection_get_next_hop (c)->id)
+    fwd = GNUNET_NO;
   else
   {
     GNUNET_break_op (0);
     return GNUNET_OK;
   }
-  send_prebuilt_message_peer (message, neighbor);
-  t = c->t;
-  connection_destroy (c);
-  tunnel_destroy_if_empty (t);
+  send_prebuilt_message_connection (message, c, NULL, fwd);
+  c->destroy = GNUNET_YES;
 
   return GNUNET_OK;
 }
@@ -4734,6 +4680,7 @@
   struct MeshTunnel2 *t;
   struct MeshPeer *neighbor;
   struct MeshFlowControl *fc;
+  GNUNET_PEER_Id id;
   uint32_t pid;
   uint32_t ttl;
   uint16_t type;
@@ -4761,13 +4708,13 @@
     return GNUNET_OK;
   }
   t = c->t;
+  fc = fwd ? c->fwd_fc : c->bck_fc;
 
-  /* Check neighbor status */
-  neighbor = peer_get (peer);
-  fc = neighbor->fc;
-  if (NULL == fc)
+  /* Check if origin is as expected */
+  neighbor = fwd ? connection_get_prev_hop (c) : connection_get_next_hop (c);
+  if (peer_get (peer)->id != neighbor->id)
   {
-    GNUNET_break (0);
+    GNUNET_break_op (0);
     return GNUNET_OK;
   }
 
@@ -5841,12 +5788,6 @@
   path->peers[0] = myid;
   GNUNET_PEER_change_rc (myid, 1);
   peer_add_path (peer_info, path, GNUNET_YES);
-  if (NULL == peer_info->fc)
-  {
-    peer_info->fc = GNUNET_new (struct MeshFlowControl);
-    fc_init (peer_info->fc);
-    peer_info->fc->peer = peer_info;
-  }
   return;
 }
 

Modified: gnunet/src/mesh/mesh_protocol_enc.h
===================================================================
--- gnunet/src/mesh/mesh_protocol_enc.h 2013-08-05 13:32:17 UTC (rev 28398)
+++ gnunet/src/mesh/mesh_protocol_enc.h 2013-08-05 13:39:34 UTC (rev 28399)
@@ -242,6 +242,16 @@
      * Maximum packet ID authorized.
      */
   uint32_t ack GNUNET_PACKED;
+
+    /**
+     * ID of the tunnel
+     */
+  struct GNUNET_HashCode tid;
+
+    /**
+     * ID of the connection
+     */
+  uint32_t cid GNUNET_PACKED;
 };
 
 
@@ -259,6 +269,16 @@
    * Last packet sent.
    */
   uint32_t pid GNUNET_PACKED;
+
+    /**
+     * ID of the tunnel
+     */
+  struct GNUNET_HashCode tid;
+
+    /**
+     * ID of the connection
+     */
+  uint32_t cid GNUNET_PACKED;
 };
 
 




reply via email to

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