gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r28050 - gnunet/src/mesh
Date: Mon, 15 Jul 2013 16:09:08 +0200

Author: bartpolot
Date: 2013-07-15 16:09:07 +0200 (Mon, 15 Jul 2013)
New Revision: 28050

Modified:
   gnunet/src/mesh/gnunet-service-mesh.c
Log:
- fix polling in the presence of lost data

Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c       2013-07-15 12:56:16 UTC (rev 
28049)
+++ gnunet/src/mesh/gnunet-service-mesh.c       2013-07-15 14:09:07 UTC (rev 
28050)
@@ -1149,6 +1149,44 @@
 
 
 /**
+ * Select which PID to POLL for, to compensate for lost messages.
+ *
+ * @param pi Peer we want to poll.
+ * @param t Tunnel about which we want to poll.
+ * 
+ * @return PID to use, either last sent or first_in_queue - 1
+ */
+static uint32_t
+peer_get_first_payload_pid (struct MeshPeerInfo *pi, struct MeshTunnel *t)
+{
+  struct MeshPeerQueue *q;
+  uint16_t type;
+
+  type = pi->id == t->next_hop ? GNUNET_MESSAGE_TYPE_MESH_UNICAST :
+                                 GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN;
+
+  for (q = pi->queue_head; NULL != q; q = q->next)
+  {
+    if (q->type == type && q->tunnel == t)
+    {
+      struct GNUNET_MESH_Data *msg = q->cls;
+
+      /* Pretend that the last one sent was the previous to this */
+      return ntohl (msg->pid) - 1;
+    }
+  }
+
+  /* No data in queue, use last sent */
+  {
+    struct MeshFlowControl *fc;
+
+    fc = pi->id == t->next_hop ? &t->next_fc : &t->prev_fc;
+    return fc->last_pid_sent;
+  }
+}
+
+
+/**
  * Choose the best path towards a peer considering the tunnel properties.
  * 
  * @param peer The destination peer.
@@ -1670,10 +1708,6 @@
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
 
-  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
-  msg.header.size = htons (sizeof (msg));
-  msg.tid = htonl (t->id.tid);
-  msg.pid = htonl (fc->last_pid_sent);
   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
 
   if (fc == &t->prev_fc)
@@ -1691,6 +1725,10 @@
     GNUNET_break (0);
     return;
   }
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
+  msg.header.size = htons (sizeof (msg));
+  msg.tid = htonl (t->id.tid);
+  msg.pid = htonl (peer_get_first_payload_pid (peer_get_short (peer), t));
   send_prebuilt_message (&msg.header, peer, t);
   fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
   fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
@@ -2068,7 +2106,6 @@
   struct MeshTunnelReliability *rel;
   struct MeshReliableMessage *copy;
   uint64_t mask;
-  unsigned int i;
   unsigned int delta;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2087,12 +2124,12 @@
   msg.mid = GNUNET_htonll (t->bck_rel->mid_recv - 1);
   msg.futures = 0;
   rel = t->bck_rel;
-  for (i = 0, copy = rel->head_recv;
-       i < 64 && NULL != copy;
-       i++, copy = copy->next)
+  for (copy = rel->head_recv; NULL != copy; copy = copy->next)
   {
     delta = copy->mid - t->bck_rel->mid_recv;
-    mask = 0x1 << delta;
+    if (63 < delta)
+      break;
+    mask = 0x1LL << delta;
     msg.futures |= mask;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 " setting bit for %u (delta %u) (%llX) -> %llX\n",
@@ -2419,8 +2456,37 @@
 
 
 /**
+ * Destroy a reliable message after it has been acknowledged, either by
+ * direct mid ACK or bitfield. Updates the appropriate data structures and
+ * timers and frees all memory.
+ * 
+ * @param copy Message that is no longer needed: remote peer got it.
+ */
+static void
+tunnel_free_reliable_message (struct MeshReliableMessage *copy)
+{
+  struct MeshTunnelReliability *rel;
+  struct GNUNET_TIME_Relative time;
+
+  rel = copy->rel;
+  time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
+  rel->expected_delay.rel_value += time.rel_value;
+  rel->expected_delay.rel_value /= 2;
+  rel->n_sent--;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %llu\n", copy->mid);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
+              GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
+                                                      GNUNET_NO));
+  rel->retry_timer = rel->expected_delay;
+  GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
+  GNUNET_free (copy);
+}
+
+
+/**
  * Mark future messages as ACK'd.
- * 
+ *
  * @param t Tunnel whose sent buffer to clean.
  * @param msg DataACK message with a bitfield of future ACK'd messages.
  */
@@ -2483,10 +2549,8 @@
     }
 
     /* Now copy->mid == target, free it */
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %llu\n", target);
     next = copy->next;
-    GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
-    GNUNET_free (copy);
+    tunnel_free_reliable_message (copy);
     copy = next;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "free_sent_buffer END\n");
@@ -4228,9 +4292,7 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! ACK %llu\n", ack);
   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
   {
-    struct GNUNET_TIME_Relative time;
-
-    if (copy->mid > ack)
+   if (copy->mid > ack)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %llu, out!\n", 
copy->mid);
       tunnel_free_buffer_ucast (t, msg);
@@ -4239,17 +4301,7 @@
     work = GNUNET_YES;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %llu\n", copy->mid);
     next = copy->next;
-    time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
-    rel->expected_delay.rel_value += time.rel_value;
-    rel->expected_delay.rel_value /= 2;
-    rel->n_sent--;
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
-                GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
-                                                        GNUNET_NO));
-    rel->retry_timer = rel->expected_delay;
-    GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
-    GNUNET_free (copy);
+    tunnel_free_reliable_message (copy);
   }
 
   if (GNUNET_YES == work)




reply via email to

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