diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-02-26 12:50:50 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-02-26 12:50:50 +0000 |
commit | bc22ad5ddb9e582bf7d3479711f25b4bdfb9989b (patch) | |
tree | 7792689161d18dd4f253967c06c53dfad03a09e6 /src | |
parent | fa70ed546a994f84b49b541d1b0af0a14c4589b6 (diff) | |
download | gnunet-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.c | 162 |
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 | |||
226 | struct PingMessage | 227 | struct 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 | */ | ||
252 | struct 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 | |||
2429 | handle_ping (struct Neighbour *n, const struct PingMessage *m) | 2489 | handle_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 | */ |
2498 | static void | 2563 | static void |
2499 | handle_pong (struct Neighbour *n, const struct PingMessage *m) | 2564 | handle_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 | { |