aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-02-09 19:15:47 +0000
committerChristian Grothoff <christian@grothoff.org>2014-02-09 19:15:47 +0000
commit09104d9e153cfce464ef38cda9ccbba4b029ae11 (patch)
tree4e31100cf6f0bd5ef925bd40a27abc96bbed4601 /src
parentcca6080579e6c7b1be3bff72a31a528779177fb6 (diff)
downloadgnunet-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.c67
-rw-r--r--src/core/gnunet-service-core_neighbours.h12
-rw-r--r--src/core/gnunet-service-core_sessions.c33
-rw-r--r--src/core/gnunet-service-core_sessions.h2
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 */
465static void
466handle_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 */
491int
492GSC_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 */
455int 509int
@@ -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 */
55int
56GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target);
57
58
59/**
50 * Initialize neighbours subsystem. 60 * Initialize neighbours subsystem.
51 */ 61 */
52int 62int
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