diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2014-01-08 17:51:53 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2014-01-08 17:51:53 +0000 |
commit | 5f05330cb3d9ec30347c07522de00624de9d6c67 (patch) | |
tree | 213d4a9fdd07a2017c5768d609280fce4b6f146c /src/transport/gnunet-transport.c | |
parent | ce8e0739623ee25d2a29a75f393027a42bbe4d4f (diff) | |
download | gnunet-5f05330cb3d9ec30347c07522de00624de9d6c67.tar.gz gnunet-5f05330cb3d9ec30347c07522de00624de9d6c67.zip |
neighbour monitoring api implemented
Diffstat (limited to 'src/transport/gnunet-transport.c')
-rw-r--r-- | src/transport/gnunet-transport.c | 183 |
1 files changed, 165 insertions, 18 deletions
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index a6ffb2bab..c2d35cd66 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c | |||
@@ -149,6 +149,11 @@ static struct GNUNET_TIME_Absolute start_time; | |||
149 | static struct GNUNET_TRANSPORT_TransmitHandle *th; | 149 | static struct GNUNET_TRANSPORT_TransmitHandle *th; |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * Map storing information about monitored peers | ||
153 | */ | ||
154 | static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers; | ||
155 | |||
156 | /** | ||
152 | * | 157 | * |
153 | */ | 158 | */ |
154 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; | 159 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; |
@@ -194,6 +199,7 @@ static unsigned int address_resolutions; | |||
194 | */ | 199 | */ |
195 | static unsigned int address_resolution_in_progress; | 200 | static unsigned int address_resolution_in_progress; |
196 | 201 | ||
202 | |||
197 | /** | 203 | /** |
198 | * Context for a plugin test. | 204 | * Context for a plugin test. |
199 | */ | 205 | */ |
@@ -217,6 +223,25 @@ struct TestContext | |||
217 | 223 | ||
218 | }; | 224 | }; |
219 | 225 | ||
226 | struct MonitoredPeer | ||
227 | { | ||
228 | enum GNUNET_TRANSPORT_PeerState state; | ||
229 | struct GNUNET_TIME_Absolute state_timeout; | ||
230 | struct GNUNET_HELLO_Address *address; | ||
231 | }; | ||
232 | |||
233 | |||
234 | int destroy_it (void *cls, | ||
235 | const struct GNUNET_PeerIdentity *key, | ||
236 | void *value) | ||
237 | { | ||
238 | struct MonitoredPeer *m = value; | ||
239 | GNUNET_CONTAINER_multipeermap_remove (monitored_peers, key, value); | ||
240 | GNUNET_free_non_null (m->address); | ||
241 | GNUNET_free (value); | ||
242 | return GNUNET_OK; | ||
243 | } | ||
244 | |||
220 | /** | 245 | /** |
221 | * Task run in monitor mode when the user presses CTRL-C to abort. | 246 | * Task run in monitor mode when the user presses CTRL-C to abort. |
222 | * Stops monitoring activity. | 247 | * Stops monitoring activity. |
@@ -270,6 +295,13 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
270 | traffic_received, | 295 | traffic_received, |
271 | GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); | 296 | GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); |
272 | } | 297 | } |
298 | |||
299 | if (NULL != monitored_peers) | ||
300 | { | ||
301 | GNUNET_CONTAINER_multipeermap_iterate (monitored_peers, &destroy_it, NULL); | ||
302 | GNUNET_CONTAINER_multipeermap_destroy (monitored_peers); | ||
303 | monitored_peers = NULL; | ||
304 | } | ||
273 | } | 305 | } |
274 | 306 | ||
275 | static struct ResolutionContext *rc_head; | 307 | static struct ResolutionContext *rc_head; |
@@ -279,8 +311,12 @@ struct ResolutionContext | |||
279 | { | 311 | { |
280 | struct ResolutionContext *next; | 312 | struct ResolutionContext *next; |
281 | struct ResolutionContext *prev; | 313 | struct ResolutionContext *prev; |
314 | struct GNUNET_PeerIdentity id; | ||
282 | struct GNUNET_HELLO_Address *addrcp; | 315 | struct GNUNET_HELLO_Address *addrcp; |
283 | struct GNUNET_TRANSPORT_AddressToStringContext *asc; | 316 | struct GNUNET_TRANSPORT_AddressToStringContext *asc; |
317 | enum GNUNET_TRANSPORT_PeerState state; | ||
318 | struct GNUNET_TIME_Absolute state_timeout; | ||
319 | char *transport; | ||
284 | int printed; | 320 | int printed; |
285 | }; | 321 | }; |
286 | 322 | ||
@@ -310,6 +346,7 @@ operation_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
310 | 346 | ||
311 | GNUNET_CONTAINER_DLL_remove(rc_head, rc_tail, cur); | 347 | GNUNET_CONTAINER_DLL_remove(rc_head, rc_tail, cur); |
312 | GNUNET_TRANSPORT_address_to_string_cancel (cur->asc); | 348 | GNUNET_TRANSPORT_address_to_string_cancel (cur->asc); |
349 | GNUNET_free(cur->transport); | ||
313 | GNUNET_free(cur->addrcp); | 350 | GNUNET_free(cur->addrcp); |
314 | GNUNET_free(cur); | 351 | GNUNET_free(cur); |
315 | 352 | ||
@@ -641,18 +678,41 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
641 | } | 678 | } |
642 | 679 | ||
643 | static void | 680 | static void |
644 | resolve_address (const struct GNUNET_HELLO_Address *address, int numeric); | 681 | resolve_address (const struct GNUNET_PeerIdentity *id, |
682 | const struct GNUNET_HELLO_Address *address, int numeric, | ||
683 | enum GNUNET_TRANSPORT_PeerState state, | ||
684 | struct GNUNET_TIME_Absolute state_timeout); | ||
685 | |||
686 | static void | ||
687 | print_info (const struct GNUNET_PeerIdentity *id, const char *transport, | ||
688 | const char *addr, enum GNUNET_TRANSPORT_PeerState state, | ||
689 | struct GNUNET_TIME_Absolute state_timeout) | ||
690 | { | ||
691 | if ((GNUNET_YES == iterate_all) || (GNUNET_YES == monitor_connections) ) | ||
692 | { | ||
693 | FPRINTF (stdout, _("Peer `%s': %s %s in state `%s' until %s\n"), | ||
694 | GNUNET_i2s (id), | ||
695 | (NULL == transport) ? "<none>" : transport, | ||
696 | (NULL == transport) ? "<none>" : addr, | ||
697 | GNUNET_TRANSPORT_p2s (state), | ||
698 | GNUNET_STRINGS_absolute_time_to_string (state_timeout)); | ||
699 | } | ||
700 | else | ||
701 | { | ||
702 | /* Only connected peers, skip state */ | ||
703 | FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (id), transport, addr); | ||
704 | } | ||
705 | |||
706 | } | ||
645 | 707 | ||
646 | static void | 708 | static void |
647 | process_string (void *cls, const char *address) | 709 | process_string (void *cls, const char *address) |
648 | { | 710 | { |
649 | struct ResolutionContext *rc = cls; | 711 | struct ResolutionContext *rc = cls; |
650 | struct GNUNET_HELLO_Address *addrcp = rc->addrcp; | ||
651 | 712 | ||
652 | if (address != NULL ) | 713 | if (address != NULL ) |
653 | { | 714 | { |
654 | FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (&addrcp->peer), | 715 | print_info (&rc->id, rc->transport, address, rc->state, rc->state_timeout); |
655 | addrcp->transport_name, address); | ||
656 | rc->printed = GNUNET_YES; | 716 | rc->printed = GNUNET_YES; |
657 | } | 717 | } |
658 | else | 718 | else |
@@ -664,13 +724,18 @@ process_string (void *cls, const char *address) | |||
664 | { | 724 | { |
665 | if (numeric == GNUNET_NO) | 725 | if (numeric == GNUNET_NO) |
666 | { | 726 | { |
667 | resolve_address (rc->addrcp, GNUNET_YES); /* Failed to resolve address, try numeric lookup */ | 727 | /* Failed to resolve address, try numeric lookup */ |
728 | resolve_address (&rc->id, rc->addrcp, GNUNET_YES, | ||
729 | rc->state, rc->state_timeout); | ||
668 | } | 730 | } |
669 | else | 731 | else |
670 | FPRINTF (stdout, _("Peer `%s': %s <unable to resolve address>\n"), | 732 | { |
671 | GNUNET_i2s (&addrcp->peer), addrcp->transport_name); | 733 | print_info (&rc->id, rc->transport, "<unable to resolve address>", |
734 | rc->state, rc->state_timeout); | ||
735 | } | ||
672 | } | 736 | } |
673 | GNUNET_free(rc->addrcp); | 737 | GNUNET_free (rc->transport); |
738 | GNUNET_free (rc->addrcp); | ||
674 | GNUNET_CONTAINER_DLL_remove(rc_head, rc_tail, rc); | 739 | GNUNET_CONTAINER_DLL_remove(rc_head, rc_tail, rc); |
675 | GNUNET_free(rc); | 740 | GNUNET_free(rc); |
676 | if ((0 == address_resolutions) && (iterate_connections)) | 741 | if ((0 == address_resolutions) && (iterate_connections)) |
@@ -692,7 +757,10 @@ process_string (void *cls, const char *address) | |||
692 | } | 757 | } |
693 | 758 | ||
694 | static void | 759 | static void |
695 | resolve_address (const struct GNUNET_HELLO_Address *address, int numeric) | 760 | resolve_address (const struct GNUNET_PeerIdentity *id, |
761 | const struct GNUNET_HELLO_Address *address, int numeric, | ||
762 | enum GNUNET_TRANSPORT_PeerState state, | ||
763 | struct GNUNET_TIME_Absolute state_timeout) | ||
696 | { | 764 | { |
697 | struct ResolutionContext *rc; | 765 | struct ResolutionContext *rc; |
698 | 766 | ||
@@ -701,15 +769,19 @@ resolve_address (const struct GNUNET_HELLO_Address *address, int numeric) | |||
701 | GNUNET_CONTAINER_DLL_insert(rc_head, rc_tail, rc); | 769 | GNUNET_CONTAINER_DLL_insert(rc_head, rc_tail, rc); |
702 | address_resolutions++; | 770 | address_resolutions++; |
703 | 771 | ||
772 | rc->id = (*id); | ||
773 | rc->transport = GNUNET_strdup(address->transport_name); | ||
704 | rc->addrcp = GNUNET_HELLO_address_copy (address); | 774 | rc->addrcp = GNUNET_HELLO_address_copy (address); |
705 | rc->printed = GNUNET_NO; | 775 | rc->printed = GNUNET_NO; |
776 | rc->state = state; | ||
777 | rc->state_timeout = state_timeout; | ||
706 | /* Resolve address to string */ | 778 | /* Resolve address to string */ |
707 | rc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric, | 779 | rc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric, |
708 | RESOLUTION_TIMEOUT, &process_string, rc); | 780 | RESOLUTION_TIMEOUT, &process_string, rc); |
709 | } | 781 | } |
710 | 782 | ||
711 | /** | 783 | /** |
712 | * Function called with information about a peers | 784 | * Function called with information about a peers during a one shot iteration |
713 | * | 785 | * |
714 | * @param cls closure | 786 | * @param cls closure |
715 | * @param peer identity of the peer, NULL for final callback when operation done | 787 | * @param peer identity of the peer, NULL for final callback when operation done |
@@ -720,7 +792,7 @@ resolve_address (const struct GNUNET_HELLO_Address *address, int numeric) | |||
720 | * | 792 | * |
721 | */ | 793 | */ |
722 | static void | 794 | static void |
723 | process_peer_cb (void *cls, const struct GNUNET_PeerIdentity *peer, | 795 | process_peer_iteration_cb (void *cls, const struct GNUNET_PeerIdentity *peer, |
724 | const struct GNUNET_HELLO_Address *address, | 796 | const struct GNUNET_HELLO_Address *address, |
725 | enum GNUNET_TRANSPORT_PeerState state, | 797 | enum GNUNET_TRANSPORT_PeerState state, |
726 | struct GNUNET_TIME_Absolute state_timeout) | 798 | struct GNUNET_TIME_Absolute state_timeout) |
@@ -735,9 +807,52 @@ process_peer_cb (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
735 | end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); | 807 | end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); |
736 | return; | 808 | return; |
737 | } | 809 | } |
738 | if (address == NULL ) | 810 | |
811 | if ((GNUNET_NO == iterate_all) && (GNUNET_NO == GNUNET_TRANSPORT_is_connected(state)) ) | ||
812 | return; /* Display only connected peers */ | ||
813 | |||
814 | if (GNUNET_SCHEDULER_NO_TASK != op_timeout) | ||
815 | GNUNET_SCHEDULER_cancel (op_timeout); | ||
816 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, | ||
817 | NULL ); | ||
818 | |||
819 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received address for peer `%s': %s\n", | ||
820 | GNUNET_i2s (peer), address->transport_name); | ||
821 | |||
822 | if (NULL != address) | ||
823 | resolve_address (peer, address, numeric, state, state_timeout); | ||
824 | else | ||
825 | print_info (peer, NULL, NULL, state, state_timeout); | ||
826 | } | ||
827 | |||
828 | |||
829 | /** | ||
830 | * Function called with information about a peers | ||
831 | * | ||
832 | * @param cls closure | ||
833 | * @param peer identity of the peer, NULL for final callback when operation done | ||
834 | * @param address binary address used to communicate with this peer, | ||
835 | * NULL on disconnect or when done | ||
836 | * @param state current state this peer is in | ||
837 | * @param state_timeout time out for the current state | ||
838 | * | ||
839 | */ | ||
840 | static void | ||
841 | process_peer_monitoring_cb (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
842 | const struct GNUNET_HELLO_Address *address, | ||
843 | enum GNUNET_TRANSPORT_PeerState state, | ||
844 | struct GNUNET_TIME_Absolute state_timeout) | ||
845 | { | ||
846 | struct MonitoredPeer *m; | ||
847 | |||
848 | if (peer == NULL ) | ||
739 | { | 849 | { |
740 | FPRINTF (stdout, _("Peer `%s' disconnected\n"), GNUNET_i2s (peer)); | 850 | /* done */ |
851 | address_resolution_in_progress = GNUNET_NO; | ||
852 | pic = NULL; | ||
853 | if (GNUNET_SCHEDULER_NO_TASK != end) | ||
854 | GNUNET_SCHEDULER_cancel (end); | ||
855 | end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); | ||
741 | return; | 856 | return; |
742 | } | 857 | } |
743 | 858 | ||
@@ -746,9 +861,40 @@ process_peer_cb (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
746 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, | 861 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, |
747 | NULL ); | 862 | NULL ); |
748 | 863 | ||
749 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received address for peer `%s': %s\n", | 864 | if (NULL == (m = GNUNET_CONTAINER_multipeermap_get (monitored_peers, peer))) |
750 | GNUNET_i2s (peer), address->transport_name); | 865 | { |
751 | resolve_address (address, numeric); | 866 | m = GNUNET_new (struct MonitoredPeer); |
867 | GNUNET_CONTAINER_multipeermap_put (monitored_peers, peer, | ||
868 | m, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
869 | } | ||
870 | else | ||
871 | { | ||
872 | if ( (m->state == state) && | ||
873 | (m->state_timeout.abs_value_us == state_timeout.abs_value_us) && | ||
874 | ((NULL == address) && (NULL == m->address)) ) | ||
875 | { | ||
876 | return; /* No real change */ | ||
877 | } | ||
878 | if ( ((NULL != address) && (NULL != m->address)) && | ||
879 | (0 == GNUNET_HELLO_address_cmp(m->address, address)) ) | ||
880 | return; /* No real change */ | ||
881 | } | ||
882 | |||
883 | |||
884 | if (NULL != m->address) | ||
885 | { | ||
886 | GNUNET_free (m->address); | ||
887 | m->address = NULL; | ||
888 | } | ||
889 | if (NULL != address) | ||
890 | m->address = GNUNET_HELLO_address_copy (address); | ||
891 | m->state = state; | ||
892 | m->state_timeout = state_timeout; | ||
893 | |||
894 | if (NULL != address) | ||
895 | resolve_address (peer, m->address, numeric, m->state, m->state_timeout); | ||
896 | else | ||
897 | print_info (peer, NULL, NULL, m->state, m->state_timeout); | ||
752 | } | 898 | } |
753 | 899 | ||
754 | static void | 900 | static void |
@@ -903,15 +1049,16 @@ testservice_task (void *cls, int result) | |||
903 | { | 1049 | { |
904 | address_resolution_in_progress = GNUNET_YES; | 1050 | address_resolution_in_progress = GNUNET_YES; |
905 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, | 1051 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, |
906 | GNUNET_YES, TIMEOUT, &process_peer_cb, (void *) cfg); | 1052 | GNUNET_YES, TIMEOUT, &process_peer_iteration_cb, (void *) cfg); |
907 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, | 1053 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, |
908 | NULL ); | 1054 | NULL ); |
909 | } | 1055 | } |
910 | else if (monitor_connections) /* -m: List information about peers continuously */ | 1056 | else if (monitor_connections) /* -m: List information about peers continuously */ |
911 | { | 1057 | { |
1058 | monitored_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); | ||
912 | address_resolution_in_progress = GNUNET_YES; | 1059 | address_resolution_in_progress = GNUNET_YES; |
913 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, | 1060 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, |
914 | GNUNET_NO, TIMEOUT, &process_peer_cb, (void *) cfg); | 1061 | GNUNET_NO, TIMEOUT, &process_peer_monitoring_cb, (void *) cfg); |
915 | } | 1062 | } |
916 | else if (monitor_connects) /* -e : Monitor (dis)connect events continuously */ | 1063 | else if (monitor_connects) /* -e : Monitor (dis)connect events continuously */ |
917 | { | 1064 | { |