aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-04-14 19:08:44 +0000
committerChristian Grothoff <christian@grothoff.org>2010-04-14 19:08:44 +0000
commit1af740f9589aee283ef9473e8528b5a9ce76e60d (patch)
tree12e07b6a01300a5759da03f25d17e80cda1517de /src/transport
parentd525f2466043fa68adc5a96a2e95cc31ae1a6afb (diff)
downloadgnunet-1af740f9589aee283ef9473e8528b5a9ce76e60d.tar.gz
gnunet-1af740f9589aee283ef9473e8528b5a9ce76e60d.zip
work in progress
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport.c144
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 */
2493static void
2494handle_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);