diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-03-20 23:22:22 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-03-20 23:22:22 +0000 |
commit | 802381d15888a93efe7be449e4fbbb6a463dcc24 (patch) | |
tree | a7a82824a0494220b6cd7587a635d4823c5d5538 /src/core | |
parent | 74a300e03fb41b97af150ae0a2443bc3b2536746 (diff) | |
download | gnunet-802381d15888a93efe7be449e4fbbb6a463dcc24.tar.gz gnunet-802381d15888a93efe7be449e4fbbb6a463dcc24.zip |
fix #3709: bound encrypted message queue
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/gnunet-service-core_neighbours.c | 44 | ||||
-rw-r--r-- | src/core/gnunet-service-core_neighbours.h | 10 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.c | 10 |
3 files changed, 60 insertions, 4 deletions
diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c index e3f4425e9..cd503a256 100644 --- a/src/core/gnunet-service-core_neighbours.c +++ b/src/core/gnunet-service-core_neighbours.c | |||
@@ -103,7 +103,12 @@ struct Neighbour | |||
103 | /** | 103 | /** |
104 | * ID of task used for re-trying plaintext scheduling. | 104 | * ID of task used for re-trying plaintext scheduling. |
105 | */ | 105 | */ |
106 | struct GNUNET_SCHEDULER_Task * retry_plaintext_task; | 106 | struct GNUNET_SCHEDULER_Task *retry_plaintext_task; |
107 | |||
108 | /** | ||
109 | * How many messages are in the queue for this neighbour? | ||
110 | */ | ||
111 | unsigned int queue_size; | ||
107 | 112 | ||
108 | /** | 113 | /** |
109 | * #GNUNET_YES if this peer currently has excess bandwidth. | 114 | * #GNUNET_YES if this peer currently has excess bandwidth. |
@@ -155,9 +160,13 @@ free_neighbour (struct Neighbour *n) | |||
155 | GNUNET_i2s (&n->peer)); | 160 | GNUNET_i2s (&n->peer)); |
156 | while (NULL != (m = n->message_head)) | 161 | while (NULL != (m = n->message_head)) |
157 | { | 162 | { |
158 | GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); | 163 | GNUNET_CONTAINER_DLL_remove (n->message_head, |
164 | n->message_tail, | ||
165 | m); | ||
166 | n->queue_size--; | ||
159 | GNUNET_free (m); | 167 | GNUNET_free (m); |
160 | } | 168 | } |
169 | GNUNET_assert (0 == n->queue_size); | ||
161 | if (NULL != n->th) | 170 | if (NULL != n->th) |
162 | { | 171 | { |
163 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); | 172 | GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); |
@@ -172,7 +181,7 @@ free_neighbour (struct Neighbour *n) | |||
172 | GSC_KX_stop (n->kxinfo); | 181 | GSC_KX_stop (n->kxinfo); |
173 | n->kxinfo = NULL; | 182 | n->kxinfo = NULL; |
174 | } | 183 | } |
175 | if (n->retry_plaintext_task != NULL) | 184 | if (NULL != n->retry_plaintext_task) |
176 | { | 185 | { |
177 | GNUNET_SCHEDULER_cancel (n->retry_plaintext_task); | 186 | GNUNET_SCHEDULER_cancel (n->retry_plaintext_task); |
178 | n->retry_plaintext_task = NULL; | 187 | n->retry_plaintext_task = NULL; |
@@ -223,7 +232,10 @@ transmit_ready (void *cls, size_t size, void *buf) | |||
223 | GNUNET_break (0); | 232 | GNUNET_break (0); |
224 | return 0; | 233 | return 0; |
225 | } | 234 | } |
226 | GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); | 235 | GNUNET_CONTAINER_DLL_remove (n->message_head, |
236 | n->message_tail, | ||
237 | m); | ||
238 | n->queue_size--; | ||
227 | if (NULL == buf) | 239 | if (NULL == buf) |
228 | { | 240 | { |
229 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 241 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -297,6 +309,7 @@ process_queue (struct Neighbour *n) | |||
297 | GNUNET_CONTAINER_DLL_remove (n->message_head, | 309 | GNUNET_CONTAINER_DLL_remove (n->message_head, |
298 | n->message_tail, | 310 | n->message_tail, |
299 | m); | 311 | m); |
312 | n->queue_size--; | ||
300 | GNUNET_free (m); | 313 | GNUNET_free (m); |
301 | process_queue (n); | 314 | process_queue (n); |
302 | } | 315 | } |
@@ -463,6 +476,7 @@ GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, | |||
463 | GNUNET_CONTAINER_DLL_insert_tail (n->message_head, | 476 | GNUNET_CONTAINER_DLL_insert_tail (n->message_head, |
464 | n->message_tail, | 477 | n->message_tail, |
465 | me); | 478 | me); |
479 | n->queue_size++; | ||
466 | process_queue (n); | 480 | process_queue (n); |
467 | } | 481 | } |
468 | 482 | ||
@@ -495,6 +509,28 @@ handle_transport_notify_excess_bw (void *cls, | |||
495 | 509 | ||
496 | 510 | ||
497 | /** | 511 | /** |
512 | * Check how many messages are queued for the given neighbour. | ||
513 | * | ||
514 | * @param target neighbour to check | ||
515 | * @return number of items in the message queue | ||
516 | */ | ||
517 | unsigned int | ||
518 | GSC_NEIGHBOURS_get_queue_size (const struct GNUNET_PeerIdentity *target) | ||
519 | { | ||
520 | struct Neighbour *n; | ||
521 | |||
522 | n = find_neighbour (target); | ||
523 | if (NULL == n) | ||
524 | { | ||
525 | GNUNET_break (0); | ||
526 | return UINT_MAX; | ||
527 | } | ||
528 | return n->queue_size; | ||
529 | } | ||
530 | |||
531 | |||
532 | |||
533 | /** | ||
498 | * Check if the given neighbour has excess bandwidth available. | 534 | * Check if the given neighbour has excess bandwidth available. |
499 | * | 535 | * |
500 | * @param target neighbour to check | 536 | * @param target neighbour to check |
diff --git a/src/core/gnunet-service-core_neighbours.h b/src/core/gnunet-service-core_neighbours.h index 40baf847e..a951e8fb6 100644 --- a/src/core/gnunet-service-core_neighbours.h +++ b/src/core/gnunet-service-core_neighbours.h | |||
@@ -57,6 +57,16 @@ GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target) | |||
57 | 57 | ||
58 | 58 | ||
59 | /** | 59 | /** |
60 | * Check how many messages are queued for the given neighbour. | ||
61 | * | ||
62 | * @param target neighbour to check | ||
63 | * @return number of items in the message queue | ||
64 | */ | ||
65 | unsigned int | ||
66 | GSC_NEIGHBOURS_get_queue_size (const struct GNUNET_PeerIdentity *target); | ||
67 | |||
68 | |||
69 | /** | ||
60 | * Initialize neighbours subsystem. | 70 | * Initialize neighbours subsystem. |
61 | */ | 71 | */ |
62 | int | 72 | int |
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index a16da8b7e..e4702a03a 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -35,6 +35,13 @@ | |||
35 | 35 | ||
36 | 36 | ||
37 | /** | 37 | /** |
38 | * How many encrypted messages do we queue at most? | ||
39 | * Needed to bound memory consumption. | ||
40 | */ | ||
41 | #define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE 4 | ||
42 | |||
43 | |||
44 | /** | ||
38 | * Message ready for encryption. This struct is followed by the | 45 | * Message ready for encryption. This struct is followed by the |
39 | * actual content of the message. | 46 | * actual content of the message. |
40 | */ | 47 | */ |
@@ -639,6 +646,9 @@ try_transmission (struct Session *session) | |||
639 | min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; | 646 | min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; |
640 | /* if the peer has excess bandwidth, background traffic is allowed, | 647 | /* if the peer has excess bandwidth, background traffic is allowed, |
641 | otherwise not */ | 648 | otherwise not */ |
649 | if (MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE >= | ||
650 | GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer)) | ||
651 | return; /* queue already too long */ | ||
642 | excess = GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer); | 652 | excess = GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer); |
643 | if (GNUNET_YES == excess) | 653 | if (GNUNET_YES == excess) |
644 | maxp = GNUNET_CORE_PRIO_BACKGROUND; | 654 | maxp = GNUNET_CORE_PRIO_BACKGROUND; |