diff options
Diffstat (limited to 'src/fragmentation/defragmentation.c')
-rw-r--r-- | src/fragmentation/defragmentation.c | 313 |
1 files changed, 147 insertions, 166 deletions
diff --git a/src/fragmentation/defragmentation.c b/src/fragmentation/defragmentation.c index 8aad86003..35d59854f 100644 --- a/src/fragmentation/defragmentation.c +++ b/src/fragmentation/defragmentation.c | |||
@@ -69,7 +69,7 @@ struct MessageContext | |||
69 | /** | 69 | /** |
70 | * Pointer to the assembled message, allocated at the | 70 | * Pointer to the assembled message, allocated at the |
71 | * end of this struct. | 71 | * end of this struct. |
72 | */ | 72 | */ |
73 | const struct GNUNET_MessageHeader *msg; | 73 | const struct GNUNET_MessageHeader *msg; |
74 | 74 | ||
75 | /** | 75 | /** |
@@ -183,7 +183,7 @@ struct GNUNET_DEFRAGMENT_Context | |||
183 | 183 | ||
184 | /** | 184 | /** |
185 | * Maximum message size for each fragment. | 185 | * Maximum message size for each fragment. |
186 | */ | 186 | */ |
187 | uint16_t mtu; | 187 | uint16_t mtu; |
188 | }; | 188 | }; |
189 | 189 | ||
@@ -203,11 +203,11 @@ struct GNUNET_DEFRAGMENT_Context | |||
203 | */ | 203 | */ |
204 | struct GNUNET_DEFRAGMENT_Context * | 204 | struct GNUNET_DEFRAGMENT_Context * |
205 | GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | 205 | GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, |
206 | uint16_t mtu, | 206 | uint16_t mtu, |
207 | unsigned int num_msgs, | 207 | unsigned int num_msgs, |
208 | void *cls, | 208 | void *cls, |
209 | GNUNET_FRAGMENT_MessageProcessor proc, | 209 | GNUNET_FRAGMENT_MessageProcessor proc, |
210 | GNUNET_DEFRAGMENT_AckProcessor ackp) | 210 | GNUNET_DEFRAGMENT_AckProcessor ackp) |
211 | { | 211 | { |
212 | struct GNUNET_DEFRAGMENT_Context *dc; | 212 | struct GNUNET_DEFRAGMENT_Context *dc; |
213 | 213 | ||
@@ -218,7 +218,7 @@ GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
218 | dc->ackp = ackp; | 218 | dc->ackp = ackp; |
219 | dc->num_msgs = num_msgs; | 219 | dc->num_msgs = num_msgs; |
220 | dc->mtu = mtu; | 220 | dc->mtu = mtu; |
221 | dc->latency = GNUNET_TIME_UNIT_SECONDS; /* start with likely overestimate */ | 221 | dc->latency = GNUNET_TIME_UNIT_SECONDS; /* start with likely overestimate */ |
222 | return dc; | 222 | return dc; |
223 | } | 223 | } |
224 | 224 | ||
@@ -228,24 +228,22 @@ GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
228 | * | 228 | * |
229 | * @param dc defragmentation context | 229 | * @param dc defragmentation context |
230 | */ | 230 | */ |
231 | void | 231 | void |
232 | GNUNET_DEFRAGMENT_context_destroy (struct GNUNET_DEFRAGMENT_Context *dc) | 232 | GNUNET_DEFRAGMENT_context_destroy (struct GNUNET_DEFRAGMENT_Context *dc) |
233 | { | 233 | { |
234 | struct MessageContext *mc; | 234 | struct MessageContext *mc; |
235 | 235 | ||
236 | while (NULL != (mc = dc->head)) | 236 | while (NULL != (mc = dc->head)) |
237 | { | ||
238 | GNUNET_CONTAINER_DLL_remove (dc->head, dc->tail, mc); | ||
239 | dc->list_size--; | ||
240 | if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) | ||
237 | { | 241 | { |
238 | GNUNET_CONTAINER_DLL_remove (dc->head, | 242 | GNUNET_SCHEDULER_cancel (mc->ack_task); |
239 | dc->tail, | 243 | mc->ack_task = GNUNET_SCHEDULER_NO_TASK; |
240 | mc); | ||
241 | dc->list_size--; | ||
242 | if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) | ||
243 | { | ||
244 | GNUNET_SCHEDULER_cancel (mc->ack_task); | ||
245 | mc->ack_task = GNUNET_SCHEDULER_NO_TASK; | ||
246 | } | ||
247 | GNUNET_free (mc); | ||
248 | } | 244 | } |
245 | GNUNET_free (mc); | ||
246 | } | ||
249 | GNUNET_assert (0 == dc->list_size); | 247 | GNUNET_assert (0 == dc->list_size); |
250 | GNUNET_free (dc); | 248 | GNUNET_free (dc); |
251 | } | 249 | } |
@@ -258,8 +256,7 @@ GNUNET_DEFRAGMENT_context_destroy (struct GNUNET_DEFRAGMENT_Context *dc) | |||
258 | * @param tc the scheduler context | 256 | * @param tc the scheduler context |
259 | */ | 257 | */ |
260 | static void | 258 | static void |
261 | send_ack (void *cls, | 259 | send_ack (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
262 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
263 | { | 260 | { |
264 | struct MessageContext *mc = cls; | 261 | struct MessageContext *mc = cls; |
265 | struct GNUNET_DEFRAGMENT_Context *dc = mc->dc; | 262 | struct GNUNET_DEFRAGMENT_Context *dc = mc->dc; |
@@ -271,9 +268,8 @@ send_ack (void *cls, | |||
271 | fa.fragment_id = htonl (mc->fragment_id); | 268 | fa.fragment_id = htonl (mc->fragment_id); |
272 | fa.bits = GNUNET_htonll (mc->bits); | 269 | fa.bits = GNUNET_htonll (mc->bits); |
273 | GNUNET_STATISTICS_update (mc->dc->stats, | 270 | GNUNET_STATISTICS_update (mc->dc->stats, |
274 | _("# acknowledgements sent for fragment"), | 271 | _("# acknowledgements sent for fragment"), |
275 | 1, | 272 | 1, GNUNET_NO); |
276 | GNUNET_NO); | ||
277 | dc->ackp (dc->cls, mc->fragment_id, &fa.header); | 273 | dc->ackp (dc->cls, mc->fragment_id, &fa.header); |
278 | } | 274 | } |
279 | 275 | ||
@@ -285,27 +281,26 @@ send_ack (void *cls, | |||
285 | static void | 281 | static void |
286 | gsl_fit_mul (const double *x, const size_t xstride, | 282 | gsl_fit_mul (const double *x, const size_t xstride, |
287 | const double *y, const size_t ystride, | 283 | const double *y, const size_t ystride, |
288 | const size_t n, | 284 | const size_t n, double *c1, double *cov_11, double *sumsq) |
289 | double *c1, double *cov_11, double *sumsq) | ||
290 | { | 285 | { |
291 | double m_x = 0, m_y = 0, m_dx2 = 0, m_dxdy = 0; | 286 | double m_x = 0, m_y = 0, m_dx2 = 0, m_dxdy = 0; |
292 | 287 | ||
293 | size_t i; | 288 | size_t i; |
294 | 289 | ||
295 | for (i = 0; i < n; i++) | 290 | for (i = 0; i < n; i++) |
296 | { | 291 | { |
297 | m_x += (x[i * xstride] - m_x) / (i + 1.0); | 292 | m_x += (x[i * xstride] - m_x) / (i + 1.0); |
298 | m_y += (y[i * ystride] - m_y) / (i + 1.0); | 293 | m_y += (y[i * ystride] - m_y) / (i + 1.0); |
299 | } | 294 | } |
300 | 295 | ||
301 | for (i = 0; i < n; i++) | 296 | for (i = 0; i < n; i++) |
302 | { | 297 | { |
303 | const double dx = x[i * xstride] - m_x; | 298 | const double dx = x[i * xstride] - m_x; |
304 | const double dy = y[i * ystride] - m_y; | 299 | const double dy = y[i * ystride] - m_y; |
305 | 300 | ||
306 | m_dx2 += (dx * dx - m_dx2) / (i + 1.0); | 301 | m_dx2 += (dx * dx - m_dx2) / (i + 1.0); |
307 | m_dxdy += (dx * dy - m_dxdy) / (i + 1.0); | 302 | m_dxdy += (dx * dy - m_dxdy) / (i + 1.0); |
308 | } | 303 | } |
309 | 304 | ||
310 | /* In terms of y = b x */ | 305 | /* In terms of y = b x */ |
311 | 306 | ||
@@ -318,12 +313,13 @@ gsl_fit_mul (const double *x, const size_t xstride, | |||
318 | /* Compute chi^2 = \sum (y_i - b * x_i)^2 */ | 313 | /* Compute chi^2 = \sum (y_i - b * x_i)^2 */ |
319 | 314 | ||
320 | for (i = 0; i < n; i++) | 315 | for (i = 0; i < n; i++) |
321 | { | 316 | { |
322 | const double dx = x[i * xstride] - m_x; | 317 | const double dx = x[i * xstride] - m_x; |
323 | const double dy = y[i * ystride] - m_y; | 318 | const double dy = y[i * ystride] - m_y; |
324 | const double d = (m_y - b * m_x) + dy - b * dx; | 319 | const double d = (m_y - b * m_x) + dy - b * dx; |
325 | d2 += d * d; | 320 | |
326 | } | 321 | d2 += d * d; |
322 | } | ||
327 | 323 | ||
328 | s2 = d2 / (n - 1.0); /* chisq per degree of freedom */ | 324 | s2 = d2 / (n - 1.0); /* chisq per degree of freedom */ |
329 | 325 | ||
@@ -356,16 +352,16 @@ estimate_latency (struct MessageContext *mc) | |||
356 | 352 | ||
357 | first = &mc->frag_times[mc->frag_times_start_offset]; | 353 | first = &mc->frag_times[mc->frag_times_start_offset]; |
358 | GNUNET_assert (total > 1); | 354 | GNUNET_assert (total > 1); |
359 | for (i=0;i<total;i++) | 355 | for (i = 0; i < total; i++) |
360 | { | 356 | { |
361 | x[i] = (double) i; | 357 | x[i] = (double) i; |
362 | y[i] = (double) (first[i].time.abs_value - first[0].time.abs_value); | 358 | y[i] = (double) (first[i].time.abs_value - first[0].time.abs_value); |
363 | } | 359 | } |
364 | gsl_fit_mul (x, 1, y, 1, total, &c1, &cov11, &sumsq); | 360 | gsl_fit_mul (x, 1, y, 1, total, &c1, &cov11, &sumsq); |
365 | c1 += sqrt (sumsq); /* add 1 std dev */ | 361 | c1 += sqrt (sumsq); /* add 1 std dev */ |
366 | ret.rel_value = (uint64_t) c1; | 362 | ret.rel_value = (uint64_t) c1; |
367 | if (ret.rel_value == 0) | 363 | if (ret.rel_value == 0) |
368 | ret = GNUNET_TIME_UNIT_MILLISECONDS; /* always at least 1 */ | 364 | ret = GNUNET_TIME_UNIT_MILLISECONDS; /* always at least 1 */ |
369 | return ret; | 365 | return ret; |
370 | }; | 366 | }; |
371 | 367 | ||
@@ -384,22 +380,20 @@ discard_oldest_mc (struct GNUNET_DEFRAGMENT_Context *dc) | |||
384 | old = NULL; | 380 | old = NULL; |
385 | pos = dc->head; | 381 | pos = dc->head; |
386 | while (NULL != pos) | 382 | while (NULL != pos) |
387 | { | 383 | { |
388 | if ( (old == NULL) || | 384 | if ((old == NULL) || |
389 | (old->last_update.abs_value > pos->last_update.abs_value) ) | 385 | (old->last_update.abs_value > pos->last_update.abs_value)) |
390 | old = pos; | 386 | old = pos; |
391 | pos = pos->next; | 387 | pos = pos->next; |
392 | } | 388 | } |
393 | GNUNET_assert (NULL != old); | 389 | GNUNET_assert (NULL != old); |
394 | GNUNET_CONTAINER_DLL_remove (dc->head, | 390 | GNUNET_CONTAINER_DLL_remove (dc->head, dc->tail, old); |
395 | dc->tail, | ||
396 | old); | ||
397 | dc->list_size--; | 391 | dc->list_size--; |
398 | if (GNUNET_SCHEDULER_NO_TASK != old->ack_task) | 392 | if (GNUNET_SCHEDULER_NO_TASK != old->ack_task) |
399 | { | 393 | { |
400 | GNUNET_SCHEDULER_cancel (old->ack_task); | 394 | GNUNET_SCHEDULER_cancel (old->ack_task); |
401 | old->ack_task = GNUNET_SCHEDULER_NO_TASK; | 395 | old->ack_task = GNUNET_SCHEDULER_NO_TASK; |
402 | } | 396 | } |
403 | GNUNET_free (old); | 397 | GNUNET_free (old); |
404 | } | 398 | } |
405 | 399 | ||
@@ -411,9 +405,9 @@ discard_oldest_mc (struct GNUNET_DEFRAGMENT_Context *dc) | |||
411 | * @param msg the message that was received | 405 | * @param msg the message that was received |
412 | * @return GNUNET_OK on success, GNUNET_NO if this was a duplicate, GNUNET_SYSERR on error | 406 | * @return GNUNET_OK on success, GNUNET_NO if this was a duplicate, GNUNET_SYSERR on error |
413 | */ | 407 | */ |
414 | int | 408 | int |
415 | GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, | 409 | GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, |
416 | const struct GNUNET_MessageHeader *msg) | 410 | const struct GNUNET_MessageHeader *msg) |
417 | { | 411 | { |
418 | struct MessageContext *mc; | 412 | struct MessageContext *mc; |
419 | const struct FragmentHeader *fh; | 413 | const struct FragmentHeader *fh; |
@@ -429,135 +423,122 @@ GNUNET_DEFRAGMENT_process_fragment (struct GNUNET_DEFRAGMENT_Context *dc, | |||
429 | unsigned int n; | 423 | unsigned int n; |
430 | int duplicate; | 424 | int duplicate; |
431 | 425 | ||
432 | if (ntohs(msg->size) < sizeof (struct FragmentHeader)) | 426 | if (ntohs (msg->size) < sizeof (struct FragmentHeader)) |
433 | { | 427 | { |
434 | GNUNET_break_op (0); | 428 | GNUNET_break_op (0); |
435 | return GNUNET_SYSERR; | 429 | return GNUNET_SYSERR; |
436 | } | 430 | } |
437 | if (ntohs (msg->size) > dc->mtu) | 431 | if (ntohs (msg->size) > dc->mtu) |
438 | { | 432 | { |
439 | GNUNET_break_op (0); | 433 | GNUNET_break_op (0); |
440 | return GNUNET_SYSERR; | 434 | return GNUNET_SYSERR; |
441 | } | 435 | } |
442 | fh = (const struct FragmentHeader*) msg; | 436 | fh = (const struct FragmentHeader *) msg; |
443 | msize = ntohs (fh->total_size); | 437 | msize = ntohs (fh->total_size); |
444 | if (msize < sizeof (struct GNUNET_MessageHeader)) | 438 | if (msize < sizeof (struct GNUNET_MessageHeader)) |
445 | { | 439 | { |
446 | GNUNET_break_op (0); | 440 | GNUNET_break_op (0); |
447 | return GNUNET_SYSERR; | 441 | return GNUNET_SYSERR; |
448 | } | 442 | } |
449 | fid = ntohl (fh->fragment_id); | 443 | fid = ntohl (fh->fragment_id); |
450 | foff = ntohs (fh->offset); | 444 | foff = ntohs (fh->offset); |
451 | if (foff >= msize) | 445 | if (foff >= msize) |
452 | { | 446 | { |
453 | GNUNET_break_op (0); | 447 | GNUNET_break_op (0); |
454 | return GNUNET_SYSERR; | 448 | return GNUNET_SYSERR; |
455 | } | 449 | } |
456 | if (0 != (foff % (dc->mtu - sizeof (struct FragmentHeader)))) | 450 | if (0 != (foff % (dc->mtu - sizeof (struct FragmentHeader)))) |
457 | { | 451 | { |
458 | GNUNET_break_op (0); | 452 | GNUNET_break_op (0); |
459 | return GNUNET_SYSERR; | 453 | return GNUNET_SYSERR; |
460 | } | 454 | } |
461 | GNUNET_STATISTICS_update (dc->stats, | 455 | GNUNET_STATISTICS_update (dc->stats, _("# fragments received"), 1, GNUNET_NO); |
462 | _("# fragments received"), | ||
463 | 1, | ||
464 | GNUNET_NO); | ||
465 | mc = dc->head; | 456 | mc = dc->head; |
466 | while ( (NULL != mc) && | 457 | while ((NULL != mc) && (fid != mc->fragment_id)) |
467 | (fid != mc->fragment_id) ) | ||
468 | mc = mc->next; | 458 | mc = mc->next; |
469 | bit = foff / (dc->mtu - sizeof (struct FragmentHeader)); | 459 | bit = foff / (dc->mtu - sizeof (struct FragmentHeader)); |
470 | if (bit * (dc->mtu - sizeof (struct FragmentHeader)) + ntohs (msg->size) | 460 | if (bit * (dc->mtu - sizeof (struct FragmentHeader)) + ntohs (msg->size) |
471 | - sizeof (struct FragmentHeader) > msize) | 461 | - sizeof (struct FragmentHeader) > msize) |
472 | { | 462 | { |
473 | /* payload extends past total message size */ | 463 | /* payload extends past total message size */ |
474 | GNUNET_break_op (0); | 464 | GNUNET_break_op (0); |
475 | return GNUNET_SYSERR; | 465 | return GNUNET_SYSERR; |
476 | } | 466 | } |
477 | if ( (NULL != mc) && (msize != mc->total_size) ) | 467 | if ((NULL != mc) && (msize != mc->total_size)) |
478 | { | 468 | { |
479 | /* inconsistent message size */ | 469 | /* inconsistent message size */ |
480 | GNUNET_break_op (0); | 470 | GNUNET_break_op (0); |
481 | return GNUNET_SYSERR; | 471 | return GNUNET_SYSERR; |
482 | } | 472 | } |
483 | now = GNUNET_TIME_absolute_get (); | 473 | now = GNUNET_TIME_absolute_get (); |
484 | if (NULL == mc) | 474 | if (NULL == mc) |
485 | { | 475 | { |
486 | mc = GNUNET_malloc (sizeof (struct MessageContext) + msize); | 476 | mc = GNUNET_malloc (sizeof (struct MessageContext) + msize); |
487 | mc->msg = (const struct GNUNET_MessageHeader*) &mc[1]; | 477 | mc->msg = (const struct GNUNET_MessageHeader *) &mc[1]; |
488 | mc->dc = dc; | 478 | mc->dc = dc; |
489 | mc->total_size = msize; | 479 | mc->total_size = msize; |
490 | mc->fragment_id = fid; | 480 | mc->fragment_id = fid; |
491 | mc->last_update = now; | 481 | mc->last_update = now; |
492 | n = (msize + dc->mtu - sizeof (struct FragmentHeader) - 1) / (dc->mtu - sizeof (struct FragmentHeader)); | 482 | n = (msize + dc->mtu - sizeof (struct FragmentHeader) - 1) / (dc->mtu - |
493 | if (n == 64) | 483 | sizeof (struct |
494 | mc->bits = UINT64_MAX; /* set all 64 bit */ | 484 | FragmentHeader)); |
495 | else | 485 | if (n == 64) |
496 | mc->bits = (1LL << n) - 1; /* set lowest 'bits' bit */ | 486 | mc->bits = UINT64_MAX; /* set all 64 bit */ |
497 | if (dc->list_size >= dc->num_msgs) | 487 | else |
498 | discard_oldest_mc (dc); | 488 | mc->bits = (1LL << n) - 1; /* set lowest 'bits' bit */ |
499 | GNUNET_CONTAINER_DLL_insert (dc->head, | 489 | if (dc->list_size >= dc->num_msgs) |
500 | dc->tail, | 490 | discard_oldest_mc (dc); |
501 | mc); | 491 | GNUNET_CONTAINER_DLL_insert (dc->head, dc->tail, mc); |
502 | dc->list_size++; | 492 | dc->list_size++; |
503 | } | 493 | } |
504 | 494 | ||
505 | /* copy data to 'mc' */ | 495 | /* copy data to 'mc' */ |
506 | if (0 != (mc->bits & (1LL << bit))) | 496 | if (0 != (mc->bits & (1LL << bit))) |
507 | { | 497 | { |
508 | mc->bits -= 1LL << bit; | 498 | mc->bits -= 1LL << bit; |
509 | mbuf = (char* )&mc[1]; | 499 | mbuf = (char *) &mc[1]; |
510 | memcpy (&mbuf[bit * (dc->mtu - sizeof (struct FragmentHeader))], | 500 | memcpy (&mbuf[bit * (dc->mtu - sizeof (struct FragmentHeader))], |
511 | &fh[1], | 501 | &fh[1], ntohs (msg->size) - sizeof (struct FragmentHeader)); |
512 | ntohs (msg->size) - sizeof (struct FragmentHeader)); | 502 | mc->last_update = now; |
513 | mc->last_update = now; | 503 | if (bit < mc->last_bit) |
514 | if (bit < mc->last_bit) | 504 | mc->frag_times_start_offset = mc->frag_times_write_offset; |
515 | mc->frag_times_start_offset = mc->frag_times_write_offset; | 505 | mc->last_bit = bit; |
516 | mc->last_bit = bit; | 506 | mc->frag_times[mc->frag_times_write_offset].time = now; |
517 | mc->frag_times[mc->frag_times_write_offset].time = now; | 507 | mc->frag_times[mc->frag_times_write_offset].bit = bit; |
518 | mc->frag_times[mc->frag_times_write_offset].bit = bit; | 508 | mc->frag_times_write_offset++; |
519 | mc->frag_times_write_offset++; | 509 | duplicate = GNUNET_NO; |
520 | duplicate = GNUNET_NO; | 510 | } |
521 | } | ||
522 | else | 511 | else |
523 | { | 512 | { |
524 | duplicate = GNUNET_YES; | 513 | duplicate = GNUNET_YES; |
525 | GNUNET_STATISTICS_update (dc->stats, | 514 | GNUNET_STATISTICS_update (dc->stats, |
526 | _("# duplicate fragments received"), | 515 | _("# duplicate fragments received"), |
527 | 1, | 516 | 1, GNUNET_NO); |
528 | GNUNET_NO); | 517 | } |
529 | } | ||
530 | 518 | ||
531 | /* count number of missing fragments */ | 519 | /* count number of missing fragments */ |
532 | bc = 0; | 520 | bc = 0; |
533 | for (b=0;b<64;b++) | 521 | for (b = 0; b < 64; b++) |
534 | if (0 != (mc->bits & (1LL << b))) bc++; | 522 | if (0 != (mc->bits & (1LL << b))) |
523 | bc++; | ||
535 | if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1) | 524 | if (mc->frag_times_write_offset - mc->frag_times_start_offset > 1) |
536 | dc->latency = estimate_latency (mc); | 525 | dc->latency = estimate_latency (mc); |
537 | delay = GNUNET_TIME_relative_multiply (dc->latency, | 526 | delay = GNUNET_TIME_relative_multiply (dc->latency, bc + 1); |
538 | bc + 1); | 527 | if ((0 == mc->bits) || (GNUNET_YES == duplicate)) /* message complete or duplicate, ACK now! */ |
539 | if ( (0 == mc->bits) || (GNUNET_YES == duplicate) ) /* message complete or duplicate, ACK now! */ | ||
540 | delay = GNUNET_TIME_UNIT_ZERO; | 528 | delay = GNUNET_TIME_UNIT_ZERO; |
541 | if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) | 529 | if (GNUNET_SCHEDULER_NO_TASK != mc->ack_task) |
542 | GNUNET_SCHEDULER_cancel (mc->ack_task); | 530 | GNUNET_SCHEDULER_cancel (mc->ack_task); |
543 | mc->ack_task = GNUNET_SCHEDULER_add_delayed (delay, | 531 | mc->ack_task = GNUNET_SCHEDULER_add_delayed (delay, &send_ack, mc); |
544 | &send_ack, | 532 | if ((duplicate == GNUNET_NO) && (0 == mc->bits)) |
545 | mc); | 533 | { |
546 | if ( (duplicate == GNUNET_NO) && | 534 | GNUNET_STATISTICS_update (dc->stats, |
547 | (0 == mc->bits) ) | 535 | _("# messages defragmented"), 1, GNUNET_NO); |
548 | { | 536 | /* message complete, notify! */ |
549 | GNUNET_STATISTICS_update (dc->stats, | 537 | dc->proc (dc->cls, mc->msg); |
550 | _("# messages defragmented"), | 538 | } |
551 | 1, | ||
552 | GNUNET_NO); | ||
553 | /* message complete, notify! */ | ||
554 | dc->proc (dc->cls, | ||
555 | mc->msg); | ||
556 | } | ||
557 | if (duplicate == GNUNET_YES) | 539 | if (duplicate == GNUNET_YES) |
558 | return GNUNET_NO; | 540 | return GNUNET_NO; |
559 | return GNUNET_YES; | 541 | return GNUNET_YES; |
560 | } | 542 | } |
561 | 543 | ||
562 | /* end of defragmentation.c */ | 544 | /* end of defragmentation.c */ |
563 | |||