diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-08-12 15:00:47 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-08-12 15:00:47 +0000 |
commit | 63d15aa9d1ea50933ff34fc42916024a5d3196bf (patch) | |
tree | 5f5dad8cabd420639867d630a0b92c000001fc06 /src/transport/gnunet-service-transport_neighbours.c | |
parent | e5a68574ecfc990eedae657c74e54dda3d96f599 (diff) | |
download | gnunet-63d15aa9d1ea50933ff34fc42916024a5d3196bf.tar.gz gnunet-63d15aa9d1ea50933ff34fc42916024a5d3196bf.zip |
no need for public key
Diffstat (limited to 'src/transport/gnunet-service-transport_neighbours.c')
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 269 |
1 files changed, 101 insertions, 168 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index c833f6085..f30878966 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -38,6 +38,11 @@ | |||
38 | */ | 38 | */ |
39 | #define NEIGHBOUR_TABLE_SIZE 256 | 39 | #define NEIGHBOUR_TABLE_SIZE 256 |
40 | 40 | ||
41 | /** | ||
42 | * How often must a peer violate bandwidth quotas before we start | ||
43 | * to simply drop its messages? | ||
44 | */ | ||
45 | #define QUOTA_VIOLATION_DROP_THRESHOLD 10 | ||
41 | 46 | ||
42 | 47 | ||
43 | // TODO: | 48 | // TODO: |
@@ -145,11 +150,6 @@ struct NeighbourMapEntry | |||
145 | size_t addrlen; | 150 | size_t addrlen; |
146 | 151 | ||
147 | /** | 152 | /** |
148 | * Public key for this peer. Valid only if the respective flag is set below. | ||
149 | */ | ||
150 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; | ||
151 | |||
152 | /** | ||
153 | * Identity of this neighbour. | 153 | * Identity of this neighbour. |
154 | */ | 154 | */ |
155 | struct GNUNET_PeerIdentity id; | 155 | struct GNUNET_PeerIdentity id; |
@@ -198,11 +198,6 @@ struct NeighbourMapEntry | |||
198 | // int received_pong; | 198 | // int received_pong; |
199 | 199 | ||
200 | /** | 200 | /** |
201 | * Do we have a valid public key for this neighbour? | ||
202 | */ | ||
203 | int public_key_valid; | ||
204 | |||
205 | /** | ||
206 | * Are we already in the process of disconnecting this neighbour? | 201 | * Are we already in the process of disconnecting this neighbour? |
207 | */ | 202 | */ |
208 | // int in_disconnect; | 203 | // int in_disconnect; |
@@ -372,6 +367,23 @@ disconnect_neighbour (struct NeighbourMapEntry *n) | |||
372 | 367 | ||
373 | 368 | ||
374 | /** | 369 | /** |
370 | * Peer has been idle for too long. Disconnect. | ||
371 | * | ||
372 | * @param cls the 'struct NeighbourMapEntry' of the neighbour that went idle | ||
373 | * @param tc scheduler context | ||
374 | */ | ||
375 | static void | ||
376 | neighbour_timeout_task (void *cls, | ||
377 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
378 | { | ||
379 | struct NeighbourMapEntry *n = cls; | ||
380 | |||
381 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
382 | disconnect_neighbour (n); | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
375 | * Disconnect from the given neighbour. | 387 | * Disconnect from the given neighbour. |
376 | * | 388 | * |
377 | * @param cls unused | 389 | * @param cls unused |
@@ -461,7 +473,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
461 | * Try to connect to the target peer using the given address | 473 | * Try to connect to the target peer using the given address |
462 | * | 474 | * |
463 | * @param cls the 'struct NeighbourMapEntry' of the target | 475 | * @param cls the 'struct NeighbourMapEntry' of the target |
464 | * @param public_key public key for the peer, never NULL | ||
465 | * @param target identity of the target peer | 476 | * @param target identity of the target peer |
466 | * @param plugin_name name of the plugin | 477 | * @param plugin_name name of the plugin |
467 | * @param plugin_address binary address | 478 | * @param plugin_address binary address |
@@ -472,7 +483,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
472 | */ | 483 | */ |
473 | static void | 484 | static void |
474 | try_connect_using_address (void *cls, | 485 | try_connect_using_address (void *cls, |
475 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, | ||
476 | const struct GNUNET_PeerIdentity *target, | 486 | const struct GNUNET_PeerIdentity *target, |
477 | const char *plugin_name, | 487 | const char *plugin_name, |
478 | const void *plugin_address, | 488 | const void *plugin_address, |
@@ -484,11 +494,6 @@ try_connect_using_address (void *cls, | |||
484 | struct NeighbourMapEntry *n = cls; | 494 | struct NeighbourMapEntry *n = cls; |
485 | 495 | ||
486 | n->asc = NULL; | 496 | n->asc = NULL; |
487 | if (n->public_key_valid == GNUNET_NO) | ||
488 | { | ||
489 | n->public_key = *public_key; | ||
490 | n->public_key_valid = GNUNET_YES; | ||
491 | } | ||
492 | GST_neighbours_switch_to_address (target, | 497 | GST_neighbours_switch_to_address (target, |
493 | plugin_name, | 498 | plugin_name, |
494 | plugin_address, | 499 | plugin_address, |
@@ -506,29 +511,6 @@ try_connect_using_address (void *cls, | |||
506 | 511 | ||
507 | 512 | ||
508 | /** | 513 | /** |
509 | * We've tried to connect but waited long enough and failed. Clean up. | ||
510 | * | ||
511 | * @param cls the 'struct NeighbourMapEntry' of the neighbour that failed to connect | ||
512 | * @param tc scheduler context | ||
513 | */ | ||
514 | static void | ||
515 | neighbour_connect_timeout_task (void *cls, | ||
516 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
517 | { | ||
518 | struct NeighbourMapEntry *n = cls; | ||
519 | |||
520 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
521 | GNUNET_assert (GNUNET_YES == | ||
522 | GNUNET_CONTAINER_multihashmap_remove (neighbours, | ||
523 | &n->id.hashPubKey, | ||
524 | n)); | ||
525 | GNUNET_assert (NULL == n->messages_head); | ||
526 | GNUNET_assert (NULL == n->ats); | ||
527 | GNUNET_free (n); | ||
528 | } | ||
529 | |||
530 | |||
531 | /** | ||
532 | * Try to create a connection to the given target (eventually). | 514 | * Try to create a connection to the given target (eventually). |
533 | * | 515 | * |
534 | * @param target peer to try to connect to | 516 | * @param target peer to try to connect to |
@@ -542,7 +524,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) | |||
542 | &GST_my_identity, | 524 | &GST_my_identity, |
543 | sizeof (struct GNUNET_PeerIdentity))); | 525 | sizeof (struct GNUNET_PeerIdentity))); |
544 | n = lookup_neighbour (target); | 526 | n = lookup_neighbour (target); |
545 | if ( (NULL != n) || | 527 | if ( (NULL != n) && |
546 | (GNUNET_YES == n->is_connected) ) | 528 | (GNUNET_YES == n->is_connected) ) |
547 | return; /* already connected */ | 529 | return; /* already connected */ |
548 | if (n == NULL) | 530 | if (n == NULL) |
@@ -553,7 +535,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) | |||
553 | GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, | 535 | GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, |
554 | MAX_BANDWIDTH_CARRY_S); | 536 | MAX_BANDWIDTH_CARRY_S); |
555 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 537 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, |
556 | &neighbour_connect_timeout_task, n); | 538 | &neighbour_timeout_task, n); |
557 | GNUNET_assert (GNUNET_OK == | 539 | GNUNET_assert (GNUNET_OK == |
558 | GNUNET_CONTAINER_multihashmap_put (neighbours, | 540 | GNUNET_CONTAINER_multihashmap_put (neighbours, |
559 | &n->id.hashPubKey, | 541 | &n->id.hashPubKey, |
@@ -643,6 +625,83 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, | |||
643 | 625 | ||
644 | 626 | ||
645 | /** | 627 | /** |
628 | * We have received a message from the given sender. How long should | ||
629 | * we delay before receiving more? (Also used to keep the peer marked | ||
630 | * as live). | ||
631 | * | ||
632 | * @param sender sender of the message | ||
633 | * @param size size of the message | ||
634 | * @return how long to wait before reading more from this sender | ||
635 | */ | ||
636 | struct GNUNET_TIME_Relative | ||
637 | GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity *sender, | ||
638 | ssize_t size) | ||
639 | { | ||
640 | struct NeighbourMapEntry *n; | ||
641 | struct GNUNET_TIME_Relative ret; | ||
642 | |||
643 | n = lookup_neighbour (sender); | ||
644 | if (n == NULL) | ||
645 | return GNUNET_TIME_UNIT_ZERO; | ||
646 | if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
647 | size)) | ||
648 | { | ||
649 | n->quota_violation_count++; | ||
650 | #if DEBUG_TRANSPORT | ||
651 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
652 | "Bandwidth quota (%u b/s) violation detected (total of %u).\n", | ||
653 | n->in_tracker.available_bytes_per_s__, | ||
654 | n->quota_violation_count); | ||
655 | #endif | ||
656 | /* Discount 32k per violation */ | ||
657 | GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
658 | - 32 * 1024); | ||
659 | } | ||
660 | else | ||
661 | { | ||
662 | if (n->quota_violation_count > 0) | ||
663 | { | ||
664 | /* try to add 32k back */ | ||
665 | GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, | ||
666 | 32 * 1024); | ||
667 | n->quota_violation_count--; | ||
668 | } | ||
669 | } | ||
670 | n->peer_timeout = | ||
671 | GNUNET_TIME_relative_to_absolute | ||
672 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | ||
673 | GNUNET_SCHEDULER_cancel (n->timeout_task); | ||
674 | n->timeout_task = | ||
675 | GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
676 | &neighbour_timeout_task, n); | ||
677 | if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD) | ||
678 | { | ||
679 | GNUNET_STATISTICS_update (GST_stats, | ||
680 | gettext_noop ("# bandwidth quota violations by other peers"), | ||
681 | 1, | ||
682 | GNUNET_NO); | ||
683 | return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT; | ||
684 | } | ||
685 | ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0); | ||
686 | if (ret.rel_value > 0) | ||
687 | { | ||
688 | #if DEBUG_TRANSPORT | ||
689 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
690 | "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n", | ||
691 | (unsigned long long) n->in_tracker.consumption_since_last_update__, | ||
692 | (unsigned int) n->in_tracker.available_bytes_per_s__, | ||
693 | (unsigned long long) ret.rel_value); | ||
694 | #endif | ||
695 | GNUNET_STATISTICS_update (GST_stats, | ||
696 | gettext_noop ("# ms throttling suggested"), | ||
697 | (int64_t) ret.rel_value, | ||
698 | GNUNET_NO); | ||
699 | } | ||
700 | return ret; | ||
701 | } | ||
702 | |||
703 | |||
704 | /** | ||
646 | * Change the incoming quota for the given peer. | 705 | * Change the incoming quota for the given peer. |
647 | * | 706 | * |
648 | * @param neighbour identity of peer to change qutoa for | 707 | * @param neighbour identity of peer to change qutoa for |
@@ -746,105 +805,6 @@ GST_neighbours_iterate (GST_NeighbourIterator cb, | |||
746 | 805 | ||
747 | 806 | ||
748 | /** | 807 | /** |
749 | * Peer has been idle for too long. Disconnect. | ||
750 | * | ||
751 | * @param cls the 'struct NeighbourMapEntry' of the neighbour that went idle | ||
752 | * @param tc scheduler context | ||
753 | */ | ||
754 | static void | ||
755 | neighbour_idle_timeout_task (void *cls, | ||
756 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
757 | { | ||
758 | struct NeighbourMapEntry *n = cls; | ||
759 | |||
760 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
761 | disconnect_neighbour (n); | ||
762 | } | ||
763 | |||
764 | |||
765 | /** | ||
766 | * We have received a CONNECT. Set the peer to connected. | ||
767 | * | ||
768 | * @param sender peer sending the PONG | ||
769 | * @param hdr the PONG message (presumably) | ||
770 | * @param plugin_name name of transport that delivered the PONG | ||
771 | * @param sender_address address of the other peer, NULL if other peer | ||
772 | * connected to us | ||
773 | * @param sender_address_len number of bytes in sender_address | ||
774 | * @param bandwidth bandwidth for the connection | ||
775 | * @param ats performance data | ||
776 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
777 | * @return GNUNET_OK if the message was well-formed, GNUNET_SYSERR if not | ||
778 | */ | ||
779 | int | ||
780 | GST_neighbours_handle_connect (const struct GNUNET_PeerIdentity *sender, | ||
781 | const struct GNUNET_MessageHeader *hdr, | ||
782 | const char *plugin_name, | ||
783 | const void *sender_address, | ||
784 | size_t sender_address_len, | ||
785 | struct Session *session, | ||
786 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
787 | uint32_t ats_count) | ||
788 | { | ||
789 | struct NeighbourMapEntry *n; | ||
790 | |||
791 | if (0 == memcmp (sender, | ||
792 | &GST_my_identity, | ||
793 | sizeof (struct GNUNET_PeerIdentity))) | ||
794 | { | ||
795 | GNUNET_break (0); | ||
796 | return GNUNET_SYSERR; | ||
797 | } | ||
798 | n = lookup_neighbour (sender); | ||
799 | if ( (NULL != n) && | ||
800 | (n->is_connected == GNUNET_YES) ) | ||
801 | return GNUNET_OK; /* ats will consider switching and tell us */ | ||
802 | if (n == NULL) | ||
803 | { | ||
804 | n = GNUNET_malloc (sizeof (struct NeighbourMapEntry)); | ||
805 | n->id = *sender; | ||
806 | GNUNET_BANDWIDTH_tracker_init (&n->in_tracker, | ||
807 | GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, | ||
808 | MAX_BANDWIDTH_CARRY_S); | ||
809 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
810 | &neighbour_connect_timeout_task, n); | ||
811 | GNUNET_assert (GNUNET_OK == | ||
812 | GNUNET_CONTAINER_multihashmap_put (neighbours, | ||
813 | &n->id.hashPubKey, | ||
814 | n, | ||
815 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
816 | } | ||
817 | GST_neighbours_switch_to_address (sender, | ||
818 | plugin_name, | ||
819 | sender_address, | ||
820 | sender_address_len, | ||
821 | session, | ||
822 | ats, ats_count); | ||
823 | if (NULL != session) | ||
824 | { | ||
825 | /* inbound bi-directional connection, just use it */ | ||
826 | n->is_connected = GNUNET_YES; | ||
827 | connect_notify_cb (callback_cls, | ||
828 | sender, | ||
829 | n->ats, | ||
830 | n->ats_count); | ||
831 | n->peer_timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | ||
832 | if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) | ||
833 | GNUNET_SCHEDULER_cancel (n->timeout_task); | ||
834 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
835 | &neighbour_idle_timeout_task, | ||
836 | n); | ||
837 | } | ||
838 | else | ||
839 | { | ||
840 | /* try to establish our connection back to the initiator */ | ||
841 | GST_neighbours_try_connect (sender); | ||
842 | } | ||
843 | return GNUNET_OK; | ||
844 | } | ||
845 | |||
846 | |||
847 | /** | ||
848 | * If we have an active connection to the given target, it must be shutdown. | 808 | * If we have an active connection to the given target, it must be shutdown. |
849 | * | 809 | * |
850 | * @param target peer to disconnect from | 810 | * @param target peer to disconnect from |
@@ -860,31 +820,4 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) | |||
860 | } | 820 | } |
861 | 821 | ||
862 | 822 | ||
863 | /** | ||
864 | * We have received a DISCONNECT. Set the peer to disconnected. | ||
865 | * | ||
866 | * @param sender peer sending the PONG | ||
867 | * @param hdr the PONG message (presumably) | ||
868 | * @param plugin_name name of transport that delivered the PONG | ||
869 | * @param sender_address address of the other peer, NULL if other peer | ||
870 | * connected to us | ||
871 | * @param sender_address_len number of bytes in sender_address | ||
872 | * @return GNUNET_OK if the message was well-formed, GNUNET_SYSERR if not | ||
873 | */ | ||
874 | int | ||
875 | GST_neighbours_handle_disconnect (const struct GNUNET_PeerIdentity *sender, | ||
876 | const struct GNUNET_MessageHeader *hdr, | ||
877 | const char *plugin_name, | ||
878 | const void *sender_address, | ||
879 | size_t sender_address_len) | ||
880 | { | ||
881 | struct NeighbourMapEntry *n; | ||
882 | |||
883 | n = lookup_neighbour (sender); | ||
884 | /* FIXME: should disconnects have a signature that we should check here? */ | ||
885 | disconnect_neighbour (n); | ||
886 | return GNUNET_OK; | ||
887 | } | ||
888 | |||
889 | |||
890 | /* end of file gnunet-service-transport_neighbours.c */ | 823 | /* end of file gnunet-service-transport_neighbours.c */ |