aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-02-26 12:50:50 +0000
committerChristian Grothoff <christian@grothoff.org>2010-02-26 12:50:50 +0000
commitbc22ad5ddb9e582bf7d3479711f25b4bdfb9989b (patch)
tree7792689161d18dd4f253967c06c53dfad03a09e6 /src
parentfa70ed546a994f84b49b541d1b0af0a14c4589b6 (diff)
downloadgnunet-bc22ad5ddb9e582bf7d3479711f25b4bdfb9989b.tar.gz
gnunet-bc22ad5ddb9e582bf7d3479711f25b4bdfb9989b.zip
fixing quota calculations, send initial quota with PONG
Diffstat (limited to 'src')
-rw-r--r--src/core/gnunet-service-core.c162
1 files changed, 131 insertions, 31 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index bb4d34dfe..2cd4039fe 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -218,6 +218,7 @@ struct EncryptedMessage
218 218
219}; 219};
220 220
221
221/** 222/**
222 * We're sending an (encrypted) PING to the other peer to check if he 223 * We're sending an (encrypted) PING to the other peer to check if he
223 * can decrypt. The other peer should respond with a PONG with the 224 * can decrypt. The other peer should respond with a PONG with the
@@ -226,7 +227,7 @@ struct EncryptedMessage
226struct PingMessage 227struct PingMessage
227{ 228{
228 /** 229 /**
229 * Message type is either CORE_PING or CORE_PONG. 230 * Message type is CORE_PING.
230 */ 231 */
231 struct GNUNET_MessageHeader header; 232 struct GNUNET_MessageHeader header;
232 233
@@ -243,6 +244,43 @@ struct PingMessage
243}; 244};
244 245
245 246
247
248/**
249 * Response to a PING. Includes data from the original PING
250 * plus initial bandwidth quota information.
251 */
252struct PongMessage
253{
254 /**
255 * Message type is CORE_PONG.
256 */
257 struct GNUNET_MessageHeader header;
258
259 /**
260 * Random number proochosen to make reply harder.
261 */
262 uint32_t challenge GNUNET_PACKED;
263
264 /**
265 * Must be zero.
266 */
267 uint32_t reserved GNUNET_PACKED;
268
269 /**
270 * Desired bandwidth (how much we should send to this
271 * peer / how much is the sender willing to receive),
272 * in bytes per minute.
273 */
274 uint32_t inbound_bpm_limit GNUNET_PACKED;
275
276 /**
277 * Intended target of the PING, used primarily to check
278 * that decryption actually worked.
279 */
280 struct GNUNET_PeerIdentity target;
281};
282
283
246/** 284/**
247 * Message transmitted to set (or update) a session key. 285 * Message transmitted to set (or update) a session key.
248 */ 286 */
@@ -385,7 +423,7 @@ struct Neighbour
385 * (or the SET_KEY). We keep it here until we have a key 423 * (or the SET_KEY). We keep it here until we have a key
386 * to decrypt it. NULL if no PONG is pending. 424 * to decrypt it. NULL if no PONG is pending.
387 */ 425 */
388 struct PingMessage *pending_pong; 426 struct PongMessage *pending_pong;
389 427
390 /** 428 /**
391 * Non-NULL if we are currently looking up HELLOs for this peer. 429 * Non-NULL if we are currently looking up HELLOs for this peer.
@@ -721,10 +759,23 @@ update_window (int force,
721 759
722 since = GNUNET_TIME_absolute_get_duration (*ts); 760 since = GNUNET_TIME_absolute_get_duration (*ts);
723 increment = (bpm * since.value) / 60 / 1000; 761 increment = (bpm * since.value) / 60 / 1000;
762#if DEBUG_CORE_QUOTA
763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
764 "Updating window with %u bpm after %llu ms by %llu\n",
765 bpm,
766 (unsigned long long) since.value,
767 increment);
768#endif
724 if ( (force == GNUNET_NO) && 769 if ( (force == GNUNET_NO) &&
725 (since.value < 60 * 1000) && 770 (since.value < 60 * 1000) &&
726 (increment < 32 * 1024) ) 771 (increment < 32 * 1024) )
727 return; /* not even a minute has passed */ 772 {
773#if DEBUG_CORE_QUOTA
774 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
775 "Not updating window, change too small.\n");
776#endif
777 return; /* not even a minute has passed */
778 }
728 *ts = GNUNET_TIME_absolute_get (); 779 *ts = GNUNET_TIME_absolute_get ();
729 *window += increment; 780 *window += increment;
730 if (*window > MAX_WINDOW_TIME * bpm) 781 if (*window > MAX_WINDOW_TIME * bpm)
@@ -964,14 +1015,15 @@ handle_client_request_info (void *cls,
964 memset (&cim, 0, sizeof (cim)); 1015 memset (&cim, 0, sizeof (cim));
965 if (n != NULL) 1016 if (n != NULL)
966 { 1017 {
967 update_window (GNUNET_YES, 1018 want_reserv = ntohl (rcm->reserve_inbound);
968 &n->available_send_window, 1019 if (n->bpm_out_internal_limit != ntohl (rcm->limit_outbound_bpm))
969 &n->last_asw_update, 1020 update_window (GNUNET_YES,
970 n->bpm_out); 1021 &n->available_send_window,
1022 &n->last_asw_update,
1023 n->bpm_out);
971 n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm); 1024 n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
972 n->bpm_out = GNUNET_MAX (n->bpm_out_internal_limit, 1025 n->bpm_out = GNUNET_MIN (n->bpm_out_internal_limit,
973 n->bpm_out_external_limit); 1026 n->bpm_out_external_limit);
974 want_reserv = ntohl (rcm->reserve_inbound);
975 if (want_reserv < 0) 1027 if (want_reserv < 0)
976 { 1028 {
977 n->available_recv_window += want_reserv; 1029 n->available_recv_window += want_reserv;
@@ -995,11 +1047,13 @@ handle_client_request_info (void *cls,
995 n->current_preference = (unsigned long long) -1; 1047 n->current_preference = (unsigned long long) -1;
996 } 1048 }
997 update_preference_sum (n->current_preference - old_preference); 1049 update_preference_sum (n->current_preference - old_preference);
998 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1050#if DEBUG_CORE_QUOTA
1051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
999 "Received reservation request for %d bytes for peer `%4s', reserved %d bytes\n", 1052 "Received reservation request for %d bytes for peer `%4s', reserved %d bytes\n",
1000 want_reserv, 1053 want_reserv,
1001 GNUNET_i2s (&rcm->peer), 1054 GNUNET_i2s (&rcm->peer),
1002 got_reserv); 1055 got_reserv);
1056#endif
1003 cim.reserved_amount = htonl (got_reserv); 1057 cim.reserved_amount = htonl (got_reserv);
1004 cim.bpm_in = htonl (n->bpm_in); 1058 cim.bpm_in = htonl (n->bpm_in);
1005 cim.bpm_out = htonl (n->bpm_out); 1059 cim.bpm_out = htonl (n->bpm_out);
@@ -1828,6 +1882,12 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
1828 &retry_plaintext_processing, n); 1882 &retry_plaintext_processing, n);
1829 return; 1883 return;
1830 } 1884 }
1885#if DEBUG_CORE_QUOTA
1886 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1887 "Sending %llu as new limit to peer `%4s'\n",
1888 (unsigned long long) n->bpm_in,
1889 GNUNET_i2s (&n->peer));
1890#endif
1831 ph->iv_seed = htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, -1)); 1891 ph->iv_seed = htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, -1));
1832 ph->sequence_number = htonl (++n->last_sequence_number_sent); 1892 ph->sequence_number = htonl (++n->last_sequence_number_sent);
1833 ph->inbound_bpm_limit = htonl (n->bpm_in); 1893 ph->inbound_bpm_limit = htonl (n->bpm_in);
@@ -2429,7 +2489,8 @@ static void
2429handle_ping (struct Neighbour *n, const struct PingMessage *m) 2489handle_ping (struct Neighbour *n, const struct PingMessage *m)
2430{ 2490{
2431 struct PingMessage t; 2491 struct PingMessage t;
2432 struct PingMessage *tp; 2492 struct PongMessage tx;
2493 struct PongMessage *tp;
2433 struct MessageEntry *me; 2494 struct MessageEntry *me;
2434 2495
2435#if DEBUG_CORE 2496#if DEBUG_CORE
@@ -2462,22 +2523,26 @@ handle_ping (struct Neighbour *n, const struct PingMessage *m)
2462 return; 2523 return;
2463 } 2524 }
2464 me = GNUNET_malloc (sizeof (struct MessageEntry) + 2525 me = GNUNET_malloc (sizeof (struct MessageEntry) +
2465 sizeof (struct PingMessage)); 2526 sizeof (struct PongMessage));
2466 GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, 2527 GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head,
2467 n->encrypted_tail, 2528 n->encrypted_tail,
2468 n->encrypted_tail, 2529 n->encrypted_tail,
2469 me); 2530 me);
2470 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY); 2531 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
2471 me->priority = PONG_PRIORITY; 2532 me->priority = PONG_PRIORITY;
2472 me->size = sizeof (struct PingMessage); 2533 me->size = sizeof (struct PongMessage);
2473 tp = (struct PingMessage *) &me[1]; 2534 tx.reserved = htonl (0);
2535 tx.inbound_bpm_limit = htonl (n->bpm_in);
2536 tx.challenge = t.challenge;
2537 tx.target = t.target;
2538 tp = (struct PongMessage *) &me[1];
2474 tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG); 2539 tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
2475 tp->header.size = htons (sizeof (struct PingMessage)); 2540 tp->header.size = htons (sizeof (struct PongMessage));
2476 do_encrypt (n, 2541 do_encrypt (n,
2477 &my_identity.hashPubKey, 2542 &my_identity.hashPubKey,
2478 &t.challenge, 2543 &tx.challenge,
2479 &tp->challenge, 2544 &tp->challenge,
2480 sizeof (struct PingMessage) - 2545 sizeof (struct PongMessage) -
2481 sizeof (struct GNUNET_MessageHeader)); 2546 sizeof (struct GNUNET_MessageHeader));
2482#if DEBUG_CORE 2547#if DEBUG_CORE
2483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2548 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2496,9 +2561,10 @@ handle_ping (struct Neighbour *n, const struct PingMessage *m)
2496 * @param m the encrypted PONG message itself 2561 * @param m the encrypted PONG message itself
2497 */ 2562 */
2498static void 2563static void
2499handle_pong (struct Neighbour *n, const struct PingMessage *m) 2564handle_pong (struct Neighbour *n,
2565 const struct PongMessage *m)
2500{ 2566{
2501 struct PingMessage t; 2567 struct PongMessage t;
2502 struct ConnectNotifyMessage cnm; 2568 struct ConnectNotifyMessage cnm;
2503 2569
2504#if DEBUG_CORE 2570#if DEBUG_CORE
@@ -2511,9 +2577,14 @@ handle_pong (struct Neighbour *n, const struct PingMessage *m)
2511 &n->peer.hashPubKey, 2577 &n->peer.hashPubKey,
2512 &m->challenge, 2578 &m->challenge,
2513 &t.challenge, 2579 &t.challenge,
2514 sizeof (struct PingMessage) - 2580 sizeof (struct PongMessage) -
2515 sizeof (struct GNUNET_MessageHeader))) 2581 sizeof (struct GNUNET_MessageHeader)))
2516 return; 2582 return;
2583 if (0 != ntohl (t.reserved))
2584 {
2585 GNUNET_break_op (0);
2586 return;
2587 }
2517#if DEBUG_CORE 2588#if DEBUG_CORE
2518 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2589 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2519 "Decrypted `%s' from `%4s' with challenge %u using key %u\n", 2590 "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
@@ -2548,6 +2619,9 @@ handle_pong (struct Neighbour *n, const struct PingMessage *m)
2548 return; 2619 return;
2549 case PEER_STATE_KEY_RECEIVED: 2620 case PEER_STATE_KEY_RECEIVED:
2550 n->status = PEER_STATE_KEY_CONFIRMED; 2621 n->status = PEER_STATE_KEY_CONFIRMED;
2622 n->bpm_out_external_limit = ntohl (t.inbound_bpm_limit);
2623 n->bpm_out = GNUNET_MIN (n->bpm_out_external_limit,
2624 n->bpm_out_internal_limit);
2551#if DEBUG_CORE 2625#if DEBUG_CORE
2552 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2626 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2553 "Confirmed key via `%s' message for peer `%4s'\n", 2627 "Confirmed key via `%s' message for peer `%4s'\n",
@@ -2590,7 +2664,7 @@ handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2590 struct GNUNET_TIME_Absolute t; 2664 struct GNUNET_TIME_Absolute t;
2591 struct GNUNET_CRYPTO_AesSessionKey k; 2665 struct GNUNET_CRYPTO_AesSessionKey k;
2592 struct PingMessage *ping; 2666 struct PingMessage *ping;
2593 struct PingMessage *pong; 2667 struct PongMessage *pong;
2594 enum PeerStateMachine sender_status; 2668 enum PeerStateMachine sender_status;
2595 2669
2596#if DEBUG_CORE 2670#if DEBUG_CORE
@@ -3004,12 +3078,21 @@ handle_encrypted_message (struct Neighbour *n,
3004 } 3078 }
3005 3079
3006 /* process decrypted message(s) */ 3080 /* process decrypted message(s) */
3007 update_window (GNUNET_YES, 3081 if (n->bpm_out_external_limit != ntohl (pt->inbound_bpm_limit))
3008 &n->available_send_window, 3082 {
3009 &n->last_asw_update, 3083 update_window (GNUNET_YES,
3010 n->bpm_out); 3084 &n->available_send_window,
3085 &n->last_asw_update,
3086 n->bpm_out);
3087#if DEBUG_CORE_QUOTA
3088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3089 "Received %llu as new inbound limit for peer `%4s'\n",
3090 (unsigned long long) ntohl (pt->inbound_bpm_limit),
3091 GNUNET_i2s (&n->peer));
3092#endif
3093 }
3011 n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit); 3094 n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
3012 n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit, 3095 n->bpm_out = GNUNET_MIN (n->bpm_out_external_limit,
3013 n->bpm_out_internal_limit); 3096 n->bpm_out_internal_limit);
3014 n->last_activity = GNUNET_TIME_absolute_get (); 3097 n->last_activity = GNUNET_TIME_absolute_get ();
3015 off = sizeof (struct EncryptedMessage); 3098 off = sizeof (struct EncryptedMessage);
@@ -3108,7 +3191,7 @@ handle_transport_receive (void *cls,
3108 handle_ping (n, (const struct PingMessage *) message); 3191 handle_ping (n, (const struct PingMessage *) message);
3109 break; 3192 break;
3110 case GNUNET_MESSAGE_TYPE_CORE_PONG: 3193 case GNUNET_MESSAGE_TYPE_CORE_PONG:
3111 if (size != sizeof (struct PingMessage)) 3194 if (size != sizeof (struct PongMessage))
3112 { 3195 {
3113 GNUNET_break_op (0); 3196 GNUNET_break_op (0);
3114 return; 3197 return;
@@ -3122,11 +3205,11 @@ handle_transport_receive (void *cls,
3122 "PONG", GNUNET_i2s (&n->peer)); 3205 "PONG", GNUNET_i2s (&n->peer));
3123#endif 3206#endif
3124 GNUNET_free_non_null (n->pending_pong); 3207 GNUNET_free_non_null (n->pending_pong);
3125 n->pending_pong = GNUNET_malloc (sizeof (struct PingMessage)); 3208 n->pending_pong = GNUNET_malloc (sizeof (struct PongMessage));
3126 memcpy (n->pending_pong, message, sizeof (struct PingMessage)); 3209 memcpy (n->pending_pong, message, sizeof (struct PongMessage));
3127 return; 3210 return;
3128 } 3211 }
3129 handle_pong (n, (const struct PingMessage *) message); 3212 handle_pong (n, (const struct PongMessage *) message);
3130 break; 3213 break;
3131 default: 3214 default:
3132 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3215 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -3165,7 +3248,15 @@ neighbour_quota_update (void *cls,
3165 divides by a bit more to avoid division by zero AND to 3248 divides by a bit more to avoid division by zero AND to
3166 account for possibility of new neighbours joining any time 3249 account for possibility of new neighbours joining any time
3167 AND to convert to double... */ 3250 AND to convert to double... */
3168 pref_rel = n->current_preference / (1.0 + preference_sum); 3251 if (preference_sum == 0)
3252 {
3253 pref_rel = 1.0 / (double) neighbour_count;
3254 }
3255 else
3256 {
3257 pref_rel = n->current_preference / preference_sum;
3258 }
3259
3169 distributable = 0; 3260 distributable = 0;
3170 if (bandwidth_target_out > neighbour_count * MIN_BPM_PER_PEER) 3261 if (bandwidth_target_out > neighbour_count * MIN_BPM_PER_PEER)
3171 distributable = bandwidth_target_out - neighbour_count * MIN_BPM_PER_PEER; 3262 distributable = bandwidth_target_out - neighbour_count * MIN_BPM_PER_PEER;
@@ -3182,6 +3273,15 @@ neighbour_quota_update (void *cls,
3182#endif 3273#endif
3183 q_in = 0; /* force disconnect */ 3274 q_in = 0; /* force disconnect */
3184 } 3275 }
3276#if DEBUG_CORE_QUOTA
3277 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3278 "Current quota for `%4s' is %llu in (old: %llu) / %llu out (%llu internal)\n",
3279 GNUNET_i2s (&n->peer),
3280 (unsigned long long) q_in,
3281 (unsigned long long) n->bpm_in,
3282 (unsigned long long) n->bpm_out,
3283 (unsigned long long) n->bpm_out_internal_limit);
3284#endif
3185 if ( (n->bpm_in + MIN_BPM_CHANGE < q_in) || 3285 if ( (n->bpm_in + MIN_BPM_CHANGE < q_in) ||
3186 (n->bpm_in - MIN_BPM_CHANGE > q_in) ) 3286 (n->bpm_in - MIN_BPM_CHANGE > q_in) )
3187 { 3287 {