- fix
[oweals/gnunet.git] / src / fragmentation / fragmentation.c
index ef3a57a87b618f7f4f670f88e6c85b3dfcf7b99b..8fab3fee4c74f7c2b6ce3ba990d50361e6677b59 100644 (file)
@@ -99,6 +99,11 @@ struct GNUNET_FRAGMENT_Context
    */
   unsigned int next_transmission;
 
+  /**
+   * How many rounds of transmission have we completed so far?
+   */
+  unsigned int num_rounds;
+
   /**
    * GNUNET_YES if we called 'proc' and are now waiting for 'GNUNET_FRAGMENT_transmission_done'
    */
@@ -152,7 +157,7 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   size = ntohs (fc->msg->size);
   if (bit == size / (fc->mtu - sizeof (struct FragmentHeader)))
     fsize =
-      (size % (fc->mtu - sizeof (struct FragmentHeader))) +
+        (size % (fc->mtu - sizeof (struct FragmentHeader))) +
         sizeof (struct FragmentHeader);
   else
     fsize = fc->mtu;
@@ -200,9 +205,11 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   if (wrap)
   {
     /* full round transmitted wait 2x delay for ACK before going again */
+    fc->num_rounds++;
     delay =
         GNUNET_TIME_relative_max (GNUNET_TIME_relative_multiply (delay, 2),
-                                  fc->delay);
+                                  GNUNET_TIME_relative_multiply (fc->delay,
+                                                                 fc->num_rounds));
     /* never use zero, need some time for ACK always */
     delay = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, delay);
     fc->last_round = GNUNET_TIME_absolute_get ();
@@ -324,12 +331,13 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
   if (ntohl (fa->fragment_id) != fc->fragment_id)
     return GNUNET_SYSERR;       /* not our ACK */
   abits = GNUNET_ntohll (fa->bits);
-  if (GNUNET_YES == fc->wack)
+  if ((GNUNET_YES == fc->wack) && (abits == (fc->acks & abits)))
   {
     /* normal ACK, can update running average of delay... */
     fc->wack = GNUNET_NO;
     ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round);
-    fc->delay.rel_value = (ndelay.rel_value + 3 * fc->delay.rel_value) / 4;
+    fc->delay.rel_value =
+        (ndelay.rel_value * fc->num_rounds + 3 * fc->delay.rel_value) / 4;
   }
   GNUNET_STATISTICS_update (fc->stats,
                             _("# fragment acknowledgements received"), 1,