aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-transport.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-01-08 17:51:53 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-01-08 17:51:53 +0000
commit5f05330cb3d9ec30347c07522de00624de9d6c67 (patch)
tree213d4a9fdd07a2017c5768d609280fce4b6f146c /src/transport/gnunet-transport.c
parentce8e0739623ee25d2a29a75f393027a42bbe4d4f (diff)
downloadgnunet-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.c183
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;
149static struct GNUNET_TRANSPORT_TransmitHandle *th; 149static struct GNUNET_TRANSPORT_TransmitHandle *th;
150 150
151/** 151/**
152 * Map storing information about monitored peers
153 */
154static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers;
155
156/**
152 * 157 *
153 */ 158 */
154struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; 159struct GNUNET_TRANSPORT_PeerMonitoringContext *pic;
@@ -194,6 +199,7 @@ static unsigned int address_resolutions;
194 */ 199 */
195static unsigned int address_resolution_in_progress; 200static 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
226struct 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
275static struct ResolutionContext *rc_head; 307static 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
643static void 680static void
644resolve_address (const struct GNUNET_HELLO_Address *address, int numeric); 681resolve_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
686static void
687print_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
646static void 708static void
647process_string (void *cls, const char *address) 709process_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
694static void 759static void
695resolve_address (const struct GNUNET_HELLO_Address *address, int numeric) 760resolve_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 */
722static void 794static void
723process_peer_cb (void *cls, const struct GNUNET_PeerIdentity *peer, 795process_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 */
840static void
841process_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
754static void 900static 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 {