aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_neighbours.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-12 15:00:47 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-12 15:00:47 +0000
commit63d15aa9d1ea50933ff34fc42916024a5d3196bf (patch)
tree5f5dad8cabd420639867d630a0b92c000001fc06 /src/transport/gnunet-service-transport_neighbours.c
parente5a68574ecfc990eedae657c74e54dda3d96f599 (diff)
downloadgnunet-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.c269
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 */
375static void
376neighbour_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 */
473static void 484static void
474try_connect_using_address (void *cls, 485try_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 */
514static void
515neighbour_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 */
636struct GNUNET_TIME_Relative
637GST_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 */
754static void
755neighbour_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 */
779int
780GST_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 */
874int
875GST_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 */