aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_manipulation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_manipulation.c')
-rw-r--r--src/transport/gnunet-service-transport_manipulation.c75
1 files changed, 62 insertions, 13 deletions
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c
index 76278aa4b..d537dd9b7 100644
--- a/src/transport/gnunet-service-transport_manipulation.c
+++ b/src/transport/gnunet-service-transport_manipulation.c
@@ -48,6 +48,7 @@ enum TRAFFIC_METRIC_DIRECTION
48struct GST_ManipulationHandle man_handle; 48struct GST_ManipulationHandle man_handle;
49 49
50 50
51
51/** 52/**
52 * Struct containing information about manipulations to a specific peer 53 * Struct containing information about manipulations to a specific peer
53 */ 54 */
@@ -151,6 +152,11 @@ struct DelayQueueEntry
151 struct TM_Peer *tmp; 152 struct TM_Peer *tmp;
152 153
153 /** 154 /**
155 * Peer ID
156 */
157 struct GNUNET_PeerIdentity id;
158
159 /**
154 * Absolute time when to send 160 * Absolute time when to send
155 */ 161 */
156 struct GNUNET_TIME_Absolute sent_at; 162 struct GNUNET_TIME_Absolute sent_at;
@@ -182,6 +188,14 @@ struct DelayQueueEntry
182}; 188};
183 189
184 190
191struct DelayQueueEntry *generic_dqe_head;
192struct DelayQueueEntry *generic_dqe_tail;
193
194/**
195 * Task to schedule delayed sendding
196 */
197GNUNET_SCHEDULER_TaskIdentifier generic_send_delay_task;
198
185static void 199static void
186set_metric (struct TM_Peer *dest, int direction, uint32_t type, uint32_t value) 200set_metric (struct TM_Peer *dest, int direction, uint32_t type, uint32_t value)
187{ 201{
@@ -340,16 +354,34 @@ send_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
340 struct DelayQueueEntry *next; 354 struct DelayQueueEntry *next;
341 struct TM_Peer *tmp = dqe->tmp; 355 struct TM_Peer *tmp = dqe->tmp;
342 struct GNUNET_TIME_Relative delay; 356 struct GNUNET_TIME_Relative delay;
343 tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK;
344 GNUNET_CONTAINER_DLL_remove (tmp->send_head, tmp->send_tail, dqe);
345 GST_neighbours_send (&tmp->peer, dqe->msg, dqe->msg_size, dqe->timeout, dqe->cont, dqe->cont_cls);
346 357
347 next = tmp->send_head; 358 if (NULL != tmp)
348 if (NULL != next) 359 {
360 tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK;
361 GNUNET_CONTAINER_DLL_remove (tmp->send_head, tmp->send_tail, dqe);
362 GST_neighbours_send (&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, dqe->cont, dqe->cont_cls);
363
364 next = tmp->send_head;
365 if (NULL != next)
366 {
367 /* More delayed messages */
368 delay = GNUNET_TIME_absolute_get_remaining (next->sent_at);
369 tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe);
370 }
371 }
372 else
349 { 373 {
350 /* More delayed messages */ 374 /* Remove from generic queue */
351 delay = GNUNET_TIME_absolute_get_remaining (next->sent_at); 375 generic_send_delay_task = GNUNET_SCHEDULER_NO_TASK;
352 tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe); 376 GNUNET_CONTAINER_DLL_remove (generic_dqe_head, generic_dqe_tail, dqe);
377 GST_neighbours_send (&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, dqe->cont, dqe->cont_cls);
378 next = generic_dqe_head;
379 if (NULL != next)
380 {
381 /* More delayed messages */
382 delay = GNUNET_TIME_absolute_get_remaining (next->sent_at);
383 generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe);
384 }
353 } 385 }
354 386
355 GNUNET_free (dqe); 387 GNUNET_free (dqe);
@@ -384,6 +416,7 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
384 /* We have a delay */ 416 /* We have a delay */
385 delay.rel_value = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND); 417 delay.rel_value = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND);
386 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); 418 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size);
419 dqe->id = *target;
387 dqe->tmp = tmp; 420 dqe->tmp = tmp;
388 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); 421 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay);
389 dqe->cont = cont; 422 dqe->cont = cont;
@@ -403,7 +436,8 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
403 /* We have a delay */ 436 /* We have a delay */
404 delay.rel_value = find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND); 437 delay.rel_value = find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND);
405 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); 438 dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size);
406 dqe->tmp = tmp; 439 dqe->id = *target;
440 dqe->tmp = NULL;
407 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); 441 dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay);
408 dqe->cont = cont; 442 dqe->cont = cont;
409 dqe->cont_cls = cont_cls; 443 dqe->cont_cls = cont_cls;
@@ -411,9 +445,9 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
411 dqe->msg_size = msg_size; 445 dqe->msg_size = msg_size;
412 dqe->timeout = timeout; 446 dqe->timeout = timeout;
413 memcpy (dqe->msg, msg, msg_size); 447 memcpy (dqe->msg, msg, msg_size);
414 GNUNET_CONTAINER_DLL_insert_tail (tmp->send_head, tmp->send_tail, dqe); 448 GNUNET_CONTAINER_DLL_insert_tail (generic_dqe_head, generic_dqe_tail, dqe);
415 if (GNUNET_SCHEDULER_NO_TASK == tmp->send_delay_task) 449 if (GNUNET_SCHEDULER_NO_TASK == generic_send_delay_task)
416 tmp->send_delay_task =GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe); 450 generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe);
417 return; 451 return;
418 } 452 }
419 453
@@ -597,9 +631,24 @@ free_tmps (void *cls,
597void 631void
598GST_manipulation_stop () 632GST_manipulation_stop ()
599{ 633{
634 struct DelayQueueEntry *cur;
635 struct DelayQueueEntry *next;
600 GNUNET_CONTAINER_multihashmap_iterate (man_handle.peers, &free_tmps,NULL); 636 GNUNET_CONTAINER_multihashmap_iterate (man_handle.peers, &free_tmps,NULL);
601
602 GNUNET_CONTAINER_multihashmap_destroy (man_handle.peers); 637 GNUNET_CONTAINER_multihashmap_destroy (man_handle.peers);
638
639 next = generic_dqe_head;
640 while (NULL != (cur = next))
641 {
642 next = cur->next;
643 GNUNET_CONTAINER_DLL_remove (generic_dqe_head, generic_dqe_tail, cur);
644 GNUNET_free (cur);
645 }
646 if (GNUNET_SCHEDULER_NO_TASK != generic_send_delay_task)
647 {
648 GNUNET_SCHEDULER_cancel (generic_send_delay_task);
649 generic_send_delay_task = GNUNET_SCHEDULER_NO_TASK;
650 }
651
603 free_metric (&man_handle.general); 652 free_metric (&man_handle.general);
604 man_handle.peers = NULL; 653 man_handle.peers = NULL;
605} 654}