aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fragmentation/fragmentation.c91
-rw-r--r--src/fragmentation/test_fragmentation.c8
-rw-r--r--src/include/gnunet_fragmentation_lib.h19
-rw-r--r--src/transport/plugin_transport_udp.c53
-rw-r--r--src/transport/plugin_transport_wlan.c5
5 files changed, 119 insertions, 57 deletions
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c
index 4749f5378..19f7ff175 100644
--- a/src/fragmentation/fragmentation.c
+++ b/src/fragmentation/fragmentation.c
@@ -52,7 +52,12 @@ struct GNUNET_FRAGMENT_Context
52 /** 52 /**
53 * Current expected delay for ACKs. 53 * Current expected delay for ACKs.
54 */ 54 */
55 struct GNUNET_TIME_Relative delay; 55 struct GNUNET_TIME_Relative ack_delay;
56
57 /**
58 * Current expected delay between messages.
59 */
60 struct GNUNET_TIME_Relative msg_delay;
56 61
57 /** 62 /**
58 * Next allowed transmission time. 63 * Next allowed transmission time.
@@ -181,11 +186,11 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
181 return; 186 return;
182 } 187 }
183 fc->next_transmission = (fc->next_transmission + 1) % 64; 188 fc->next_transmission = (fc->next_transmission + 1) % 64;
184 wrap |= (fc->next_transmission == 0); 189 wrap |= (0 == fc->next_transmission);
185 while (0 == (fc->acks & (1LL << fc->next_transmission))) 190 while (0 == (fc->acks & (1LL << fc->next_transmission)))
186 { 191 {
187 fc->next_transmission = (fc->next_transmission + 1) % 64; 192 fc->next_transmission = (fc->next_transmission + 1) % 64;
188 wrap |= (fc->next_transmission == 0); 193 wrap |= (0 == fc->next_transmission);
189 } 194 }
190 195
191 /* assemble fragmentation message */ 196 /* assemble fragmentation message */
@@ -217,16 +222,17 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
217 delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize); 222 delay = GNUNET_BANDWIDTH_tracker_get_delay (fc->tracker, fsize);
218 else 223 else
219 delay = GNUNET_TIME_UNIT_ZERO; 224 delay = GNUNET_TIME_UNIT_ZERO;
225 delay = GNUNET_TIME_relative_max (delay,
226 fc->msg_delay);
220 if (wrap) 227 if (wrap)
221 { 228 {
222 /* full round transmitted wait 2x delay for ACK before going again */ 229 /* full round transmitted wait 2x delay for ACK before going again */
223 fc->num_rounds++; 230 fc->num_rounds++;
224 delay = 231 delay = GNUNET_TIME_relative_multiply (delay, 2);
225 GNUNET_TIME_relative_max (GNUNET_TIME_relative_multiply (delay, 2), 232 fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay,
226 GNUNET_TIME_relative_multiply (fc->delay, 233 2 + (size / (fc->mtu - sizeof (struct FragmentHeader))));
227 fc->num_rounds));
228 /* never use zero, need some time for ACK always */ 234 /* never use zero, need some time for ACK always */
229 delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay); 235 delay = GNUNET_TIME_relative_max (MIN_ACK_DELAY, delay);
230 fc->wack = GNUNET_YES; 236 fc->wack = GNUNET_YES;
231 fc->last_round = GNUNET_TIME_absolute_get (); 237 fc->last_round = GNUNET_TIME_absolute_get ();
232 GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1, 238 GNUNET_STATISTICS_update (fc->stats, _("# fragments wrap arounds"), 1,
@@ -250,7 +256,9 @@ transmit_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
250 * @param stats statistics context 256 * @param stats statistics context
251 * @param mtu the maximum message size for each fragment 257 * @param mtu the maximum message size for each fragment
252 * @param tracker bandwidth tracker to use for flow control (can be NULL) 258 * @param tracker bandwidth tracker to use for flow control (can be NULL)
253 * @param delay expected delay between fragment transmission 259 * @param msg_delay initial delay to insert between fragment transmissions
260 * based on previous messages
261 * @param ack_delay expected delay between fragment transmission
254 * and ACK based on previous messages 262 * and ACK based on previous messages
255 * @param msg the message to fragment 263 * @param msg the message to fragment
256 * @param proc function to call for each fragment to transmit 264 * @param proc function to call for each fragment to transmit
@@ -261,7 +269,8 @@ struct GNUNET_FRAGMENT_Context *
261GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, 269GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
262 uint16_t mtu, 270 uint16_t mtu,
263 struct GNUNET_BANDWIDTH_Tracker *tracker, 271 struct GNUNET_BANDWIDTH_Tracker *tracker,
264 struct GNUNET_TIME_Relative delay, 272 struct GNUNET_TIME_Relative msg_delay,
273 struct GNUNET_TIME_Relative ack_delay,
265 const struct GNUNET_MessageHeader *msg, 274 const struct GNUNET_MessageHeader *msg,
266 GNUNET_FRAGMENT_MessageProcessor proc, 275 GNUNET_FRAGMENT_MessageProcessor proc,
267 void *proc_cls) 276 void *proc_cls)
@@ -280,7 +289,8 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
280 fc->stats = stats; 289 fc->stats = stats;
281 fc->mtu = mtu; 290 fc->mtu = mtu;
282 fc->tracker = tracker; 291 fc->tracker = tracker;
283 fc->delay = delay; 292 fc->ack_delay = ack_delay;
293 fc->msg_delay = msg_delay;
284 fc->msg = (const struct GNUNET_MessageHeader *) &fc[1]; 294 fc->msg = (const struct GNUNET_MessageHeader *) &fc[1];
285 fc->proc = proc; 295 fc->proc = proc;
286 fc->proc_cls = proc_cls; 296 fc->proc_cls = proc_cls;
@@ -339,7 +349,11 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
339 const struct FragmentAcknowledgement *fa; 349 const struct FragmentAcknowledgement *fa;
340 uint64_t abits; 350 uint64_t abits;
341 struct GNUNET_TIME_Relative ndelay; 351 struct GNUNET_TIME_Relative ndelay;
352 unsigned int ack_cnt;
353 unsigned int snd_cnt;
354 unsigned int i;
342 355
356 fprintf (stderr, "Got ACK!\n");
343 if (sizeof (struct FragmentAcknowledgement) != ntohs (msg->size)) 357 if (sizeof (struct FragmentAcknowledgement) != ntohs (msg->size))
344 { 358 {
345 GNUNET_break_op (0); 359 GNUNET_break_op (0);
@@ -355,9 +369,40 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
355 /* normal ACK, can update running average of delay... */ 369 /* normal ACK, can update running average of delay... */
356 fc->wack = GNUNET_NO; 370 fc->wack = GNUNET_NO;
357 ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round); 371 ndelay = GNUNET_TIME_absolute_get_duration (fc->last_round);
358 fc->delay.rel_value = 372 fc->ack_delay.rel_value =
359 (ndelay.rel_value / fc->num_transmissions + 3 * fc->delay.rel_value) / 4; 373 (ndelay.rel_value / fc->num_transmissions + 3 * fc->ack_delay.rel_value) / 4;
360 fc->num_transmissions = 0; 374 fc->num_transmissions = 0;
375 /* calculate ratio msg sent vs. msg acked */
376 ack_cnt = 0;
377 snd_cnt = 0;
378 for (i=0;i<64;i++)
379 {
380 if (1 == (fc->acks_mask & (1 << i)))
381 {
382 snd_cnt++;
383 if (0 == (abits & (1 << i)))
384 ack_cnt++;
385 }
386 }
387 if (0 == ack_cnt)
388 {
389 /* complete loss */
390 fc->msg_delay = GNUNET_TIME_relative_multiply (fc->msg_delay,
391 snd_cnt);
392 }
393 else if (snd_cnt > ack_cnt)
394 {
395 /* some loss, slow down proportionally */
396 fc->msg_delay.rel_value = ((fc->msg_delay.rel_value * ack_cnt) / snd_cnt);
397 }
398 else if (0 < fc->msg_delay.rel_value)
399 {
400 fc->msg_delay.rel_value--; /* try a bit faster */
401 }
402 fc->msg_delay = GNUNET_TIME_relative_max (fc->msg_delay,
403 GNUNET_TIME_UNIT_SECONDS);
404 fprintf (stderr, "New msg delay: %llu\n",
405 (unsigned long long )fc->msg_delay.rel_value);
361 } 406 }
362 GNUNET_STATISTICS_update (fc->stats, 407 GNUNET_STATISTICS_update (fc->stats,
363 _("# fragment acknowledgements received"), 1, 408 _("# fragment acknowledgements received"), 1,
@@ -406,19 +451,23 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
406 * resources). 451 * resources).
407 * 452 *
408 * @param fc fragmentation context 453 * @param fc fragmentation context
409 * @return average delay between transmission and ACK for the 454 * @param msg_delay where to store average delay between individual message transmissions the
410 * last message, FOREVER if the message was not fully transmitted 455 * last message (OUT only)
456 * @param ack_delay where to store average delay between transmission and ACK for the
457 * last message, set to FOREVER if the message was not fully transmitted (OUT only)
411 */ 458 */
412struct GNUNET_TIME_Relative 459void
413GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc) 460GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc,
461 struct GNUNET_TIME_Relative *msg_delay,
462 struct GNUNET_TIME_Relative *ack_delay)
414{ 463{
415 struct GNUNET_TIME_Relative ret;
416
417 if (fc->task != GNUNET_SCHEDULER_NO_TASK) 464 if (fc->task != GNUNET_SCHEDULER_NO_TASK)
418 GNUNET_SCHEDULER_cancel (fc->task); 465 GNUNET_SCHEDULER_cancel (fc->task);
419 ret = fc->delay; 466 if (NULL != ack_delay)
467 *ack_delay = fc->ack_delay;
468 if (NULL != msg_delay)
469 *msg_delay = fc->msg_delay;
420 GNUNET_free (fc); 470 GNUNET_free (fc);
421 return ret;
422} 471}
423 472
424 473
diff --git a/src/fragmentation/test_fragmentation.c b/src/fragmentation/test_fragmentation.c
index 0381a8dd0..ecbcdddab 100644
--- a/src/fragmentation/test_fragmentation.c
+++ b/src/fragmentation/test_fragmentation.c
@@ -77,7 +77,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
77 { 77 {
78 if (frags[i] == NULL) 78 if (frags[i] == NULL)
79 continue; 79 continue;
80 GNUNET_FRAGMENT_context_destroy (frags[i]); 80 GNUNET_FRAGMENT_context_destroy (frags[i], NULL, NULL);
81 frags[i] = NULL; 81 frags[i] = NULL;
82 } 82 }
83} 83}
@@ -134,7 +134,7 @@ proc_acks (void *cls, uint32_t msg_id, const struct GNUNET_MessageHeader *hdr)
134#if DETAILS 134#if DETAILS
135 FPRINTF (stderr, "%s", "@"); /* good ACK */ 135 FPRINTF (stderr, "%s", "@"); /* good ACK */
136#endif 136#endif
137 GNUNET_FRAGMENT_context_destroy (frags[i]); 137 GNUNET_FRAGMENT_context_destroy (frags[i], NULL, NULL);
138 frags[i] = NULL; 138 frags[i] = NULL;
139 acks++; 139 acks++;
140 return; 140 return;
@@ -215,7 +215,9 @@ run (void *cls, char *const *args, const char *cfgfile,
215 htons (sizeof (struct GNUNET_MessageHeader) + (17 * i) % (32 * 1024)); 215 htons (sizeof (struct GNUNET_MessageHeader) + (17 * i) % (32 * 1024));
216 frags[i] = GNUNET_FRAGMENT_context_create (NULL /* no stats */ , 216 frags[i] = GNUNET_FRAGMENT_context_create (NULL /* no stats */ ,
217 MTU, &trackers[i], 217 MTU, &trackers[i],
218 GNUNET_TIME_UNIT_SECONDS, msg, 218 GNUNET_TIME_UNIT_MILLISECONDS,
219 GNUNET_TIME_UNIT_SECONDS,
220 msg,
219 &proc_frac, &frags[i]); 221 &proc_frac, &frags[i]);
220 } 222 }
221} 223}
diff --git a/src/include/gnunet_fragmentation_lib.h b/src/include/gnunet_fragmentation_lib.h
index a953bd2b1..b02201867 100644
--- a/src/include/gnunet_fragmentation_lib.h
+++ b/src/include/gnunet_fragmentation_lib.h
@@ -73,7 +73,9 @@ typedef void (*GNUNET_FRAGMENT_MessageProcessor) (void *cls,
73 * @param stats statistics context 73 * @param stats statistics context
74 * @param mtu the maximum message size for each fragment 74 * @param mtu the maximum message size for each fragment
75 * @param tracker bandwidth tracker to use for flow control (can be NULL) 75 * @param tracker bandwidth tracker to use for flow control (can be NULL)
76 * @param delay expected delay between fragment transmission 76 * @param msg_delay initial delay to insert between fragment transmissions
77 * based on previous messages
78 * @param ack_delay expected delay between fragment transmission
77 * and ACK based on previous messages 79 * and ACK based on previous messages
78 * @param msg the message to fragment 80 * @param msg the message to fragment
79 * @param proc function to call for each fragment to transmit 81 * @param proc function to call for each fragment to transmit
@@ -84,7 +86,8 @@ struct GNUNET_FRAGMENT_Context *
84GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, 86GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
85 uint16_t mtu, 87 uint16_t mtu,
86 struct GNUNET_BANDWIDTH_Tracker *tracker, 88 struct GNUNET_BANDWIDTH_Tracker *tracker,
87 struct GNUNET_TIME_Relative delay, 89 struct GNUNET_TIME_Relative msg_delay,
90 struct GNUNET_TIME_Relative ack_delay,
88 const struct GNUNET_MessageHeader *msg, 91 const struct GNUNET_MessageHeader *msg,
89 GNUNET_FRAGMENT_MessageProcessor proc, 92 GNUNET_FRAGMENT_MessageProcessor proc,
90 void *proc_cls); 93 void *proc_cls);
@@ -122,11 +125,15 @@ GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc,
122 * resources). 125 * resources).
123 * 126 *
124 * @param fc fragmentation context 127 * @param fc fragmentation context
125 * @return average delay between transmission and ACK for the 128 * @param msg_delay where to store average delay between individual message transmissions the
126 * last message, FOREVER if the message was not fully transmitted 129 * last message (OUT only)
130 * @param ack_delay where to store average delay between transmission and ACK for the
131 * last message, set to FOREVER if the message was not fully transmitted (OUT only)
127 */ 132 */
128struct GNUNET_TIME_Relative 133void
129GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc); 134GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc,
135 struct GNUNET_TIME_Relative *msg_delay,
136 struct GNUNET_TIME_Relative *ack_delay);
130 137
131 138
132/** 139/**
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index b6b13eab2..18791c264 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -128,7 +128,12 @@ struct Session
128 /** 128 /**
129 * expected delay for ACKs 129 * expected delay for ACKs
130 */ 130 */
131 struct GNUNET_TIME_Relative last_expected_delay; 131 struct GNUNET_TIME_Relative last_expected_ack_delay;
132
133 /**
134 * desired delay between UDP messages
135 */
136 struct GNUNET_TIME_Relative last_expected_msg_delay;
132 137
133 struct GNUNET_ATS_Information ats; 138 struct GNUNET_ATS_Information ats;
134 139
@@ -290,7 +295,7 @@ struct UDP_FragmentationContext
290 size_t on_wire_size; 295 size_t on_wire_size;
291 296
292 unsigned int fragments_used; 297 unsigned int fragments_used;
293 struct GNUNET_TIME_Relative exp_delay; 298
294}; 299};
295 300
296 301
@@ -971,9 +976,9 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
971static void 976static void
972free_session (struct Session *s) 977free_session (struct Session *s)
973{ 978{
974 if (s->frag_ctx != NULL) 979 if (NULL != s->frag_ctx)
975 { 980 {
976 GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag); 981 GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag, NULL, NULL);
977 GNUNET_free (s->frag_ctx); 982 GNUNET_free (s->frag_ctx);
978 s->frag_ctx = NULL; 983 s->frag_ctx = NULL;
979 } 984 }
@@ -1236,7 +1241,8 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
1236 s->addrlen = len; 1241 s->addrlen = len;
1237 s->target = *target; 1242 s->target = *target;
1238 s->sock_addr = (const struct sockaddr *) &s[1]; 1243 s->sock_addr = (const struct sockaddr *) &s[1];
1239 s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS; 1244 s->last_expected_ack_delay = GNUNET_TIME_UNIT_SECONDS;
1245 s->last_expected_msg_delay = GNUNET_TIME_UNIT_MILLISECONDS;
1240 s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS; 1246 s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS;
1241 s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO; 1247 s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO;
1242 start_session_timeout (s); 1248 start_session_timeout (s);
@@ -1561,17 +1567,17 @@ udp_plugin_send (void *cls,
1561 frag_ctx->timeout = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), to); 1567 frag_ctx->timeout = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), to);
1562 frag_ctx->payload_size = msgbuf_size; /* unfragmented message size without UDP overhead */ 1568 frag_ctx->payload_size = msgbuf_size; /* unfragmented message size without UDP overhead */
1563 frag_ctx->on_wire_size = 0; /* bytes with UDP and fragmentation overhead */ 1569 frag_ctx->on_wire_size = 0; /* bytes with UDP and fragmentation overhead */
1570 fprintf (stderr, "New fc with msg delay: %llu and ack delay %llu\n",
1571 (unsigned long long )s->last_expected_msg_delay.rel_value,
1572 (unsigned long long )s->last_expected_ack_delay.rel_value);
1564 frag_ctx->frag = GNUNET_FRAGMENT_context_create (plugin->env->stats, 1573 frag_ctx->frag = GNUNET_FRAGMENT_context_create (plugin->env->stats,
1565 UDP_MTU, 1574 UDP_MTU,
1566 &plugin->tracker, 1575 &plugin->tracker,
1567 GNUNET_TIME_relative_max (s->last_expected_delay, GNUNET_TIME_UNIT_SECONDS), 1576 s->last_expected_msg_delay,
1568 &udp->header, 1577 s->last_expected_ack_delay,
1569 &enqueue_fragment, 1578 &udp->header,
1570 frag_ctx); 1579 &enqueue_fragment,
1571 1580 frag_ctx);
1572 frag_ctx->exp_delay = s->last_expected_delay;
1573 s->frag_ctx = frag_ctx;
1574
1575 GNUNET_STATISTICS_update (plugin->env->stats, 1581 GNUNET_STATISTICS_update (plugin->env->stats,
1576 "# UDP, fragmented msgs, messages, pending", 1582 "# UDP, fragmented msgs, messages, pending",
1577 1, GNUNET_NO); 1583 1, GNUNET_NO);
@@ -1964,7 +1970,9 @@ read_process_ack (struct Plugin *plugin,
1964 "Message full ACK'ed\n", 1970 "Message full ACK'ed\n",
1965 (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), 1971 (unsigned int) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender),
1966 GNUNET_a2s ((const struct sockaddr *) addr, fromlen)); 1972 GNUNET_a2s ((const struct sockaddr *) addr, fromlen));
1967 s->last_expected_delay = GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag); 1973 GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag,
1974 &s->last_expected_msg_delay,
1975 &s->last_expected_ack_delay);
1968 1976
1969 if (s->addrlen == sizeof (struct sockaddr_in6)) 1977 if (s->addrlen == sizeof (struct sockaddr_in6))
1970 { 1978 {
@@ -1994,15 +2002,6 @@ read_process_ack (struct Plugin *plugin,
1994 udpw = tmp; 2002 udpw = tmp;
1995 } 2003 }
1996 } 2004 }
1997/*
1998 LOG (GNUNET_ERROR_TYPE_ERROR,
1999 "Fragmented message sent: fragments needed: %u , payload %u bytes, used on wire %u bytes, overhead: %f, expected delay: %llu\n",
2000 s->frag_ctx->fragments_used,
2001 s->frag_ctx->payload_size,
2002 s->frag_ctx->on_wire_size,
2003 ((float) s->frag_ctx->on_wire_size) / s->frag_ctx->payload_size,
2004 s->frag_ctx->exp_delay.rel_value);
2005*/
2006 dummy.msg_type = MSG_FRAGMENTED_COMPLETE; 2005 dummy.msg_type = MSG_FRAGMENTED_COMPLETE;
2007 dummy.msg_buf = NULL; 2006 dummy.msg_buf = NULL;
2008 dummy.msg_size = s->frag_ctx->on_wire_size; 2007 dummy.msg_size = s->frag_ctx->on_wire_size;
@@ -2190,7 +2189,9 @@ remove_timeout_messages_and_select (struct UDP_MessageWrapper *head,
2190 LOG (GNUNET_ERROR_TYPE_DEBUG, 2189 LOG (GNUNET_ERROR_TYPE_DEBUG,
2191 "Fragment for message for peer `%s' with size %u timed out\n", 2190 "Fragment for message for peer `%s' with size %u timed out\n",
2192 GNUNET_i2s(&udpw->session->target), udpw->frag_ctx->payload_size); 2191 GNUNET_i2s(&udpw->session->target), udpw->frag_ctx->payload_size);
2193 udpw->session->last_expected_delay = GNUNET_FRAGMENT_context_destroy (udpw->frag_ctx->frag); 2192 GNUNET_FRAGMENT_context_destroy (udpw->frag_ctx->frag,
2193 &udpw->session->last_expected_msg_delay,
2194 &udpw->session->last_expected_ack_delay);
2194 GNUNET_free (udpw->frag_ctx); 2195 GNUNET_free (udpw->frag_ctx);
2195 udpw->session->frag_ctx = NULL; 2196 udpw->session->frag_ctx = NULL;
2196 2197
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index b73d444eb..ccf5d587c 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -790,7 +790,7 @@ free_fragment_message (struct FragmentMessage *fm)
790 GNUNET_HELPER_send_cancel (fm->sh); 790 GNUNET_HELPER_send_cancel (fm->sh);
791 fm->sh = NULL; 791 fm->sh = NULL;
792 } 792 }
793 GNUNET_FRAGMENT_context_destroy (fm->fragcontext); 793 GNUNET_FRAGMENT_context_destroy (fm->fragcontext, NULL, NULL);
794 if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK) 794 if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
795 { 795 {
796 GNUNET_SCHEDULER_cancel (fm->timeout_task); 796 GNUNET_SCHEDULER_cancel (fm->timeout_task);
@@ -857,10 +857,13 @@ send_with_fragmentation (struct MacEndpoint *endpoint,
857 fm->timeout = GNUNET_TIME_relative_to_absolute (timeout); 857 fm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
858 fm->cont = cont; 858 fm->cont = cont;
859 fm->cont_cls = cont_cls; 859 fm->cont_cls = cont_cls;
860 /* 1 MBit/s typical data rate, 1430 byte fragments => ~100 ms per message */
860 fm->fragcontext = 861 fm->fragcontext =
861 GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU, 862 GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
862 &plugin->tracker, 863 &plugin->tracker,
863 GNUNET_TIME_UNIT_SECONDS, 864 GNUNET_TIME_UNIT_SECONDS,
865 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
866 100),
864 msg, 867 msg,
865 &transmit_fragment, fm); 868 &transmit_fragment, fm);
866 fm->timeout_task = 869 fm->timeout_task =