aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-03-20 23:22:22 +0000
committerChristian Grothoff <christian@grothoff.org>2015-03-20 23:22:22 +0000
commit802381d15888a93efe7be449e4fbbb6a463dcc24 (patch)
treea7a82824a0494220b6cd7587a635d4823c5d5538 /src/core
parent74a300e03fb41b97af150ae0a2443bc3b2536746 (diff)
downloadgnunet-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.c44
-rw-r--r--src/core/gnunet-service-core_neighbours.h10
-rw-r--r--src/core/gnunet-service-core_sessions.c10
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 */
517unsigned int
518GSC_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 */
65unsigned int
66GSC_NEIGHBOURS_get_queue_size (const struct GNUNET_PeerIdentity *target);
67
68
69/**
60 * Initialize neighbours subsystem. 70 * Initialize neighbours subsystem.
61 */ 71 */
62int 72int
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;