aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core.h10
-rw-r--r--src/core/core_api_peer_get_info.c21
-rw-r--r--src/core/gnunet-service-core.c360
3 files changed, 168 insertions, 223 deletions
diff --git a/src/core/core.h b/src/core/core.h
index d74ee06f6..45d138140 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -211,7 +211,7 @@ struct RequestInfoMessage
211 * peer to at most the specified amount (naturally, the 211 * peer to at most the specified amount (naturally, the
212 * amount is also limited by the receiving peer). 212 * amount is also limited by the receiving peer).
213 */ 213 */
214 uint32_t limit_outbound_bpm GNUNET_PACKED; 214 struct GNUNET_BANDWIDTH_Value32NBO limit_outbound;
215 215
216 /** 216 /**
217 * Number of bytes of inbound traffic to reserve, can 217 * Number of bytes of inbound traffic to reserve, can
@@ -253,16 +253,16 @@ struct ConfigurationInfoMessage
253 int32_t reserved_amount GNUNET_PACKED; 253 int32_t reserved_amount GNUNET_PACKED;
254 254
255 /** 255 /**
256 * Available bandwidth in (in bytes per minute) for this peer. 256 * Available bandwidth in for this peer.
257 * 0 if we have been disconnected. 257 * 0 if we have been disconnected.
258 */ 258 */
259 uint32_t bpm_in GNUNET_PACKED; 259 struct GNUNET_BANDWIDTH_Value32NBO bw_in;
260 260
261 /** 261 /**
262 * Available bandwidth out (in bytes per minute) for this peer, 262 * Available bandwidth out for this peer,
263 * 0 if we have been disconnected. 263 * 0 if we have been disconnected.
264 */ 264 */
265 uint32_t bpm_out GNUNET_PACKED; 265 struct GNUNET_BANDWIDTH_Value32NBO bw_out;
266 266
267 /** 267 /**
268 * Current traffic preference for the peer. 268 * Current traffic preference for the peer.
diff --git a/src/core/core_api_peer_get_info.c b/src/core/core_api_peer_get_info.c
index cd963375f..c28ae2feb 100644
--- a/src/core/core_api_peer_get_info.c
+++ b/src/core/core_api_peer_get_info.c
@@ -61,12 +61,13 @@ receive_info (void *cls,
61{ 61{
62 struct GNUNET_CORE_InformationRequestContext *irc = cls; 62 struct GNUNET_CORE_InformationRequestContext *irc = cls;
63 const struct ConfigurationInfoMessage *cim; 63 const struct ConfigurationInfoMessage *cim;
64 static struct GNUNET_BANDWIDTH_Value32NBO zbw; /* zero bandwidth */
64 65
65 if (msg == NULL) 66 if (msg == NULL)
66 { 67 {
67 if (irc->info != NULL) 68 if (irc->info != NULL)
68 irc->info (irc->info_cls, 69 irc->info (irc->info_cls,
69 NULL, 0, 0, 0, 0); 70 NULL, zbw, zbw, 0, 0);
70 GNUNET_CLIENT_disconnect (irc->client); 71 GNUNET_CLIENT_disconnect (irc->client);
71 GNUNET_free (irc); 72 GNUNET_free (irc);
72 return; 73 return;
@@ -77,7 +78,7 @@ receive_info (void *cls,
77 GNUNET_break (0); 78 GNUNET_break (0);
78 if (irc->info != NULL) 79 if (irc->info != NULL)
79 irc->info (irc->info_cls, 80 irc->info (irc->info_cls,
80 NULL, 0, 0, 0, 0); 81 NULL, zbw, zbw, 0, 0);
81 GNUNET_CLIENT_disconnect (irc->client); 82 GNUNET_CLIENT_disconnect (irc->client);
82 GNUNET_free (irc); 83 GNUNET_free (irc);
83 return; 84 return;
@@ -86,8 +87,8 @@ receive_info (void *cls,
86 if (irc->info != NULL) 87 if (irc->info != NULL)
87 irc->info (irc->info_cls, 88 irc->info (irc->info_cls,
88 &cim->peer, 89 &cim->peer,
89 ntohl (cim->bpm_in), 90 cim->bw_in,
90 ntohl (cim->bpm_out), 91 cim->bw_out,
91 ntohl (cim->reserved_amount), 92 ntohl (cim->reserved_amount),
92 GNUNET_ntohll (cim->preference)); 93 GNUNET_ntohll (cim->preference));
93 GNUNET_CLIENT_disconnect (irc->client); 94 GNUNET_CLIENT_disconnect (irc->client);
@@ -103,11 +104,11 @@ receive_info (void *cls,
103 * @param peer identifies the peer 104 * @param peer identifies the peer
104 * @param timeout after how long should we give up (and call "info" with NULL 105 * @param timeout after how long should we give up (and call "info" with NULL
105 * for "peer" to signal an error)? 106 * for "peer" to signal an error)?
106 * @param bpm_out set to the current bandwidth limit (sending) for this peer, 107 * @param bw_out set to the current bandwidth limit (sending) for this peer,
107 * caller should set "bpm_out" to "-1" to avoid changing 108 * caller should set "bw_out" to "-1" to avoid changing
108 * the current value; otherwise "bpm_out" will be lowered to 109 * the current value; otherwise "bw_out" will be lowered to
109 * the specified value; passing a pointer to "0" can be used to force 110 * the specified value; passing a pointer to "0" can be used to force
110 * us to disconnect from the peer; "bpm_out" might not increase 111 * us to disconnect from the peer; "bw_out" might not increase
111 * as specified since the upper bound is generally 112 * as specified since the upper bound is generally
112 * determined by the other peer! 113 * determined by the other peer!
113 * @param amount reserve N bytes for receiving, negative 114 * @param amount reserve N bytes for receiving, negative
@@ -125,7 +126,7 @@ GNUNET_CORE_peer_change_preference (struct GNUNET_SCHEDULER_Handle *sched,
125 const struct GNUNET_CONFIGURATION_Handle *cfg, 126 const struct GNUNET_CONFIGURATION_Handle *cfg,
126 const struct GNUNET_PeerIdentity *peer, 127 const struct GNUNET_PeerIdentity *peer,
127 struct GNUNET_TIME_Relative timeout, 128 struct GNUNET_TIME_Relative timeout,
128 uint32_t bpm_out, 129 struct GNUNET_BANDWIDTH_Value32NBO bw_out,
129 int32_t amount, 130 int32_t amount,
130 uint64_t preference, 131 uint64_t preference,
131 GNUNET_CORE_PeerConfigurationInfoCallback info, 132 GNUNET_CORE_PeerConfigurationInfoCallback info,
@@ -146,7 +147,7 @@ GNUNET_CORE_peer_change_preference (struct GNUNET_SCHEDULER_Handle *sched,
146 rim.header.size = htons (sizeof (struct RequestInfoMessage)); 147 rim.header.size = htons (sizeof (struct RequestInfoMessage));
147 rim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO); 148 rim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
148 rim.reserved = htonl (0); 149 rim.reserved = htonl (0);
149 rim.limit_outbound_bpm = htonl (bpm_out); 150 rim.limit_outbound = bw_out;
150 rim.reserve_inbound = htonl (amount); 151 rim.reserve_inbound = htonl (amount);
151 rim.preference_change = GNUNET_htonll(preference); 152 rim.preference_change = GNUNET_htonll(preference);
152 rim.peer = *peer; 153 rim.peer = *peer;
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 0001fccbf..85be80101 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -48,9 +48,9 @@
48/** 48/**
49 * Receive and send buffer windows grow over time. For 49 * Receive and send buffer windows grow over time. For
50 * how long can 'unused' bandwidth accumulate before we 50 * how long can 'unused' bandwidth accumulate before we
51 * need to cap it? (specified in ms). 51 * need to cap it? (specified in seconds).
52 */ 52 */
53#define MAX_WINDOW_TIME (5 * 60 * 1000) 53#define MAX_WINDOW_TIME_S (5 * 60)
54 54
55/** 55/**
56 * How many messages do we queue up at most for optional 56 * How many messages do we queue up at most for optional
@@ -60,17 +60,11 @@
60#define MAX_NOTIFY_QUEUE 16 60#define MAX_NOTIFY_QUEUE 16
61 61
62/** 62/**
63 * Minimum of bytes per minute (out) to assign to any connected peer. 63 * Minimum bandwidth (out) to assign to any connected peer.
64 * Should be rather low; values larger than DEFAULT_BPM_IN_OUT make no 64 * Should be rather low; values larger than DEFAULT_BW_IN_OUT make no
65 * sense. 65 * sense.
66 */ 66 */
67#define MIN_BPM_PER_PEER GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT 67#define MIN_BANDWIDTH_PER_PEER GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT
68
69/**
70 * What is the smallest change (in number of bytes per minute)
71 * that we consider significant enough to bother triggering?
72 */
73#define MIN_BPM_CHANGE 32
74 68
75/** 69/**
76 * After how much time past the "official" expiration time do 70 * After how much time past the "official" expiration time do
@@ -84,27 +78,27 @@
84/** 78/**
85 * What is the maximum delay for a SET_KEY message? 79 * What is the maximum delay for a SET_KEY message?
86 */ 80 */
87#define MAX_SET_KEY_DELAY GNUNET_TIME_UNIT_SECONDS 81#define MAX_SET_KEY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
88 82
89/** 83/**
90 * What how long do we wait for SET_KEY confirmation initially? 84 * What how long do we wait for SET_KEY confirmation initially?
91 */ 85 */
92#define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) 86#define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 3)
93 87
94/** 88/**
95 * What is the maximum delay for a PING message? 89 * What is the maximum delay for a PING message?
96 */ 90 */
97#define MAX_PING_DELAY GNUNET_TIME_UNIT_SECONDS 91#define MAX_PING_DELAY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 2)
98 92
99/** 93/**
100 * What is the maximum delay for a PONG message? 94 * What is the maximum delay for a PONG message?
101 */ 95 */
102#define MAX_PONG_DELAY GNUNET_TIME_UNIT_SECONDS 96#define MAX_PONG_DELAY GNUNET_TIME_relative_multiply (MAX_PING_DELAY, 2)
103 97
104/** 98/**
105 * How often do we recalculate bandwidth quotas? 99 * How often do we recalculate bandwidth quotas?
106 */ 100 */
107#define QUOTA_UPDATE_FREQUENCY GNUNET_TIME_UNIT_SECONDS 101#define QUOTA_UPDATE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
108 102
109/** 103/**
110 * What is the priority for a SET_KEY message? 104 * What is the priority for a SET_KEY message?
@@ -206,11 +200,10 @@ struct EncryptedMessage
206 uint32_t sequence_number GNUNET_PACKED; 200 uint32_t sequence_number GNUNET_PACKED;
207 201
208 /** 202 /**
209 * Desired bandwidth (how much we should send to this 203 * Desired bandwidth (how much we should send to this peer / how
210 * peer / how much is the sender willing to receive), 204 * much is the sender willing to receive)?
211 * in bytes per minute.
212 */ 205 */
213 uint32_t inbound_bpm_limit GNUNET_PACKED; 206 struct GNUNET_BANDWIDTH_Value32NBO inbound_bw_limit;
214 207
215 /** 208 /**
216 * Timestamp. Used to prevent reply of ancient messages 209 * Timestamp. Used to prevent reply of ancient messages
@@ -271,10 +264,9 @@ struct PongMessage
271 264
272 /** 265 /**
273 * Desired bandwidth (how much we should send to this 266 * Desired bandwidth (how much we should send to this
274 * peer / how much is the sender willing to receive), 267 * peer / how much is the sender willing to receive).
275 * in bytes per minute.
276 */ 268 */
277 uint32_t inbound_bpm_limit GNUNET_PACKED; 269 struct GNUNET_BANDWIDTH_Value32NBO inbound_bw_limit;
278 270
279 /** 271 /**
280 * Intended target of the PING, used primarily to check 272 * Intended target of the PING, used primarily to check
@@ -510,32 +502,14 @@ struct Neighbour
510 struct GNUNET_TIME_Relative set_key_retry_frequency; 502 struct GNUNET_TIME_Relative set_key_retry_frequency;
511 503
512 /** 504 /**
513 * Time of our last update to the "available_send_window". 505 * Tracking bandwidth for sending to this peer.
514 */
515 struct GNUNET_TIME_Absolute last_asw_update;
516
517 /**
518 * Time of our last update to the "available_recv_window".
519 */
520 struct GNUNET_TIME_Absolute last_arw_update;
521
522 /**
523 * Number of bytes that we are eligible to transmit to this
524 * peer at this point. Incremented every minute by max_out_bpm,
525 * bounded by max_bpm (no back-log larger than MAX_BUF_FACT minutes,
526 * bandwidth-hogs are sampled at a frequency of about 78s!);
527 * may get negative if we have VERY high priority content.
528 */ 506 */
529 long long available_send_window; 507 struct GNUNET_BANDWIDTH_Tracker available_send_window;
530 508
531 /** 509 /**
532 * How much downstream capacity of this peer has been reserved for 510 * Tracking bandwidth for receiving from this peer.
533 * our traffic? (Our clients can request that a certain amount of
534 * bandwidth is available for replies to them; this value is used to
535 * make sure that this reserved amount of bandwidth is actually
536 * available).
537 */ 511 */
538 long long available_recv_window; 512 struct GNUNET_BANDWIDTH_Tracker available_recv_window;
539 513
540 /** 514 /**
541 * How valueable were the messages of this peer recently? 515 * How valueable were the messages of this peer recently?
@@ -562,26 +536,26 @@ struct Neighbour
562 /** 536 /**
563 * Available bandwidth in for this peer (current target). 537 * Available bandwidth in for this peer (current target).
564 */ 538 */
565 uint32_t bpm_in; 539 struct GNUNET_BANDWIDTH_Value32NBO bw_in;
566 540
567 /** 541 /**
568 * Available bandwidth out for this peer (current target). 542 * Available bandwidth out for this peer (current target).
569 */ 543 */
570 uint32_t bpm_out; 544 struct GNUNET_BANDWIDTH_Value32NBO bw_out;
571 545
572 /** 546 /**
573 * Internal bandwidth limit set for this peer (initially 547 * Internal bandwidth limit set for this peer (initially typically
574 * typically set to "-1"). "bpm_out" is MAX of 548 * set to "-1"). Actual "bw_out" is MIN of
575 * "bpm_out_internal_limit" and "bpm_out_external_limit". 549 * "bpm_out_internal_limit" and "bw_out_external_limit".
576 */ 550 */
577 uint32_t bpm_out_internal_limit; 551 struct GNUNET_BANDWIDTH_Value32NBO bw_out_internal_limit;
578 552
579 /** 553 /**
580 * External bandwidth limit set for this peer by the 554 * External bandwidth limit set for this peer by the
581 * peer that we are communicating with. "bpm_out" is MAX of 555 * peer that we are communicating with. "bw_out" is MIN of
582 * "bpm_out_internal_limit" and "bpm_out_external_limit". 556 * "bw_out_internal_limit" and "bw_out_external_limit".
583 */ 557 */
584 uint32_t bpm_out_external_limit; 558 struct GNUNET_BANDWIDTH_Value32NBO bw_out_external_limit;
585 559
586 /** 560 /**
587 * What was our PING challenge number (for this peer)? 561 * What was our PING challenge number (for this peer)?
@@ -602,6 +576,7 @@ struct Neighbour
602 * Are we currently connected to this neighbour? 576 * Are we currently connected to this neighbour?
603 */ 577 */
604 int is_connected; 578 int is_connected;
579
605}; 580};
606 581
607 582
@@ -703,14 +678,15 @@ static unsigned long long preference_sum;
703static unsigned int neighbour_count; 678static unsigned int neighbour_count;
704 679
705/** 680/**
706 * How much inbound bandwidth are we supposed to be using? 681 * How much inbound bandwidth are we supposed to be using per second?
682 * FIXME: this value is not used!
707 */ 683 */
708static unsigned long long bandwidth_target_in; 684static unsigned long long bandwidth_target_in_bps;
709 685
710/** 686/**
711 * How much outbound bandwidth are we supposed to be using? 687 * How much outbound bandwidth are we supposed to be using per second?
712 */ 688 */
713static unsigned long long bandwidth_target_out; 689static unsigned long long bandwidth_target_out_bps;
714 690
715 691
716 692
@@ -743,50 +719,6 @@ update_preference_sum (unsigned long long inc)
743 719
744 720
745/** 721/**
746 * Recalculate the number of bytes we expect to
747 * receive or transmit in a given window.
748 *
749 * @param force force an update now (even if not much time has passed)
750 * @param window pointer to the byte counter (updated)
751 * @param ts pointer to the timestamp (updated)
752 * @param bpm number of bytes per minute that should
753 * be added to the window.
754 */
755static void
756update_window (int force,
757 long long *window,
758 struct GNUNET_TIME_Absolute *ts, unsigned int bpm)
759{
760 struct GNUNET_TIME_Relative since;
761 unsigned long long increment;
762
763 since = GNUNET_TIME_absolute_get_duration (*ts);
764 increment = (bpm * since.value) / 60 / 1000;
765#if DEBUG_CORE_QUOTA
766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
767 "Updating window with %u bpm after %llu ms by %llu\n",
768 bpm,
769 (unsigned long long) since.value,
770 increment);
771#endif
772 if ( (force == GNUNET_NO) &&
773 (since.value < 60 * 1000) &&
774 (increment < 32 * 1024) )
775 {
776#if DEBUG_CORE_QUOTA
777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
778 "Not updating window, change too small.\n");
779#endif
780 return; /* not even a minute has passed */
781 }
782 *ts = GNUNET_TIME_absolute_get ();
783 *window += increment;
784 if (*window > MAX_WINDOW_TIME * bpm)
785 *window = MAX_WINDOW_TIME * bpm;
786}
787
788
789/**
790 * Find the entry for the given neighbour. 722 * Find the entry for the given neighbour.
791 * 723 *
792 * @param peer identity of the neighbour 724 * @param peer identity of the neighbour
@@ -1004,8 +936,8 @@ handle_client_request_info (void *cls,
1004 const struct RequestInfoMessage *rcm; 936 const struct RequestInfoMessage *rcm;
1005 struct Neighbour *n; 937 struct Neighbour *n;
1006 struct ConfigurationInfoMessage cim; 938 struct ConfigurationInfoMessage cim;
1007 int want_reserv; 939 int32_t want_reserv;
1008 int got_reserv; 940 int32_t got_reserv;
1009 unsigned long long old_preference; 941 unsigned long long old_preference;
1010 struct GNUNET_SERVER_TransmitContext *tc; 942 struct GNUNET_SERVER_TransmitContext *tc;
1011 943
@@ -1019,32 +951,27 @@ handle_client_request_info (void *cls,
1019 if (n != NULL) 951 if (n != NULL)
1020 { 952 {
1021 want_reserv = ntohl (rcm->reserve_inbound); 953 want_reserv = ntohl (rcm->reserve_inbound);
1022 if (n->bpm_out_internal_limit != ntohl (rcm->limit_outbound_bpm)) 954 n->bw_out_internal_limit = rcm->limit_outbound;
1023 update_window (GNUNET_YES, 955 n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1024 &n->available_send_window, 956 n->bw_out_external_limit);
1025 &n->last_asw_update, 957 GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
1026 n->bpm_out); 958 n->bw_out);
1027 n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
1028 n->bpm_out = GNUNET_MIN (n->bpm_out_internal_limit,
1029 n->bpm_out_external_limit);
1030 if (want_reserv < 0) 959 if (want_reserv < 0)
1031 { 960 {
1032 got_reserv = want_reserv; 961 got_reserv = want_reserv;
1033 n->available_recv_window -= want_reserv;
1034 } 962 }
1035 else if (want_reserv > 0) 963 else if (want_reserv > 0)
1036 { 964 {
1037 update_window (GNUNET_NO, 965 if (GNUNET_BANDWIDTH_tracker_get_delay (&n->available_recv_window,
1038 &n->available_recv_window, 966 want_reserv).value == 0)
1039 &n->last_arw_update, n->bpm_in);
1040 if (n->available_recv_window < want_reserv)
1041 got_reserv = 0; /* all or nothing */
1042 else
1043 got_reserv = want_reserv; 967 got_reserv = want_reserv;
1044 n->available_recv_window -= got_reserv; 968 else
969 got_reserv = 0; /* all or nothing */
1045 } 970 }
1046 else 971 else
1047 got_reserv = 0; 972 got_reserv = 0;
973 GNUNET_BANDWIDTH_tracker_consume (&n->available_recv_window,
974 got_reserv);
1048 old_preference = n->current_preference; 975 old_preference = n->current_preference;
1049 n->current_preference += GNUNET_ntohll(rcm->preference_change); 976 n->current_preference += GNUNET_ntohll(rcm->preference_change);
1050 if (old_preference > n->current_preference) 977 if (old_preference > n->current_preference)
@@ -1056,13 +983,13 @@ handle_client_request_info (void *cls,
1056#if DEBUG_CORE_QUOTA 983#if DEBUG_CORE_QUOTA
1057 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 984 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1058 "Received reservation request for %d bytes for peer `%4s', reserved %d bytes\n", 985 "Received reservation request for %d bytes for peer `%4s', reserved %d bytes\n",
1059 want_reserv, 986 (int) want_reserv,
1060 GNUNET_i2s (&rcm->peer), 987 GNUNET_i2s (&rcm->peer),
1061 got_reserv); 988 (int) got_reserv);
1062#endif 989#endif
1063 cim.reserved_amount = htonl (got_reserv); 990 cim.reserved_amount = htonl (got_reserv);
1064 cim.bpm_in = htonl (n->bpm_in); 991 cim.bw_in = n->bw_in;
1065 cim.bpm_out = htonl (n->bpm_out); 992 cim.bw_out = n->bw_out;
1066 cim.preference = n->current_preference; 993 cim.preference = n->current_preference;
1067 } 994 }
1068 cim.header.size = htons (sizeof (struct ConfigurationInfoMessage)); 995 cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
@@ -1247,7 +1174,8 @@ notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1247 GNUNET_assert (size >= m->size); 1174 GNUNET_assert (size >= m->size);
1248 memcpy (cbuf, &m[1], m->size); 1175 memcpy (cbuf, &m[1], m->size);
1249 ret = m->size; 1176 ret = m->size;
1250 n->available_send_window -= m->size; 1177 GNUNET_BANDWIDTH_tracker_consume (&n->available_send_window,
1178 m->size);
1251#if DEBUG_CORE 1179#if DEBUG_CORE
1252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1253 "Copied message of type %u and size %u into transport buffer for `%4s'\n", 1181 "Copied message of type %u and size %u into transport buffer for `%4s'\n",
@@ -1444,9 +1372,9 @@ select_messages (struct Neighbour *n,
1444 unsigned int min_prio; 1372 unsigned int min_prio;
1445 struct GNUNET_TIME_Absolute t; 1373 struct GNUNET_TIME_Absolute t;
1446 struct GNUNET_TIME_Absolute now; 1374 struct GNUNET_TIME_Absolute now;
1447 uint64_t delta; 1375 struct GNUNET_TIME_Relative delta;
1448 uint64_t avail; 1376 uint64_t avail;
1449 unsigned long long slack; /* how long could we wait before missing deadlines? */ 1377 struct GNUNET_TIME_Relative slack; /* how long could we wait before missing deadlines? */
1450 size_t off; 1378 size_t off;
1451 int discard_low_prio; 1379 int discard_low_prio;
1452 unsigned int queue_size; 1380 unsigned int queue_size;
@@ -1472,18 +1400,13 @@ select_messages (struct Neighbour *n,
1472 min_prio = -1; 1400 min_prio = -1;
1473 discard_low_prio = GNUNET_NO; 1401 discard_low_prio = GNUNET_NO;
1474 /* calculate number of bytes available for transmission at time "t" */ 1402 /* calculate number of bytes available for transmission at time "t" */
1475 update_window (GNUNET_NO, 1403 avail = GNUNET_BANDWIDTH_tracker_get_available (&n->available_send_window);
1476 &n->available_send_window, 1404 t = now;
1477 &n->last_asw_update,
1478 n->bpm_out);
1479 avail = n->available_send_window;
1480 t = n->last_asw_update;
1481 /* how many bytes have we (hypothetically) scheduled so far */ 1405 /* how many bytes have we (hypothetically) scheduled so far */
1482 off = 0; 1406 off = 0;
1483 /* maximum time we can wait before transmitting anything 1407 /* maximum time we can wait before transmitting anything
1484 and still make all of our deadlines */ 1408 and still make all of our deadlines */
1485 slack = -1; 1409 slack = GNUNET_TIME_UNIT_FOREVER_REL;
1486
1487 pos = n->messages; 1410 pos = n->messages;
1488 /* note that we use "*2" here because we want to look 1411 /* note that we use "*2" here because we want to look
1489 a bit further into the future; much more makes no 1412 a bit further into the future; much more makes no
@@ -1499,14 +1422,17 @@ select_messages (struct Neighbour *n,
1499 } 1422 }
1500 if (discard_low_prio == GNUNET_NO) 1423 if (discard_low_prio == GNUNET_NO)
1501 { 1424 {
1502 delta = pos->deadline.value; 1425 delta = GNUNET_TIME_absolute_get_difference (t, pos->deadline);
1503 if (delta < t.value) 1426 if (delta.value > 0)
1504 delta = 0; 1427 {
1505 else 1428 // FIXME: HUH? Check!
1506 delta = t.value - delta; 1429 t = pos->deadline;
1507 avail += delta * n->bpm_out / 1000 / 60; 1430 avail += GNUNET_BANDWIDTH_value_get_available_until (n->bw_out,
1431 delta);
1432 }
1508 if (avail < pos->size) 1433 if (avail < pos->size)
1509 { 1434 {
1435 // FIXME: HUH? Check!
1510 discard_low_prio = GNUNET_YES; /* we could not schedule this one! */ 1436 discard_low_prio = GNUNET_YES; /* we could not schedule this one! */
1511 } 1437 }
1512 else 1438 else
@@ -1515,23 +1441,25 @@ select_messages (struct Neighbour *n,
1515 /* update slack, considering both its absolute deadline 1441 /* update slack, considering both its absolute deadline
1516 and relative deadlines caused by other messages 1442 and relative deadlines caused by other messages
1517 with their respective load */ 1443 with their respective load */
1518 slack = GNUNET_MIN (slack, avail / n->bpm_out); 1444 slack = GNUNET_TIME_relative_min (slack,
1445 GNUNET_BANDWIDTH_value_get_delay_for (n->bw_out,
1446 avail));
1519 if ( (pos->deadline.value < now.value) || 1447 if ( (pos->deadline.value < now.value) ||
1520 (GNUNET_YES == pos->got_slack) ) 1448 (GNUNET_YES == pos->got_slack) )
1521 { 1449 {
1522 slack = 0; 1450 slack = GNUNET_TIME_UNIT_ZERO;
1523 } 1451 }
1524 else 1452 else
1525 { 1453 {
1526 slack = 1454 slack =
1527 GNUNET_MIN (slack, pos->deadline.value - now.value); 1455 GNUNET_TIME_relative_min (slack,
1456 GNUNET_TIME_absolute_get_difference (now, pos->deadline));
1528 pos->got_slack = GNUNET_YES; 1457 pos->got_slack = GNUNET_YES;
1529 } 1458 }
1530 } 1459 }
1531 } 1460 }
1532
1533 off += pos->size; 1461 off += pos->size;
1534 t.value = GNUNET_MAX (pos->deadline.value, t.value); 1462 t = GNUNET_TIME_absolute_max (pos->deadline, t); // HUH? Check!
1535 if (pos->priority <= min_prio) 1463 if (pos->priority <= min_prio)
1536 { 1464 {
1537 /* update min for discard */ 1465 /* update min for discard */
@@ -1550,7 +1478,7 @@ select_messages (struct Neighbour *n,
1550 } 1478 }
1551 /* guard against sending "tiny" messages with large headers without 1479 /* guard against sending "tiny" messages with large headers without
1552 urgent deadlines */ 1480 urgent deadlines */
1553 if ( (slack > 1000) && 1481 if ( (slack.value > 1000) &&
1554 (size > 4 * off) && 1482 (size > 4 * off) &&
1555 (queue_size < MAX_PEER_QUEUE_SIZE / 2) ) 1483 (queue_size < MAX_PEER_QUEUE_SIZE / 2) )
1556 { 1484 {
@@ -1786,6 +1714,9 @@ set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1786{ 1714{
1787 struct Neighbour *n = cls; 1715 struct Neighbour *n = cls;
1788 1716
1717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1718 "Retrying key transmission to `%4s'\n",
1719 GNUNET_i2s (&n->peer));
1789 n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; 1720 n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
1790 n->set_key_retry_frequency = 1721 n->set_key_retry_frequency =
1791 GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2); 1722 GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
@@ -1901,13 +1832,13 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
1901 } 1832 }
1902#if DEBUG_CORE_QUOTA 1833#if DEBUG_CORE_QUOTA
1903 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1904 "Sending %llu as new limit to peer `%4s'\n", 1835 "Sending %u b/s as new limit to peer `%4s'\n",
1905 (unsigned long long) n->bpm_in, 1836 (unsigned int) ntohl (n->bw_in.value__),
1906 GNUNET_i2s (&n->peer)); 1837 GNUNET_i2s (&n->peer));
1907#endif 1838#endif
1908 ph->iv_seed = htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, -1)); 1839 ph->iv_seed = htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, -1));
1909 ph->sequence_number = htonl (++n->last_sequence_number_sent); 1840 ph->sequence_number = htonl (++n->last_sequence_number_sent);
1910 ph->inbound_bpm_limit = htonl (n->bpm_in); 1841 ph->inbound_bw_limit = n->bw_in;
1911 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 1842 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1912 1843
1913 /* setup encryption message header */ 1844 /* setup encryption message header */
@@ -1998,10 +1929,10 @@ create_neighbour (const struct GNUNET_PeerIdentity *pid)
1998 n->encrypt_key_created = now; 1929 n->encrypt_key_created = now;
1999 n->last_activity = now; 1930 n->last_activity = now;
2000 n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; 1931 n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2001 n->bpm_in = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT; 1932 n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2002 n->bpm_out = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT; 1933 n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2003 n->bpm_out_internal_limit = (uint32_t) - 1; 1934 n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init ((uint32_t) - 1);
2004 n->bpm_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT; 1935 n->bw_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2005 n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1936 n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2006 (uint32_t) - 1); 1937 (uint32_t) - 1);
2007 schedule_quota_update (n); 1938 schedule_quota_update (n);
@@ -2148,7 +2079,15 @@ static size_t
2148notify_transport_connect_done (void *cls, size_t size, void *buf) 2079notify_transport_connect_done (void *cls, size_t size, void *buf)
2149{ 2080{
2150 struct Neighbour *n = cls; 2081 struct Neighbour *n = cls;
2082
2151 n->th = NULL; 2083 n->th = NULL;
2084 if (buf == NULL)
2085 {
2086 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2087 _("Failed to connect to `%4s': transport failed to connect\n"),
2088 GNUNET_i2s (&n->peer));
2089 return 0;
2090 }
2152 send_key (n); 2091 send_key (n);
2153 return 0; 2092 return 0;
2154} 2093}
@@ -2170,6 +2109,12 @@ handle_client_request_connect (void *cls,
2170 struct Neighbour *n; 2109 struct Neighbour *n;
2171 struct GNUNET_TIME_Relative timeout; 2110 struct GNUNET_TIME_Relative timeout;
2172 2111
2112 if (0 == memcmp (&cm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2113 {
2114 GNUNET_break (0);
2115 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2116 return;
2117 }
2173 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2118 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2174 n = find_neighbour (&cm->peer); 2119 n = find_neighbour (&cm->peer);
2175 if (n == NULL) 2120 if (n == NULL)
@@ -2541,7 +2486,7 @@ handle_ping (struct Neighbour *n, const struct PingMessage *m)
2541 me->priority = PONG_PRIORITY; 2486 me->priority = PONG_PRIORITY;
2542 me->size = sizeof (struct PongMessage); 2487 me->size = sizeof (struct PongMessage);
2543 tx.reserved = htonl (0); 2488 tx.reserved = htonl (0);
2544 tx.inbound_bpm_limit = htonl (n->bpm_in); 2489 tx.inbound_bw_limit = n->bw_in;
2545 tx.challenge = t.challenge; 2490 tx.challenge = t.challenge;
2546 tx.target = t.target; 2491 tx.target = t.target;
2547 tp = (struct PongMessage *) &me[1]; 2492 tp = (struct PongMessage *) &me[1];
@@ -2628,9 +2573,11 @@ handle_pong (struct Neighbour *n,
2628 return; 2573 return;
2629 case PEER_STATE_KEY_RECEIVED: 2574 case PEER_STATE_KEY_RECEIVED:
2630 n->status = PEER_STATE_KEY_CONFIRMED; 2575 n->status = PEER_STATE_KEY_CONFIRMED;
2631 n->bpm_out_external_limit = ntohl (t.inbound_bpm_limit); 2576 n->bw_out_external_limit = t.inbound_bw_limit;
2632 n->bpm_out = GNUNET_MIN (n->bpm_out_external_limit, 2577 n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
2633 n->bpm_out_internal_limit); 2578 n->bw_out_internal_limit);
2579 GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
2580 n->bw_out);
2634#if DEBUG_CORE 2581#if DEBUG_CORE
2635 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2636 "Confirmed key via `%s' message for peer `%4s'\n", 2583 "Confirmed key via `%s' message for peer `%4s'\n",
@@ -3087,22 +3034,18 @@ handle_encrypted_message (struct Neighbour *n,
3087 } 3034 }
3088 3035
3089 /* process decrypted message(s) */ 3036 /* process decrypted message(s) */
3090 if (n->bpm_out_external_limit != ntohl (pt->inbound_bpm_limit))
3091 {
3092 update_window (GNUNET_YES,
3093 &n->available_send_window,
3094 &n->last_asw_update,
3095 n->bpm_out);
3096#if DEBUG_CORE_QUOTA 3037#if DEBUG_CORE_QUOTA
3097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3038 if (n->bw_out_external_limit.value__ != pt->inbound_bw_limit.value__)
3098 "Received %llu as new inbound limit for peer `%4s'\n", 3039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3099 (unsigned long long) ntohl (pt->inbound_bpm_limit), 3040 "Received %u b/s as new inbound limit for peer `%4s'\n",
3100 GNUNET_i2s (&n->peer)); 3041 (unsigned int) ntohl (pt->inbound_bw_limit.value__),
3101#endif 3042 GNUNET_i2s (&n->peer));
3102 } 3043#endif
3103 n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit); 3044 n->bw_out_external_limit = pt->inbound_bw_limit;
3104 n->bpm_out = GNUNET_MIN (n->bpm_out_external_limit, 3045 n->bw_out = GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
3105 n->bpm_out_internal_limit); 3046 n->bw_out_internal_limit);
3047 GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
3048 n->bw_out);
3106 n->last_activity = GNUNET_TIME_absolute_get (); 3049 n->last_activity = GNUNET_TIME_absolute_get ();
3107 off = sizeof (struct EncryptedMessage); 3050 off = sizeof (struct EncryptedMessage);
3108 deliver_messages (n, buf, size, off); 3051 deliver_messages (n, buf, size, off);
@@ -3247,12 +3190,12 @@ neighbour_quota_update (void *cls,
3247 const struct GNUNET_SCHEDULER_TaskContext *tc) 3190 const struct GNUNET_SCHEDULER_TaskContext *tc)
3248{ 3191{
3249 struct Neighbour *n = cls; 3192 struct Neighbour *n = cls;
3250 uint32_t q_in; 3193 struct GNUNET_BANDWIDTH_Value32NBO q_in;
3251 double pref_rel; 3194 double pref_rel;
3252 double share; 3195 double share;
3253 unsigned long long distributable; 3196 unsigned long long distributable;
3254 uint32_t qin_ms; 3197 uint64_t need_per_peer;
3255 uint32_t qout_ms; 3198 uint64_t need_per_second;
3256 3199
3257 n->quota_update_task = GNUNET_SCHEDULER_NO_TASK; 3200 n->quota_update_task = GNUNET_SCHEDULER_NO_TASK;
3258 /* calculate relative preference among all neighbours; 3201 /* calculate relative preference among all neighbours;
@@ -3267,43 +3210,45 @@ neighbour_quota_update (void *cls,
3267 { 3210 {
3268 pref_rel = n->current_preference / preference_sum; 3211 pref_rel = n->current_preference / preference_sum;
3269 } 3212 }
3270 3213 need_per_peer = GNUNET_BANDWIDTH_value_get_available_until (MIN_BANDWIDTH_PER_PEER,
3214 GNUNET_TIME_UNIT_SECONDS);
3215 need_per_second = need_per_peer * neighbour_count;
3271 distributable = 0; 3216 distributable = 0;
3272 if (bandwidth_target_out > neighbour_count * MIN_BPM_PER_PEER) 3217 if (bandwidth_target_out_bps > need_per_second)
3273 distributable = bandwidth_target_out - neighbour_count * MIN_BPM_PER_PEER; 3218 distributable = bandwidth_target_out_bps - need_per_second;
3274 share = distributable * pref_rel; 3219 share = distributable * pref_rel;
3275 q_in = MIN_BPM_PER_PEER + (unsigned long long) share; 3220 if (share + need_per_peer > ( (uint32_t)-1))
3221 q_in = GNUNET_BANDWIDTH_value_init ((uint32_t) -1);
3222 else
3223 q_in = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
3276 /* check if we want to disconnect for good due to inactivity */ 3224 /* check if we want to disconnect for good due to inactivity */
3277 if ( (GNUNET_TIME_absolute_get_duration (n->last_activity).value > GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.value) && 3225 if ( (GNUNET_TIME_absolute_get_duration (n->last_activity).value > GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.value) &&
3278 (GNUNET_TIME_absolute_get_duration (n->time_established).value > GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.value) ) 3226 (GNUNET_TIME_absolute_get_duration (n->time_established).value > GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.value) )
3279 { 3227 {
3280#if DEBUG_CORE 3228#if DEBUG_CORE
3281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3282 "Forcing disconnect of `%4s' due to inactivity (?).\n", 3230 "Forcing disconnect of `%4s' due to inactivity (?).\n",
3283 GNUNET_i2s (&n->peer)); 3231 GNUNET_i2s (&n->peer));
3284#endif 3232#endif
3285 q_in = 0; /* force disconnect */ 3233 q_in = GNUNET_BANDWIDTH_value_init (0); /* force disconnect */
3286 } 3234 }
3287#if DEBUG_CORE_QUOTA 3235#if DEBUG_CORE_QUOTA
3288 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3289 "Current quota for `%4s' is %llu in (old: %llu) / %llu out (%llu internal)\n", 3237 "Current quota for `%4s' is %u/%llu b/s in (old: %u b/s) / %u out (%u internal)\n",
3290 GNUNET_i2s (&n->peer), 3238 GNUNET_i2s (&n->peer),
3291 (unsigned long long) q_in, 3239 (unsigned int) ntohl (q_in.value__),
3292 (unsigned long long) n->bpm_in, 3240 bandwidth_target_out_bps,
3293 (unsigned long long) n->bpm_out, 3241 (unsigned int) ntohl (n->bw_in.value__),
3294 (unsigned long long) n->bpm_out_internal_limit); 3242 (unsigned int) ntohl (n->bw_out.value__),
3295#endif 3243 (unsigned int) ntohl (n->bw_out_internal_limit.value__));
3296 if ( (n->bpm_in + MIN_BPM_CHANGE < q_in) || 3244#endif
3297 (n->bpm_in - MIN_BPM_CHANGE > q_in) ) 3245 if (n->bw_in.value__ != q_in.value__)
3298 { 3246 {
3299 n->bpm_in = q_in; 3247 n->bw_in = q_in;
3300 /* need to convert to bytes / ms, rounding up! */
3301 qin_ms = (q_in == 0) ? 0 : 1 + q_in / 60000;
3302 qout_ms = (n->bpm_out == 0) ? 0 : 1 + n->bpm_out / 60000;
3303 GNUNET_TRANSPORT_set_quota (transport, 3248 GNUNET_TRANSPORT_set_quota (transport,
3304 &n->peer, 3249 &n->peer,
3305 qin_ms, 3250 n->bw_in,
3306 qout_ms, 3251 n->bw_out,
3307 GNUNET_TIME_UNIT_FOREVER_REL, 3252 GNUNET_TIME_UNIT_FOREVER_REL,
3308 NULL, NULL); 3253 NULL, NULL);
3309 } 3254 }
@@ -3348,8 +3293,12 @@ handle_transport_notify_connect (void *cls,
3348 n->is_connected = GNUNET_YES; 3293 n->is_connected = GNUNET_YES;
3349 n->last_latency = latency; 3294 n->last_latency = latency;
3350 n->last_distance = distance; 3295 n->last_distance = distance;
3351 n->last_asw_update = now; 3296 GNUNET_BANDWIDTH_tracker_init (&n->available_send_window,
3352 n->last_arw_update = now; 3297 n->bw_out,
3298 MAX_WINDOW_TIME_S);
3299 GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window,
3300 n->bw_in,
3301 MAX_WINDOW_TIME_S);
3353#if DEBUG_CORE 3302#if DEBUG_CORE
3354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3355 "Received connection from `%4s'.\n", 3304 "Received connection from `%4s'.\n",
@@ -3445,11 +3394,6 @@ run (void *cls,
3445 struct GNUNET_SERVER_Handle *serv, 3394 struct GNUNET_SERVER_Handle *serv,
3446 const struct GNUNET_CONFIGURATION_Handle *c) 3395 const struct GNUNET_CONFIGURATION_Handle *c)
3447{ 3396{
3448#if 0
3449 unsigned long long qin;
3450 unsigned long long qout;
3451 unsigned long long tneigh;
3452#endif
3453 char *keyfile; 3397 char *keyfile;
3454 3398
3455 sched = s; 3399 sched = s;
@@ -3460,12 +3404,12 @@ run (void *cls,
3460 GNUNET_CONFIGURATION_get_value_number (c, 3404 GNUNET_CONFIGURATION_get_value_number (c,
3461 "CORE", 3405 "CORE",
3462 "TOTAL_QUOTA_IN", 3406 "TOTAL_QUOTA_IN",
3463 &bandwidth_target_in)) || 3407 &bandwidth_target_in_bps)) ||
3464 (GNUNET_OK != 3408 (GNUNET_OK !=
3465 GNUNET_CONFIGURATION_get_value_number (c, 3409 GNUNET_CONFIGURATION_get_value_number (c,
3466 "CORE", 3410 "CORE",
3467 "TOTAL_QUOTA_OUT", 3411 "TOTAL_QUOTA_OUT",
3468 &bandwidth_target_out)) || 3412 &bandwidth_target_out_bps)) ||
3469 (GNUNET_OK != 3413 (GNUNET_OK !=
3470 GNUNET_CONFIGURATION_get_value_filename (c, 3414 GNUNET_CONFIGURATION_get_value_filename (c,
3471 "GNUNETD", 3415 "GNUNETD",