diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-02-09 19:15:47 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-02-09 19:15:47 +0000 |
commit | 09104d9e153cfce464ef38cda9ccbba4b029ae11 (patch) | |
tree | 4e31100cf6f0bd5ef925bd40a27abc96bbed4601 /src | |
parent | cca6080579e6c7b1be3bff72a31a528779177fb6 (diff) | |
download | gnunet-09104d9e153cfce464ef38cda9ccbba4b029ae11.tar.gz gnunet-09104d9e153cfce464ef38cda9ccbba4b029ae11.zip |
implement #3295: only transmit background traffic if there is excess bandwidth
Diffstat (limited to 'src')
-rw-r--r-- | src/core/gnunet-service-core_neighbours.c | 67 | ||||
-rw-r--r-- | src/core/gnunet-service-core_neighbours.h | 12 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.c | 33 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.h | 2 |
4 files changed, 98 insertions, 16 deletions
diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c index ddca0859a..aa5b6121e 100644 --- a/src/core/gnunet-service-core_neighbours.c +++ b/src/core/gnunet-service-core_neighbours.c | |||
@@ -105,6 +105,11 @@ struct Neighbour | |||
105 | */ | 105 | */ |
106 | GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task; | 106 | GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task; |
107 | 107 | ||
108 | /** | ||
109 | * #GNUNET_YES if this peer currently has excess bandwidth. | ||
110 | */ | ||
111 | int has_excess_bandwidth; | ||
112 | |||
108 | }; | 113 | }; |
109 | 114 | ||
110 | 115 | ||
@@ -213,13 +218,13 @@ transmit_ready (void *cls, size_t size, void *buf) | |||
213 | 218 | ||
214 | n->th = NULL; | 219 | n->th = NULL; |
215 | m = n->message_head; | 220 | m = n->message_head; |
216 | if (m == NULL) | 221 | if (NULL == m) |
217 | { | 222 | { |
218 | GNUNET_break (0); | 223 | GNUNET_break (0); |
219 | return 0; | 224 | return 0; |
220 | } | 225 | } |
221 | GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); | 226 | GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); |
222 | if (buf == NULL) | 227 | if (NULL == buf) |
223 | { | 228 | { |
224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 229 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
225 | "Transmission of message of type %u and size %u failed\n", | 230 | "Transmission of message of type %u and size %u failed\n", |
@@ -240,6 +245,7 @@ transmit_ready (void *cls, size_t size, void *buf) | |||
240 | ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), | 245 | ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), |
241 | (unsigned int) ret, GNUNET_i2s (&n->peer)); | 246 | (unsigned int) ret, GNUNET_i2s (&n->peer)); |
242 | GNUNET_free (m); | 247 | GNUNET_free (m); |
248 | n->has_excess_bandwidth = GNUNET_NO; | ||
243 | process_queue (n); | 249 | process_queue (n); |
244 | GNUNET_STATISTICS_update (GSC_stats, | 250 | GNUNET_STATISTICS_update (GSC_stats, |
245 | gettext_noop | 251 | gettext_noop |
@@ -450,6 +456,54 @@ GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, | |||
450 | 456 | ||
451 | 457 | ||
452 | /** | 458 | /** |
459 | * One of our neighbours has excess bandwidth, | ||
460 | * remember this. | ||
461 | * | ||
462 | * @param cls NULL | ||
463 | * @param pid identity of the peer with excess bandwidth | ||
464 | */ | ||
465 | static void | ||
466 | handle_transport_notify_excess_bw (void *cls, | ||
467 | const struct GNUNET_PeerIdentity *pid) | ||
468 | { | ||
469 | struct Neighbour *n; | ||
470 | |||
471 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
472 | "Peer %s has excess bandwidth available\n", | ||
473 | GNUNET_i2s (pid)); | ||
474 | n = find_neighbour (pid); | ||
475 | if (NULL == n) | ||
476 | { | ||
477 | GNUNET_break (0); | ||
478 | return; | ||
479 | } | ||
480 | n->has_excess_bandwidth = GNUNET_YES; | ||
481 | GSC_SESSIONS_solicit (pid); | ||
482 | } | ||
483 | |||
484 | |||
485 | /** | ||
486 | * Check if the given neighbour has excess bandwidth available. | ||
487 | * | ||
488 | * @param target neighbour to check | ||
489 | * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not | ||
490 | */ | ||
491 | int | ||
492 | GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target) | ||
493 | { | ||
494 | struct Neighbour *n; | ||
495 | |||
496 | n = find_neighbour (target); | ||
497 | if (NULL == n) | ||
498 | { | ||
499 | GNUNET_break (0); | ||
500 | return GNUNET_SYSERR; | ||
501 | } | ||
502 | return n->has_excess_bandwidth; | ||
503 | } | ||
504 | |||
505 | |||
506 | /** | ||
453 | * Initialize neighbours subsystem. | 507 | * Initialize neighbours subsystem. |
454 | */ | 508 | */ |
455 | int | 509 | int |
@@ -457,10 +511,11 @@ GSC_NEIGHBOURS_init () | |||
457 | { | 511 | { |
458 | neighbours = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); | 512 | neighbours = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); |
459 | transport = | 513 | transport = |
460 | GNUNET_TRANSPORT_connect (GSC_cfg, &GSC_my_identity, NULL, | 514 | GNUNET_TRANSPORT_connect2 (GSC_cfg, &GSC_my_identity, NULL, |
461 | &handle_transport_receive, | 515 | &handle_transport_receive, |
462 | &handle_transport_notify_connect, | 516 | &handle_transport_notify_connect, |
463 | &handle_transport_notify_disconnect); | 517 | &handle_transport_notify_disconnect, |
518 | &handle_transport_notify_excess_bw); | ||
464 | if (NULL == transport) | 519 | if (NULL == transport) |
465 | { | 520 | { |
466 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); | 521 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); |
diff --git a/src/core/gnunet-service-core_neighbours.h b/src/core/gnunet-service-core_neighbours.h index d613c46a5..8dcd20634 100644 --- a/src/core/gnunet-service-core_neighbours.h +++ b/src/core/gnunet-service-core_neighbours.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2009-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -47,6 +47,16 @@ GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, | |||
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Check if the given neighbour has excess bandwidth available. | ||
51 | * | ||
52 | * @param target neighbour to check | ||
53 | * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not | ||
54 | */ | ||
55 | int | ||
56 | GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target); | ||
57 | |||
58 | |||
59 | /** | ||
50 | * Initialize neighbours subsystem. | 60 | * Initialize neighbours subsystem. |
51 | */ | 61 | */ |
52 | int | 62 | int |
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 080bbf88b..4e0ef5e30 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -508,13 +508,20 @@ try_transmission (struct Session *session) | |||
508 | enum GNUNET_CORE_Priority maxp; | 508 | enum GNUNET_CORE_Priority maxp; |
509 | enum GNUNET_CORE_Priority maxpc; | 509 | enum GNUNET_CORE_Priority maxpc; |
510 | struct GSC_ClientActiveRequest *car; | 510 | struct GSC_ClientActiveRequest *car; |
511 | int excess; | ||
511 | 512 | ||
512 | if (GNUNET_YES != session->ready_to_transmit) | 513 | if (GNUNET_YES != session->ready_to_transmit) |
513 | return; | 514 | return; |
514 | msize = 0; | 515 | msize = 0; |
515 | min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; | 516 | min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; |
516 | /* check 'ready' messages */ | 517 | /* if the peer has excess bandwidth, background traffic is allowed, |
517 | maxp = GNUNET_CORE_PRIO_BACKGROUND; | 518 | otherwise not */ |
519 | excess = GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer); | ||
520 | if (GNUNET_YES == excess) | ||
521 | maxp = GNUNET_CORE_PRIO_BACKGROUND; | ||
522 | else | ||
523 | maxp = GNUNET_CORE_PRIO_BEST_EFFORT; | ||
524 | /* determine highest priority of 'ready' messages we already solicited from clients */ | ||
518 | pos = session->sme_head; | 525 | pos = session->sme_head; |
519 | while ((NULL != pos) && | 526 | while ((NULL != pos) && |
520 | (msize + pos->size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)) | 527 | (msize + pos->size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)) |
@@ -527,7 +534,12 @@ try_transmission (struct Session *session) | |||
527 | } | 534 | } |
528 | if (maxp < GNUNET_CORE_PRIO_CRITICAL_CONTROL) | 535 | if (maxp < GNUNET_CORE_PRIO_CRITICAL_CONTROL) |
529 | { | 536 | { |
530 | maxpc = GNUNET_CORE_PRIO_BACKGROUND; | 537 | /* if highest already solicited priority from clients is not critical, |
538 | check if there are higher-priority messages to be solicited from clients */ | ||
539 | if (GNUNET_YES == excess) | ||
540 | maxpc = GNUNET_CORE_PRIO_BACKGROUND; | ||
541 | else | ||
542 | maxpc = GNUNET_CORE_PRIO_BEST_EFFORT; | ||
531 | for (car = session->active_client_request_head; NULL != car; car = car->next) | 543 | for (car = session->active_client_request_head; NULL != car; car = car->next) |
532 | { | 544 | { |
533 | if (GNUNET_YES == car->was_solicited) | 545 | if (GNUNET_YES == car->was_solicited) |
@@ -545,11 +557,15 @@ try_transmission (struct Session *session) | |||
545 | } | 557 | } |
546 | 558 | ||
547 | now = GNUNET_TIME_absolute_get (); | 559 | now = GNUNET_TIME_absolute_get (); |
548 | if ((0 == msize) || | 560 | if ( ( (GNUNET_YES == excess) || |
549 | ((msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) && | 561 | (maxpc >= GNUNET_CORE_PRIO_BEST_EFFORT) ) && |
550 | (min_deadline.abs_value_us > now.abs_value_us))) | 562 | ( (0 == msize) || |
563 | ( (msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) && | ||
564 | (min_deadline.abs_value_us > now.abs_value_us))) ) | ||
551 | { | 565 | { |
552 | /* not enough ready yet, try to solicit more */ | 566 | /* not enough ready yet (tiny message & cork possible), or no messages at all, |
567 | and either excess bandwidth or best-effort or higher message waiting at | ||
568 | client; in this case, we try to solicit more */ | ||
553 | solicit_messages (session, | 569 | solicit_messages (session, |
554 | msize); | 570 | msize); |
555 | if (msize > 0) | 571 | if (msize > 0) |
@@ -565,7 +581,8 @@ try_transmission (struct Session *session) | |||
565 | } | 581 | } |
566 | return; | 582 | return; |
567 | } | 583 | } |
568 | /* create plaintext buffer of all messages, encrypt and transmit */ | 584 | /* create plaintext buffer of all messages (that fit), encrypt and |
585 | transmit */ | ||
569 | { | 586 | { |
570 | static unsigned long long total_bytes; | 587 | static unsigned long long total_bytes; |
571 | static unsigned int total_msgs; | 588 | static unsigned int total_msgs; |
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h index cc88548ec..034026bb8 100644 --- a/src/core/gnunet-service-core_sessions.h +++ b/src/core/gnunet-service-core_sessions.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2009-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |