diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-04-14 19:08:44 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-04-14 19:08:44 +0000 |
commit | 1af740f9589aee283ef9473e8528b5a9ce76e60d (patch) | |
tree | 12e07b6a01300a5759da03f25d17e80cda1517de /src/transport | |
parent | d525f2466043fa68adc5a96a2e95cc31ae1a6afb (diff) | |
download | gnunet-1af740f9589aee283ef9473e8528b5a9ce76e60d.tar.gz gnunet-1af740f9589aee283ef9473e8528b5a9ce76e60d.zip |
work in progress
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 144 |
1 files changed, 94 insertions, 50 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 267f3c4e1..2ac33c3e1 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -24,7 +24,6 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | 25 | * |
26 | * TODO: | 26 | * TODO: |
27 | * - Need to defer forwarding messages until after CONNECT message | ||
28 | * - CHECK that 'address' being NULL in 'struct ForeignAddressList' is | 27 | * - CHECK that 'address' being NULL in 'struct ForeignAddressList' is |
29 | * tolerated in the code everywhere (could not happen before) | 28 | * tolerated in the code everywhere (could not happen before) |
30 | * | 29 | * |
@@ -453,6 +452,14 @@ struct NeighbourList | |||
453 | struct MessageQueue *messages_tail; | 452 | struct MessageQueue *messages_tail; |
454 | 453 | ||
455 | /** | 454 | /** |
455 | * Buffer for at most one payload message used when we receive | ||
456 | * payload data before our PING-PONG has succeeded. We then | ||
457 | * store such messages in this intermediary buffer until the | ||
458 | * connection is fully up. | ||
459 | */ | ||
460 | struct GNUNET_MessageHeader *pre_connect_message_buffer; | ||
461 | |||
462 | /** | ||
456 | * Context for peerinfo iteration. | 463 | * Context for peerinfo iteration. |
457 | * NULL after we are done processing peerinfo's information. | 464 | * NULL after we are done processing peerinfo's information. |
458 | */ | 465 | */ |
@@ -2474,6 +2481,82 @@ schedule_next_ping (struct ForeignAddressList *fal) | |||
2474 | } | 2481 | } |
2475 | 2482 | ||
2476 | 2483 | ||
2484 | |||
2485 | |||
2486 | /** | ||
2487 | * Function that will be called if we receive some payload | ||
2488 | * from another peer. | ||
2489 | * | ||
2490 | * @param message the payload | ||
2491 | * @param n peer who claimed to be the sender | ||
2492 | */ | ||
2493 | static void | ||
2494 | handle_payload_message (const struct GNUNET_MessageHeader *message, | ||
2495 | struct NeighbourList *n) | ||
2496 | { | ||
2497 | struct InboundMessage *im; | ||
2498 | struct TransportClient *cpos; | ||
2499 | uint16_t msize; | ||
2500 | |||
2501 | msize = ntohs (message->size); | ||
2502 | if (n->received_pong == GNUNET_NO) | ||
2503 | { | ||
2504 | GNUNET_free_non_null (n->pre_connect_message_buffer); | ||
2505 | n->pre_connect_message_buffer = GNUNET_malloc (msize); | ||
2506 | memcpy (n->pre_connect_message_buffer, message, msize); | ||
2507 | return; | ||
2508 | } | ||
2509 | #if DEBUG_TRANSPORT | ||
2510 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2511 | "Received message of type %u from `%4s', sending to all clients.\n", | ||
2512 | ntohs (message->type), | ||
2513 | GNUNET_i2s (&n->id)); | ||
2514 | #endif | ||
2515 | if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
2516 | (ssize_t) msize)) | ||
2517 | { | ||
2518 | n->quota_violation_count++; | ||
2519 | #if DEBUG_TRANSPORT | ||
2520 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2521 | "Bandwidth quota (%u b/s) violation detected (total of %u).\n", | ||
2522 | n->in_tracker.available_bytes_per_s__, | ||
2523 | n->quota_violation_count); | ||
2524 | #endif | ||
2525 | /* Discount 32k per violation */ | ||
2526 | GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
2527 | - 32 * 1024); | ||
2528 | } | ||
2529 | else | ||
2530 | { | ||
2531 | if (n->quota_violation_count > 0) | ||
2532 | { | ||
2533 | /* try to add 32k back */ | ||
2534 | GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
2535 | 32 * 1024); | ||
2536 | n->quota_violation_count--; | ||
2537 | } | ||
2538 | } | ||
2539 | GNUNET_STATISTICS_update (stats, | ||
2540 | gettext_noop ("# payload received from other peers"), | ||
2541 | msize, | ||
2542 | GNUNET_NO); | ||
2543 | /* transmit message to all clients */ | ||
2544 | im = GNUNET_malloc (sizeof (struct InboundMessage) + msize); | ||
2545 | im->header.size = htons (sizeof (struct InboundMessage) + msize); | ||
2546 | im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV); | ||
2547 | im->latency = GNUNET_TIME_relative_hton (n->latency); | ||
2548 | im->peer = n->id; | ||
2549 | memcpy (&im[1], message, msize); | ||
2550 | cpos = clients; | ||
2551 | while (cpos != NULL) | ||
2552 | { | ||
2553 | transmit_to_client (cpos, &im->header, GNUNET_YES); | ||
2554 | cpos = cpos->next; | ||
2555 | } | ||
2556 | GNUNET_free (im); | ||
2557 | } | ||
2558 | |||
2559 | |||
2477 | /** | 2560 | /** |
2478 | * Iterator over hash map entries. Checks if the given validation | 2561 | * Iterator over hash map entries. Checks if the given validation |
2479 | * entry is for the same challenge as what is given in the PONG. | 2562 | * entry is for the same challenge as what is given in the PONG. |
@@ -2497,6 +2580,7 @@ check_pending_validation (void *cls, | |||
2497 | struct GNUNET_PeerIdentity target; | 2580 | struct GNUNET_PeerIdentity target; |
2498 | struct NeighbourList *n; | 2581 | struct NeighbourList *n; |
2499 | struct ForeignAddressList *fal; | 2582 | struct ForeignAddressList *fal; |
2583 | struct GNUNET_MessageHeader *prem; | ||
2500 | 2584 | ||
2501 | if (ve->challenge != challenge) | 2585 | if (ve->challenge != challenge) |
2502 | return GNUNET_YES; | 2586 | return GNUNET_YES; |
@@ -2565,6 +2649,12 @@ check_pending_validation (void *cls, | |||
2565 | { | 2649 | { |
2566 | n->received_pong = GNUNET_YES; | 2650 | n->received_pong = GNUNET_YES; |
2567 | notify_clients_connect (&target, n->latency, n->distance); | 2651 | notify_clients_connect (&target, n->latency, n->distance); |
2652 | if (NULL != (prem = n->pre_connect_message_buffer)) | ||
2653 | { | ||
2654 | n->pre_connect_message_buffer = NULL; | ||
2655 | handle_payload_message (prem, n); | ||
2656 | GNUNET_free (prem); | ||
2657 | } | ||
2568 | } | 2658 | } |
2569 | if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) | 2659 | if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) |
2570 | { | 2660 | { |
@@ -3106,6 +3196,7 @@ disconnect_neighbour (struct NeighbourList *n, int check) | |||
3106 | gettext_noop ("# active neighbours"), | 3196 | gettext_noop ("# active neighbours"), |
3107 | -1, | 3197 | -1, |
3108 | GNUNET_NO); | 3198 | GNUNET_NO); |
3199 | GNUNET_free_non_null (n->pre_connect_message_buffer); | ||
3109 | GNUNET_free (n); | 3200 | GNUNET_free (n); |
3110 | } | 3201 | } |
3111 | 3202 | ||
@@ -3257,8 +3348,6 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3257 | { | 3348 | { |
3258 | struct TransportPlugin *plugin = cls; | 3349 | struct TransportPlugin *plugin = cls; |
3259 | struct ReadyList *service_context; | 3350 | struct ReadyList *service_context; |
3260 | struct TransportClient *cpos; | ||
3261 | struct InboundMessage *im; | ||
3262 | struct ForeignAddressList *peer_address; | 3351 | struct ForeignAddressList *peer_address; |
3263 | uint16_t msize; | 3352 | uint16_t msize; |
3264 | struct NeighbourList *n; | 3353 | struct NeighbourList *n; |
@@ -3339,53 +3428,8 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3339 | handle_pong (plugin, message, peer, sender_address, sender_address_len); | 3428 | handle_pong (plugin, message, peer, sender_address, sender_address_len); |
3340 | break; | 3429 | break; |
3341 | default: | 3430 | default: |
3342 | #if DEBUG_TRANSPORT | 3431 | handle_payload_message (message, n); |
3343 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3432 | break; |
3344 | "Received message of type %u from `%4s', sending to all clients.\n", | ||
3345 | ntohs (message->type), GNUNET_i2s (peer)); | ||
3346 | #endif | ||
3347 | if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
3348 | (ssize_t) msize)) | ||
3349 | { | ||
3350 | n->quota_violation_count++; | ||
3351 | #if DEBUG_TRANSPORT | ||
3352 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3353 | "Bandwidth quota (%u b/s) violation detected (total of %u).\n", | ||
3354 | n->in_tracker.available_bytes_per_s__, | ||
3355 | n->quota_violation_count); | ||
3356 | #endif | ||
3357 | /* Discount 32k per violation */ | ||
3358 | GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
3359 | - 32 * 1024); | ||
3360 | } | ||
3361 | else | ||
3362 | { | ||
3363 | if (n->quota_violation_count > 0) | ||
3364 | { | ||
3365 | /* try to add 32k back */ | ||
3366 | GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
3367 | 32 * 1024); | ||
3368 | n->quota_violation_count--; | ||
3369 | } | ||
3370 | } | ||
3371 | GNUNET_STATISTICS_update (stats, | ||
3372 | gettext_noop ("# payload received from other peers"), | ||
3373 | msize, | ||
3374 | GNUNET_NO); | ||
3375 | /* transmit message to all clients */ | ||
3376 | im = GNUNET_malloc (sizeof (struct InboundMessage) + msize); | ||
3377 | im->header.size = htons (sizeof (struct InboundMessage) + msize); | ||
3378 | im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV); | ||
3379 | im->latency = GNUNET_TIME_relative_hton (n->latency); | ||
3380 | im->peer = *peer; | ||
3381 | memcpy (&im[1], message, msize); | ||
3382 | cpos = clients; | ||
3383 | while (cpos != NULL) | ||
3384 | { | ||
3385 | transmit_to_client (cpos, &im->header, GNUNET_YES); | ||
3386 | cpos = cpos->next; | ||
3387 | } | ||
3388 | GNUNET_free (im); | ||
3389 | } | 3433 | } |
3390 | } | 3434 | } |
3391 | ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0); | 3435 | ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0); |