/*
This file is part of GNUnet
- Copyright (C) 2009, 2011 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2009, 2011 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @file src/fragmentation/defragmentation.c
/**
* For the current ACK round, which is the first relevant
- * offset in 'frag_times'?
+ * offset in @e frag_times?
*/
unsigned int frag_times_start_offset;
/**
* Which offset whould we write the next frag value into
- * in the 'frag_times' array? All smaller entries are valid.
+ * in the @e frag_times array? All smaller entries are valid.
*/
unsigned int frag_times_write_offset;
*/
uint16_t total_size;
+ /**
+ * Was the last fragment we got a duplicate?
+ */
+ int16_t last_duplicate;
+
};
* Maximum message size for each fragment.
*/
uint16_t mtu;
+
};
* Send acknowledgement to the other peer now.
*
* @param cls the message context
- * @param tc the scheduler context
*/
static void
-send_ack (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+send_ack (void *cls)
{
struct MessageContext *mc = cls;
struct GNUNET_DEFRAGMENT_Context *dc = mc->dc;
_("# acknowledgements sent for fragment"),
1,
GNUNET_NO);
+ mc->last_duplicate = GNUNET_NO; /* clear flag */
dc->ackp (dc->cls,
mc->fragment_id,
&fa.header);
GNUNET_NO);
}
- /* count number of missing fragments */
+ /* count number of missing fragments after the current one */
bc = 0;
- for (b = 0; b < 64; b++)
+ for (b = bit; b < 64; b++)
if (0 != (mc->bits & (1LL << b)))
bc++;
+ else
+ bc = 0;
/* notify about complete message */
- if ( (duplicate == GNUNET_NO) &&
+ if ( (GNUNET_NO == duplicate) &&
(0 == mc->bits) )
{
GNUNET_STATISTICS_update (dc->stats,
delay = GNUNET_TIME_relative_multiply (dc->latency,
bc + 1);
if ( (last + fid == num_fragments) ||
- ( (0 == mc->bits) &&
- (GNUNET_YES != duplicate)) )
+ (0 == mc->bits) ||
+ (GNUNET_YES == duplicate) )
{
/* message complete or duplicate or last missing fragment in
linear sequence; ACK now! */
mc->ack_task = GNUNET_SCHEDULER_add_delayed (delay,
&send_ack,
mc);
- if (duplicate == GNUNET_YES)
+ if (GNUNET_YES == duplicate)
+ {
+ mc->last_duplicate = GNUNET_YES;
return GNUNET_NO;
+ }
return GNUNET_YES;
}