aboutsummaryrefslogtreecommitdiff
path: root/src/fragmentation/defragmentation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fragmentation/defragmentation.c')
-rw-r--r--src/fragmentation/defragmentation.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/fragmentation/defragmentation.c b/src/fragmentation/defragmentation.c
index 061277c41..cc6875a9b 100644
--- a/src/fragmentation/defragmentation.c
+++ b/src/fragmentation/defragmentation.c
@@ -420,7 +420,9 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
420 unsigned int bc; 420 unsigned int bc;
421 unsigned int b; 421 unsigned int b;
422 unsigned int n; 422 unsigned int n;
423 unsigned int num_fragments;
423 int duplicate; 424 int duplicate;
425 int last;
424 426
425 if (ntohs (msg->size) < sizeof (struct FragmentHeader)) 427 if (ntohs (msg->size) < sizeof (struct FragmentHeader))
426 { 428 {
@@ -452,6 +454,12 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
452 return GNUNET_SYSERR; 454 return GNUNET_SYSERR;
453 } 455 }
454 GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO); 456 GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO);
457 num_fragments = (ntohs (msg->size) + dc->mtu - sizeof (struct FragmentHeader)-1) / (dc->mtu - sizeof (struct FragmentHeader));
458 last = 0;
459 for (mc = dc->head; NULL != mc; mc = mc->next)
460 if (mc->fragment_id > fid)
461 last++;
462
455 mc = dc->head; 463 mc = dc->head;
456 while ((NULL != mc) && (fid != mc->fragment_id)) 464 while ((NULL != mc) && (fid != mc->fragment_id))
457 mc = mc->next; 465 mc = mc->next;
@@ -530,10 +538,19 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc,
530 } 538 }
531 /* send ACK */ 539 /* send ACK */
532 if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1) 540 if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1)
541 {
533 dc->latency = estimate_latency (mc); 542 dc->latency = estimate_latency (mc);
543 GNUNET_STATISTICS_set (dc->stats, _("# Defragmentation latency estimate (ms)"),
544 dc->latency.rel_value,
545 GNUNET_NO);
546 }
534 delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1); 547 delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1);
535 if ((0 == mc->bits) || (GNUNET_YES == duplicate)) /* message complete or duplicate, ACK now! */ 548 if ( (last + fid == num_fragments) ||
549 (0 == mc->bits) ||
550 (GNUNET_YES == duplicate))
536 { 551 {
552 /* message complete or duplicate or last missing fragment in
553 linear sequence; ACK now! */
537 delay = GNUNET_TIME_UNIT_ZERO; 554 delay = GNUNET_TIME_UNIT_ZERO;
538 } 555 }
539 if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) 556 if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task)