diff options
author | Bertrand Marc <beberking@gmail.com> | 2012-06-06 20:47:48 +0200 |
---|---|---|
committer | Bertrand Marc <beberking@gmail.com> | 2012-06-06 20:47:48 +0200 |
commit | 740b30688bd745a527f96f9116c19acb3480971a (patch) | |
tree | 2709a3f4dba11c174aa9e1ba3612e30c578e76a9 /src/fragmentation | |
parent | 2b81464a43485fcc8ce079fafdee7b7a171835f4 (diff) |
Imported Upstream version 0.9.3upstream/0.9.3
Diffstat (limited to 'src/fragmentation')
-rw-r--r-- | src/fragmentation/Makefile.am | 2 | ||||
-rw-r--r-- | src/fragmentation/Makefile.in | 4 | ||||
-rw-r--r-- | src/fragmentation/defragmentation.c | 18 | ||||
-rw-r--r-- | src/fragmentation/fragmentation.c | 36 |
4 files changed, 48 insertions, 12 deletions
diff --git a/src/fragmentation/Makefile.am b/src/fragmentation/Makefile.am index 1cdbefc..c5027c7 100644 --- a/src/fragmentation/Makefile.am +++ b/src/fragmentation/Makefile.am @@ -18,7 +18,7 @@ libgnunetfragmentation_la_LIBADD = -lm \ $(top_builddir)/src/util/libgnunetutil.la libgnunetfragmentation_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:1 check_PROGRAMS = \ test_fragmentation diff --git a/src/fragmentation/Makefile.in b/src/fragmentation/Makefile.in index 2ccad77..2c297cb 100644 --- a/src/fragmentation/Makefile.in +++ b/src/fragmentation/Makefile.in @@ -189,6 +189,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -222,6 +223,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -352,7 +354,7 @@ libgnunetfragmentation_la_LIBADD = -lm \ libgnunetfragmentation_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 0:0:0 + -version-info 1:0:1 @ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS) test_fragmentation_SOURCES = \ diff --git a/src/fragmentation/defragmentation.c b/src/fragmentation/defragmentation.c index b07f204..2d3f4a5 100644 --- a/src/fragmentation/defragmentation.c +++ b/src/fragmentation/defragmentation.c @@ -362,7 +362,7 @@ estimate_latency (struct MessageContext *mc) if (ret.rel_value == 0) ret = GNUNET_TIME_UNIT_MILLISECONDS; /* always at least 1 */ return ret; -}; +} /** @@ -420,7 +420,9 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, unsigned int bc; unsigned int b; unsigned int n; + unsigned int num_fragments; int duplicate; + int last; if (ntohs (msg->size) < sizeof (struct FragmentHeader)) { @@ -452,6 +454,12 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, return GNUNET_SYSERR; } GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO); + num_fragments = (ntohs (msg->size) + dc->mtu - sizeof (struct FragmentHeader)-1) / (dc->mtu - sizeof (struct FragmentHeader)); + last = 0; + for (mc = dc->head; NULL != mc; mc = mc->next) + if (mc->fragment_id > fid) + last++; + mc = dc->head; while ((NULL != mc) && (fid != mc->fragment_id)) mc = mc->next; @@ -530,10 +538,16 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, } /* send ACK */ if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1) + { dc->latency = estimate_latency (mc); + } delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1); - if ((0 == mc->bits) || (GNUNET_YES == duplicate)) /* message complete or duplicate, ACK now! */ + if ( (last + fid == num_fragments) || + (0 == mc->bits) || + (GNUNET_YES == duplicate)) { + /* message complete or duplicate or last missing fragment in + linear sequence; ACK now! */ delay = GNUNET_TIME_UNIT_ZERO; } if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c index 8fab3fe..4749f53 100644 --- a/src/fragmentation/fragmentation.c +++ b/src/fragmentation/fragmentation.c @@ -29,6 +29,12 @@ /** + * Absolute minimum delay we impose between sending and expecting ACK to arrive. + */ +#define MIN_ACK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1) + + +/** * Fragmentation context. */ struct GNUNET_FRAGMENT_Context @@ -105,6 +111,11 @@ struct GNUNET_FRAGMENT_Context unsigned int num_rounds; /** + * How many transmission have we completed in this round? + */ + unsigned int num_transmissions; + + /** * GNUNET_YES if we called 'proc' and are now waiting for 'GNUNET_FRAGMENT_transmission_done' */ int8_t proc_busy; @@ -145,13 +156,12 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (GNUNET_NO == fc->proc_busy); if (0 == fc->acks) return; /* all done */ - /* calculate delay */ wrap = 0; while (0 == (fc->acks & (1LL << fc->next_transmission))) { fc->next_transmission = (fc->next_transmission + 1) % 64; - wrap |= (fc->next_transmission == 0); + wrap |= (0 == fc->next_transmission); } bit = fc->next_transmission; size = ntohs (fc->msg->size); @@ -161,7 +171,7 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sizeof (struct FragmentHeader); else fsize = fc->mtu; - if (fc->tracker != NULL) + if (NULL != fc->tracker) delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize); else delay = GNUNET_TIME_UNIT_ZERO; @@ -172,6 +182,11 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } fc->next_transmission = (fc->next_transmission + 1) % 64; wrap |= (fc->next_transmission == 0); + while (0 == (fc->acks & (1LL << fc->next_transmission))) + { + fc->next_transmission = (fc->next_transmission + 1) % 64; + wrap |= (fc->next_transmission == 0); + } /* assemble fragmentation message */ mbuf = (const char *) &fc[1]; @@ -211,12 +226,15 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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 (); + delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay); fc->wack = GNUNET_YES; + fc->last_round = GNUNET_TIME_absolute_get (); + GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1, + GNUNET_NO); } fc->proc_busy = GNUNET_YES; fc->delay_until = GNUNET_TIME_relative_to_absolute (delay); + fc->num_transmissions++; fc->proc (fc->proc_cls, &fh->header); } @@ -251,7 +269,7 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, struct GNUNET_FRAGMENT_Context *fc; size_t size; uint64_t bits; - + GNUNET_STATISTICS_update (stats, _("# messages fragmented"), 1, GNUNET_NO); GNUNET_assert (mtu >= 1024 + sizeof (struct FragmentHeader)); size = ntohs (msg->size); @@ -331,13 +349,15 @@ 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) && (abits == (fc->acks & abits))) + if ( (GNUNET_YES == fc->wack) && + (0 != fc->num_transmissions) ) { /* 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 * fc->num_rounds + 3 * fc->delay.rel_value) / 4; + (ndelay.rel_value / fc->num_transmissions + 3 * fc->delay.rel_value) / 4; + fc->num_transmissions = 0; } GNUNET_STATISTICS_update (fc->stats, _("# fragment acknowledgements received"), 1, |