*/
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'
*/
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;
fh->fragment_id = htonl (fc->fragment_id);
fh->total_size = fc->msg->size; /* already in big-endian */
fh->offset = htons ((fc->mtu - sizeof (struct FragmentHeader)) * bit);
- memcpy (&fh[1],
- &mbuf[bit * (fc->mtu - sizeof (struct FragmentHeader))],
+ memcpy (&fh[1], &mbuf[bit * (fc->mtu - sizeof (struct FragmentHeader))],
fsize - sizeof (struct FragmentHeader));
if (NULL != fc->tracker)
GNUNET_BANDWIDTH_tracker_consume (fc->tracker, fsize);
- GNUNET_STATISTICS_update (fc->stats,
- _("# fragments transmitted"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (fc->stats, _("# fragments transmitted"), 1,
+ GNUNET_NO);
if (0 != fc->last_round.abs_value)
- GNUNET_STATISTICS_update (fc->stats,
- _("# fragments retransmitted"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (fc->stats, _("# fragments retransmitted"), 1,
+ GNUNET_NO);
/* select next message to calculate delay */
bit = fc->next_transmission;
if (wrap)
{
/* full round transmitted wait 2x delay for ACK before going again */
- delay = GNUNET_TIME_relative_max (GNUNET_TIME_relative_multiply (delay, 2),
- fc->delay);
+ fc->num_rounds++;
+ delay =
+ GNUNET_TIME_relative_max (GNUNET_TIME_relative_multiply (delay, 2),
+ 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 ();
GNUNET_STATISTICS_update (stats, _("# messages fragmented"), 1, GNUNET_NO);
GNUNET_assert (mtu >= 1024 + sizeof (struct FragmentHeader));
size = ntohs (msg->size);
- GNUNET_STATISTICS_update (stats,
- _("# total size of fragmented messages"),
+ GNUNET_STATISTICS_update (stats, _("# total size of fragmented messages"),
size, GNUNET_NO);
GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
fc = GNUNET_malloc (sizeof (struct GNUNET_FRAGMENT_Context) + size);
fc->msg = (const struct GNUNET_MessageHeader *) &fc[1];
fc->proc = proc;
fc->proc_cls = proc_cls;
- fc->fragment_id = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
- UINT32_MAX);
+ fc->fragment_id =
+ GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
memcpy (&fc[1], msg, size);
bits =
(size + mtu - sizeof (struct FragmentHeader) - 1) / (mtu -
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, GNUNET_NO);
+ _("# fragment acknowledgements received"), 1,
+ GNUNET_NO);
if (abits != (fc->acks & abits))
{
/* ID collission or message reordering, count! This should be rare! */
GNUNET_STATISTICS_update (fc->stats,
- _("# bits removed from fragmentation ACKs"),
- 1, GNUNET_NO);
+ _("# bits removed from fragmentation ACKs"), 1,
+ GNUNET_NO);
}
fc->acks = abits & fc->acks_mask;
if (0 != fc->acks)
/* all done */
GNUNET_STATISTICS_update (fc->stats,
- _("# fragmentation transmissions completed"),
- 1, GNUNET_NO);
+ _("# fragmentation transmissions completed"), 1,
+ GNUNET_NO);
if (fc->task != GNUNET_SCHEDULER_NO_TASK)
{
GNUNET_SCHEDULER_cancel (fc->task);