summaryrefslogtreecommitdiff
path: root/src/fragmentation
diff options
context:
space:
mode:
authorBertrand Marc <beberking@gmail.com>2012-06-06 20:47:48 +0200
committerBertrand Marc <beberking@gmail.com>2012-06-06 20:47:48 +0200
commit740b30688bd745a527f96f9116c19acb3480971a (patch)
tree2709a3f4dba11c174aa9e1ba3612e30c578e76a9 /src/fragmentation
parent2b81464a43485fcc8ce079fafdee7b7a171835f4 (diff)
Imported Upstream version 0.9.3upstream/0.9.3
Diffstat (limited to 'src/fragmentation')
-rw-r--r--src/fragmentation/Makefile.am2
-rw-r--r--src/fragmentation/Makefile.in4
-rw-r--r--src/fragmentation/defragmentation.c18
-rw-r--r--src/fragmentation/fragmentation.c36
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,