aboutsummaryrefslogtreecommitdiff
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
parentce8e0739623ee25d2a29a75f393027a42bbe4d4f (diff)
downloadgnunet-5f05330cb3d9ec30347c07522de00624de9d6c67.tar.gz
gnunet-5f05330cb3d9ec30347c07522de00624de9d6c67.zip
neighbour monitoring api implemented
-rw-r--r--src/include/gnunet_transport_service.h8
-rw-r--r--src/transport/Makefile.am13
-rw-r--r--src/transport/gnunet-service-transport.c30
-rw-r--r--src/transport/gnunet-service-transport.h11
-rw-r--r--src/transport/gnunet-service-transport_blacklist.c23
-rw-r--r--src/transport/gnunet-service-transport_clients.c18
-rw-r--r--src/transport/gnunet-service-transport_clients.h11
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c384
-rw-r--r--src/transport/gnunet-service-transport_neighbours.h2
-rw-r--r--src/transport/gnunet-service-transport_validation.c29
-rw-r--r--src/transport/gnunet-service-transport_validation.h4
-rw-r--r--src/transport/gnunet-transport.c183
-rw-r--r--src/transport/transport.h2
-rw-r--r--src/transport/transport_api_address_to_string.c8
-rw-r--r--src/transport/transport_api_monitoring.c44
15 files changed, 539 insertions, 231 deletions
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
index 5448460ad..2c3c9556f 100644
--- a/src/include/gnunet_transport_service.h
+++ b/src/include/gnunet_transport_service.h
@@ -580,7 +580,7 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle
580/** 580/**
581 * Cancel request for address conversion. 581 * Cancel request for address conversion.
582 * 582 *
583 * @param alc handle for the request to cancel 583 * @param pic the context handle
584 */ 584 */
585void 585void
586GNUNET_TRANSPORT_address_to_string_cancel (struct 586GNUNET_TRANSPORT_address_to_string_cancel (struct
@@ -590,7 +590,7 @@ GNUNET_TRANSPORT_address_to_string_cancel (struct
590/** 590/**
591 * Convert a transport state to a human readable string. 591 * Convert a transport state to a human readable string.
592 * 592 *
593 * @param alc handle for the request to cancel 593 * @param state the state
594 */ 594 */
595const char * 595const char *
596GNUNET_TRANSPORT_p2s (enum GNUNET_TRANSPORT_PeerState state); 596GNUNET_TRANSPORT_p2s (enum GNUNET_TRANSPORT_PeerState state);
@@ -626,8 +626,8 @@ GNUNET_TRANSPORT_is_connected (enum GNUNET_TRANSPORT_PeerState state);
626 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), 626 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL),
627 * GNUNET_NO to monitor peers continuously 627 * GNUNET_NO to monitor peers continuously
628 * @param timeout how long is the lookup allowed to take at most 628 * @param timeout how long is the lookup allowed to take at most
629 * @param peer_address_callback function to call with the results 629 * @param peer_callback function to call with the results
630 * @param peer_address_callback_cls closure for peer_address_callback 630 * @param peer_callback_cls closure for peer_address_callback
631 */ 631 */
632struct GNUNET_TRANSPORT_PeerMonitoringContext * 632struct GNUNET_TRANSPORT_PeerMonitoringContext *
633GNUNET_TRANSPORT_monitor_peers (const struct 633GNUNET_TRANSPORT_monitor_peers (const struct
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 9851a7907..2808dc5cb 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -405,6 +405,7 @@ check_PROGRAMS = \
405 $(BT_API_TEST) \ 405 $(BT_API_TEST) \
406 $(BT_TIMEOUT_TEST) \ 406 $(BT_TIMEOUT_TEST) \
407 test_transport_api_multi \ 407 test_transport_api_multi \
408 test_transport_api_monitoring \
408 test_transport_blacklisting_no_bl \ 409 test_transport_blacklisting_no_bl \
409 test_transport_blacklisting_outbound_bl_full \ 410 test_transport_blacklisting_outbound_bl_full \
410 test_transport_blacklisting_outbound_bl_plugin \ 411 test_transport_blacklisting_outbound_bl_plugin \
@@ -469,6 +470,7 @@ TESTS = \
469 $(BT_API_TEST) \ 470 $(BT_API_TEST) \
470 $(BT_TIMEOUT_TEST) \ 471 $(BT_TIMEOUT_TEST) \
471 test_transport_api_multi \ 472 test_transport_api_multi \
473 test_transport_api_monitoring \
472 test_transport_blacklisting_no_bl \ 474 test_transport_blacklisting_no_bl \
473 test_transport_blacklisting_outbound_bl_full \ 475 test_transport_blacklisting_outbound_bl_full \
474 test_transport_blacklisting_outbound_bl_plugin \ 476 test_transport_blacklisting_outbound_bl_plugin \
@@ -767,8 +769,6 @@ test_transport_api_manipulation_cfg_LDADD = \
767 $(top_builddir)/src/util/libgnunetutil.la \ 769 $(top_builddir)/src/util/libgnunetutil.la \
768 $(top_builddir)/src/transport/libgnunettransporttesting.la 770 $(top_builddir)/src/transport/libgnunettransporttesting.la
769 771
770
771
772test_transport_api_reliability_tcp_SOURCES = \ 772test_transport_api_reliability_tcp_SOURCES = \
773 test_transport_api_reliability.c 773 test_transport_api_reliability.c
774test_transport_api_reliability_tcp_LDADD = \ 774test_transport_api_reliability_tcp_LDADD = \
@@ -1099,6 +1099,15 @@ test_transport_api_multi_LDADD = \
1099 $(top_builddir)/src/transport/libgnunettransporttesting.la 1099 $(top_builddir)/src/transport/libgnunettransporttesting.la
1100 1100
1101 1101
1102test_transport_api_monitoring_SOURCES = \
1103 test_transport_api_monitoring.c
1104test_transport_api_monitoring_LDADD = \
1105 $(top_builddir)/src/transport/libgnunettransport.la \
1106 $(top_builddir)/src/hello/libgnunethello.la \
1107 $(top_builddir)/src/util/libgnunetutil.la \
1108 $(top_builddir)/src/transport/libgnunettransporttesting.la
1109
1110
1102EXTRA_DIST = \ 1111EXTRA_DIST = \
1103test_plugin_hostkey \ 1112test_plugin_hostkey \
1104test_plugin_hostkey.ecc \ 1113test_plugin_hostkey.ecc \
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index ed7a6b81b..811ef5857 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -137,17 +137,24 @@ static struct SessionKiller *sk_tail;
137 * @param cls the 'HELLO' message 137 * @param cls the 'HELLO' message
138 * @param target a connected neighbour 138 * @param target a connected neighbour
139 * @param address the address 139 * @param address the address
140 * @param state current state this peer is in
141 * @param state_timeout timeout for the current state of the peer
140 * @param bandwidth_in inbound quota in NBO 142 * @param bandwidth_in inbound quota in NBO
141 * @param bandwidth_out outbound quota in NBO 143 * @param bandwidth_out outbound quota in NBO
142 */ 144 */
143static void 145static void
144transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target, 146transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target,
145 const struct GNUNET_HELLO_Address *address, 147 const struct GNUNET_HELLO_Address *address,
148 enum GNUNET_TRANSPORT_PeerState state,
149 struct GNUNET_TIME_Absolute state_timeout,
146 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 150 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
147 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 151 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
148{ 152{
149 const struct GNUNET_MessageHeader *hello = cls; 153 const struct GNUNET_MessageHeader *hello = cls;
150 154
155 if ( GNUNET_NO == GST_neighbours_test_connected(target) )
156 return;
157
151 GST_neighbours_send (target, 158 GST_neighbours_send (target,
152 hello, 159 hello,
153 ntohs (hello->size), 160 ntohs (hello->size),
@@ -838,13 +845,28 @@ neighbours_disconnect_notification (void *cls,
838 * @param cls closure 845 * @param cls closure
839 * @param peer peer this update is about (never NULL) 846 * @param peer peer this update is about (never NULL)
840 * @param address address, NULL on disconnect 847 * @param address address, NULL on disconnect
848 * @param state current state this peer is in
849 * @param state_timeout timeout for the current state of the peer
850 * @param bandwidth_in bandwidth assigned inbound
851 * @param bandwidth_out bandwidth assigned outbound
841 */ 852 */
842static void 853static void
843neighbours_address_notification (void *cls, 854neighbours_changed_notification (void *cls,
844 const struct GNUNET_PeerIdentity *peer, 855 const struct GNUNET_PeerIdentity *peer,
845 const struct GNUNET_HELLO_Address *address) 856 const struct GNUNET_HELLO_Address *address,
857 enum GNUNET_TRANSPORT_PeerState state,
858 struct GNUNET_TIME_Absolute state_timeout,
859 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
860 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
846{ 861{
847 GST_clients_broadcast_address_notification (peer, address); 862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
863 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n",
864 GNUNET_i2s (peer),
865 (NULL != address) ? GST_plugins_a2s (address) : "<none>",
866 GNUNET_TRANSPORT_p2s(state),
867 GNUNET_STRINGS_absolute_time_to_string(state_timeout));
868
869 GST_clients_broadcast_peer_notification (peer, address, state, state_timeout);
848} 870}
849 871
850 872
@@ -994,7 +1016,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
994 GST_neighbours_start (NULL, 1016 GST_neighbours_start (NULL,
995 &neighbours_connect_notification, 1017 &neighbours_connect_notification,
996 &neighbours_disconnect_notification, 1018 &neighbours_disconnect_notification,
997 &neighbours_address_notification, 1019 &neighbours_changed_notification,
998 (max_fd / 3) * 2); 1020 (max_fd / 3) * 2);
999 GST_clients_start (GST_server); 1021 GST_clients_start (GST_server);
1000 GST_validation_start ((max_fd / 3)); 1022 GST_validation_start ((max_fd / 3));
diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h
index cc83f2c83..75b387381 100644
--- a/src/transport/gnunet-service-transport.h
+++ b/src/transport/gnunet-service-transport.h
@@ -70,9 +70,14 @@ extern struct GNUNET_ATS_SchedulingHandle *GST_ats;
70 * @param peer peer this update is about, 70 * @param peer peer this update is about,
71 * @param address address, NULL for disconnect notification 71 * @param address address, NULL for disconnect notification
72 */ 72 */
73typedef void (*GNUNET_TRANSPORT_AddressChangeCallback) (void *cls, 73typedef void
74 const struct GNUNET_PeerIdentity *peer, 74(*GNUNET_TRANSPORT_NeighbourChangeCallback) (void *cls,
75 const struct GNUNET_HELLO_Address *address); 75 const struct GNUNET_PeerIdentity *peer,
76 const struct GNUNET_HELLO_Address *address,
77 enum GNUNET_TRANSPORT_PeerState state,
78 struct GNUNET_TIME_Absolute state_timeout,
79 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
80 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out);
76 81
77 82
78/** 83/**
diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c
index db154d911..7e1d7d43b 100644
--- a/src/transport/gnunet-service-transport_blacklist.c
+++ b/src/transport/gnunet-service-transport_blacklist.c
@@ -474,29 +474,32 @@ struct TestConnectionContext
474 struct Blacklisters *bl; 474 struct Blacklisters *bl;
475}; 475};
476 476
477
478/** 477/**
479 * Test if an existing connection is still acceptable given a new 478 * Test if an existing connection is still acceptable given a new
480 * blacklisting client. 479 * blacklisting client.
481 * 480 *
482 * @param cls the 'struct TestConnectionContest' 481 * @param cls the 'struct TestConnectionContest'
483 * @param neighbour neighbour's identity 482 * @param peer neighbour's identity
484 * @param address the address 483 * @param address the address
485 * @param bandwidth_in inbound quota in NBO 484 * @param state current state this peer is in
486 * @param bandwidth_out outbound quota in NBO 485 * @param state_timeout timeout for the current state of the peer
486 * @param bandwidth_in bandwidth assigned inbound
487 * @param bandwidth_out bandwidth assigned outbound
487 */ 488 */
488static void 489static void
489test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *neighbour, 490test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *peer,
490 const struct GNUNET_HELLO_Address *address, 491 const struct GNUNET_HELLO_Address *address,
491 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 492 enum GNUNET_TRANSPORT_PeerState state,
492 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 493 struct GNUNET_TIME_Absolute state_timeout,
494 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
495 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
493{ 496{
494 struct TestConnectionContext *tcc = cls; 497 struct TestConnectionContext *tcc = cls;
495 struct GST_BlacklistCheck *bc; 498 struct GST_BlacklistCheck *bc;
496 499
497 bc = GNUNET_new (struct GST_BlacklistCheck); 500 bc = GNUNET_new (struct GST_BlacklistCheck);
498 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); 501 GNUNET_CONTAINER_DLL_insert(bc_head, bc_tail, bc);
499 bc->peer = *neighbour; 502 bc->peer = *peer;
500 bc->cont = &confirm_or_drop_neighbour; 503 bc->cont = &confirm_or_drop_neighbour;
501 bc->cont_cls = NULL; 504 bc->cont_cls = NULL;
502 bc->bl_pos = tcc->bl; 505 bc->bl_pos = tcc->bl;
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c
index 6bd3e34d5..1fbd56c24 100644
--- a/src/transport/gnunet-service-transport_clients.c
+++ b/src/transport/gnunet-service-transport_clients.c
@@ -463,6 +463,8 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
463 * @param cls the `struct TransportClient *` to notify 463 * @param cls the `struct TransportClient *` to notify
464 * @param peer identity of the neighbour 464 * @param peer identity of the neighbour
465 * @param address the address 465 * @param address the address
466 * @param state the current state of the peer
467 * @param state_timeout the time out for the state
466 * @param bandwidth_in inbound bandwidth in NBO 468 * @param bandwidth_in inbound bandwidth in NBO
467 * @param bandwidth_out outbound bandwidth in NBO 469 * @param bandwidth_out outbound bandwidth in NBO
468 */ 470 */
@@ -908,6 +910,8 @@ struct PeerIterationContext
908 * @param cls the 'struct PeerIterationContext' 910 * @param cls the 'struct PeerIterationContext'
909 * @param peer identity of the neighbour 911 * @param peer identity of the neighbour
910 * @param address the address 912 * @param address the address
913 * @param state current state this peer is in
914 * @param state_timeout timeout for the current state of the peer
911 * @param bandwidth_in inbound quota in NBO 915 * @param bandwidth_in inbound quota in NBO
912 * @param bandwidth_out outbound quota in NBO 916 * @param bandwidth_out outbound quota in NBO
913 */ 917 */
@@ -928,7 +932,9 @@ send_peer_information (void *cls,
928 { 932 {
929 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 933 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
930 "Sending information about `%s' using address `%s' in state `%s'\n", 934 "Sending information about `%s' using address `%s' in state `%s'\n",
931 GNUNET_i2s(peer), address); 935 GNUNET_i2s(peer),
936 (address != NULL) ? GST_plugins_a2s (address) : "<none>",
937 GNUNET_TRANSPORT_p2s (state));
932 msg = compose_address_iterate_response_message (peer, address); 938 msg = compose_address_iterate_response_message (peer, address);
933 msg->state = htonl (state); 939 msg->state = htonl (state);
934 msg->state_timeout = GNUNET_TIME_absolute_hton(state_timeout); 940 msg->state_timeout = GNUNET_TIME_absolute_hton(state_timeout);
@@ -1119,15 +1125,21 @@ GST_clients_unicast (struct GNUNET_SERVER_Client *client,
1119 * 1125 *
1120 * @param peer peer this update is about (never NULL) 1126 * @param peer peer this update is about (never NULL)
1121 * @param address address, NULL on disconnect 1127 * @param address address, NULL on disconnect
1128 * @param state the current state of the peer
1129 * @param state_timeout the time out for the state
1122 */ 1130 */
1123void 1131void
1124GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentity *peer, 1132GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
1125 const struct GNUNET_HELLO_Address *address) 1133 const struct GNUNET_HELLO_Address *address,
1134 enum GNUNET_TRANSPORT_PeerState state,
1135 struct GNUNET_TIME_Absolute state_timeout)
1126{ 1136{
1127 struct PeerIterateResponseMessage *msg; 1137 struct PeerIterateResponseMessage *msg;
1128 struct MonitoringClient *mc; 1138 struct MonitoringClient *mc;
1129 static struct GNUNET_PeerIdentity all_zeros; 1139 static struct GNUNET_PeerIdentity all_zeros;
1130 msg = compose_address_iterate_response_message (peer, address); 1140 msg = compose_address_iterate_response_message (peer, address);
1141 msg->state = htonl (state);
1142 msg->state_timeout = GNUNET_TIME_absolute_hton (state_timeout);
1131 mc = monitoring_clients_head; 1143 mc = monitoring_clients_head;
1132 while (mc != NULL) 1144 while (mc != NULL)
1133 { 1145 {
diff --git a/src/transport/gnunet-service-transport_clients.h b/src/transport/gnunet-service-transport_clients.h
index 6a140c788..5b151382c 100644
--- a/src/transport/gnunet-service-transport_clients.h
+++ b/src/transport/gnunet-service-transport_clients.h
@@ -20,12 +20,13 @@
20 20
21/** 21/**
22 * @file transport/gnunet-service-transport_clients.h 22 * @file transport/gnunet-service-transport_clients.h
23 * @brief plugin management API 23 * @brief client management API
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#ifndef GNUNET_SERVICE_TRANSPORT_CLIENTS_H 26#ifndef GNUNET_SERVICE_TRANSPORT_CLIENTS_H
27#define GNUNET_SERVICE_TRANSPORT_CLIENTS_H 27#define GNUNET_SERVICE_TRANSPORT_CLIENTS_H
28 28
29#include "gnunet_transport_service.h"
29#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
30#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
31#include "gnunet_hello_lib.h" 32#include "gnunet_hello_lib.h"
@@ -75,10 +76,14 @@ GST_clients_unicast (struct GNUNET_SERVER_Client *client,
75 * 76 *
76 * @param peer peer this update is about (never NULL) 77 * @param peer peer this update is about (never NULL)
77 * @param address address, NULL on disconnect 78 * @param address address, NULL on disconnect
79 * @param state the current state of the peer
80 * @param state_timeout the time out for the state
78 */ 81 */
79void 82void
80GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentity *peer, 83GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
81 const struct GNUNET_HELLO_Address *address); 84 const struct GNUNET_HELLO_Address *address,
85 enum GNUNET_TRANSPORT_PeerState state,
86 struct GNUNET_TIME_Absolute state_timeout);
82 87
83 88
84#endif 89#endif
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 7d7d1f7e3..5b1c2e9ee 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -463,7 +463,7 @@ static struct BlackListCheckContext *bc_head;
463static struct BlackListCheckContext *bc_tail; 463static struct BlackListCheckContext *bc_tail;
464 464
465/** 465/**
466 * Closure for #connect_notify_cb, #disconnect_notify_cb and #address_change_cb 466 * Closure for #connect_notify_cb, #disconnect_notify_cb and #neighbour_change_cb
467 */ 467 */
468static void *callback_cls; 468static void *callback_cls;
469 469
@@ -478,9 +478,9 @@ static NotifyConnect connect_notify_cb;
478static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb; 478static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb;
479 479
480/** 480/**
481 * Function to call when we changed an active address of a neighbour. 481 * Function to call when a neighbour changed address, state or bandwidth.
482 */ 482 */
483static GNUNET_TRANSPORT_AddressChangeCallback address_change_cb; 483static GNUNET_TRANSPORT_NeighbourChangeCallback neighbour_change_cb;
484 484
485/** 485/**
486 * counter for connected neighbours 486 * counter for connected neighbours
@@ -562,9 +562,8 @@ free_address (struct NeighbourAddress *na)
562{ 562{
563 if (GNUNET_YES == na->ats_active) 563 if (GNUNET_YES == na->ats_active)
564 { 564 {
565 GST_validation_set_address_use (na->address, na->session, GNUNET_NO, __LINE__); 565 GST_validation_set_address_use (na->address, na->session, GNUNET_NO);
566 GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_NO); 566 GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_NO);
567 address_change_cb (callback_cls, &na->address->peer, NULL);
568 } 567 }
569 568
570 na->ats_active = GNUNET_NO; 569 na->ats_active = GNUNET_NO;
@@ -577,11 +576,64 @@ free_address (struct NeighbourAddress *na)
577 na->session = NULL; 576 na->session = NULL;
578} 577}
579 578
579/* Change the status of the neighbour */
580
581static void
582set_state (struct NeighbourMapEntry *n, enum GNUNET_TRANSPORT_PeerState s)
583{
584 n->state = s;
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' changed state to %s\n",
586 GNUNET_i2s (&n->id),
587 GNUNET_TRANSPORT_p2s(s));
588 neighbour_change_cb (callback_cls,
589 &n->id,
590 n->primary_address.address,
591 n->state, n->timeout,
592 n->primary_address.bandwidth_in,
593 n->primary_address.bandwidth_out);
594
595}
596
597static void
598set_state_and_timeout (struct NeighbourMapEntry *n,
599 enum GNUNET_TRANSPORT_PeerState s,
600 struct GNUNET_TIME_Absolute timeout)
601{
602 n->state = s;
603 n->timeout = timeout;
604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' changed state to %s with timeout %s\n",
605 GNUNET_i2s (&n->id),
606 GNUNET_TRANSPORT_p2s(s),
607 GNUNET_STRINGS_absolute_time_to_string (timeout));
608 neighbour_change_cb (callback_cls,
609 &n->id,
610 n->primary_address.address,
611 n->state, n->timeout,
612 n->primary_address.bandwidth_in,
613 n->primary_address.bandwidth_out);
614}
615
616static void
617set_timeout (struct NeighbourMapEntry *n,
618 struct GNUNET_TIME_Absolute timeout)
619{
620 n->timeout = timeout;
621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' changed timeout %s\n",
622 GNUNET_i2s (&n->id),
623 GNUNET_STRINGS_absolute_time_to_string (timeout));
624 neighbour_change_cb (callback_cls,
625 &n->id,
626 n->primary_address.address,
627 n->state, n->timeout,
628 n->primary_address.bandwidth_in,
629 n->primary_address.bandwidth_out);
630}
631
580 632
581/** 633/**
582 * Initialize the 'struct NeighbourAddress'. 634 * Initialize the alternative address of a neighbour
583 * 635 *
584 * @param na neighbour address to initialize 636 * @param n the neighbour
585 * @param address address of the other peer, NULL if other peer 637 * @param address address of the other peer, NULL if other peer
586 * connected to us 638 * connected to us
587 * @param session session to use (or NULL, in which case an 639 * @param session session to use (or NULL, in which case an
@@ -591,7 +643,85 @@ free_address (struct NeighbourAddress *na)
591 * @param is_active #GNUNET_YES to mark this as the active address with ATS 643 * @param is_active #GNUNET_YES to mark this as the active address with ATS
592 */ 644 */
593static void 645static void
594set_address (struct NeighbourAddress *na, 646set_alternative_address (struct NeighbourMapEntry *n,
647 const struct GNUNET_HELLO_Address *address,
648 struct Session *session,
649 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
650 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
651 int is_active)
652{
653 struct GNUNET_TRANSPORT_PluginFunctions *papi;
654 if (NULL == (papi = GST_plugins_find (address->transport_name)))
655 {
656 GNUNET_break (0);
657 return;
658 }
659 if (session == n->alternative_address.session)
660 {
661 n->alternative_address.bandwidth_in = bandwidth_in;
662 n->alternative_address.bandwidth_out = bandwidth_out;
663 if (is_active != n->alternative_address.ats_active)
664 {
665 n->alternative_address.ats_active = is_active;
666 GNUNET_ATS_address_in_use (GST_ats, n->alternative_address.address,
667 n->alternative_address.session, is_active);
668 GST_validation_set_address_use (n->alternative_address.address,
669 n->alternative_address.session, is_active);
670 }
671 if (GNUNET_YES == is_active)
672 {
673 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
674 send_outbound_quota (&address->peer, bandwidth_out);
675 }
676 return;
677 }
678 free_address (&n->alternative_address);
679 if (NULL == session)
680 session = papi->get_session (papi->cls, address);
681 if (NULL == session)
682 {
683 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
684 "Failed to obtain new session for peer `%s' and address '%s'\n",
685 GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
686 GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
687 return;
688 }
689
690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' switched to address %s\n",
691 GNUNET_i2s (&n->id),
692 GST_plugins_a2s(address));
693
694 n->alternative_address.address = GNUNET_HELLO_address_copy (address);
695 n->alternative_address.bandwidth_in = bandwidth_in;
696 n->alternative_address.bandwidth_out = bandwidth_out;
697 n->alternative_address.session = session;
698 n->alternative_address.ats_active = is_active;
699 n->alternative_address.keep_alive_nonce = 0;
700 if (GNUNET_YES == is_active)
701 {
702 /* Telling ATS about new session */
703 GNUNET_ATS_address_in_use (GST_ats, n->alternative_address.address, n->alternative_address.session, GNUNET_YES);
704 GST_validation_set_address_use (n->alternative_address.address, n->alternative_address.session, GNUNET_YES);
705 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
706 send_outbound_quota (&address->peer, bandwidth_out);
707 }
708}
709
710
711/**
712 * Initialize the primary address of a neighbour
713 *
714 * @param n the neighbour
715 * @param address address of the other peer, NULL if other peer
716 * connected to us
717 * @param session session to use (or NULL, in which case an
718 * address must be setup)
719 * @param bandwidth_in inbound quota to be used when connection is up
720 * @param bandwidth_out outbound quota to be used when connection is up
721 * @param is_active #GNUNET_YES to mark this as the active address with ATS
722 */
723static void
724set_primary_address (struct NeighbourMapEntry *n,
595 const struct GNUNET_HELLO_Address *address, 725 const struct GNUNET_HELLO_Address *address,
596 struct Session *session, 726 struct Session *session,
597 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 727 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
@@ -605,27 +735,24 @@ set_address (struct NeighbourAddress *na,
605 GNUNET_break (0); 735 GNUNET_break (0);
606 return; 736 return;
607 } 737 }
608 if (session == na->session) 738 if (session == n->primary_address.session)
609 { 739 {
610 na->bandwidth_in = bandwidth_in; 740 n->primary_address.bandwidth_in = bandwidth_in;
611 na->bandwidth_out = bandwidth_out; 741 n->primary_address.bandwidth_out = bandwidth_out;
612 if (is_active != na->ats_active) 742 if (is_active != n->primary_address.ats_active)
613 { 743 {
614 na->ats_active = is_active; 744 n->primary_address.ats_active = is_active;
615 GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, is_active); 745 GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, n->primary_address.session, is_active);
616 GST_validation_set_address_use (na->address, na->session, is_active, __LINE__); 746 GST_validation_set_address_use (n->primary_address.address, n->primary_address.session, is_active);
617 if (is_active)
618 address_change_cb (callback_cls, &address->peer, address);
619 } 747 }
620 if (GNUNET_YES == is_active) 748 if (GNUNET_YES == is_active)
621 { 749 {
622 /* FIXME: is this the right place to set quotas? */
623 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); 750 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
624 send_outbound_quota (&address->peer, bandwidth_out); 751 send_outbound_quota (&address->peer, bandwidth_out);
625 } 752 }
626 return; 753 return;
627 } 754 }
628 free_address (na); 755 free_address (&n->primary_address);
629 if (NULL == session) 756 if (NULL == session)
630 session = papi->get_session (papi->cls, address); 757 session = papi->get_session (papi->cls, address);
631 if (NULL == session) 758 if (NULL == session)
@@ -636,22 +763,32 @@ set_address (struct NeighbourAddress *na,
636 GNUNET_ATS_address_destroyed (GST_ats, address, NULL); 763 GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
637 return; 764 return;
638 } 765 }
639 na->address = GNUNET_HELLO_address_copy (address); 766
640 na->bandwidth_in = bandwidth_in; 767 n->primary_address.address = GNUNET_HELLO_address_copy (address);
641 na->bandwidth_out = bandwidth_out; 768 n->primary_address.bandwidth_in = bandwidth_in;
642 na->session = session; 769 n->primary_address.bandwidth_out = bandwidth_out;
643 na->ats_active = is_active; 770 n->primary_address.session = session;
644 na->keep_alive_nonce = 0; 771 n->primary_address.ats_active = is_active;
772 n->primary_address.keep_alive_nonce = 0;
645 if (GNUNET_YES == is_active) 773 if (GNUNET_YES == is_active)
646 { 774 {
647 /* Telling ATS about new session */ 775 /* Telling ATS about new session */
648 GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_YES); 776 GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, n->primary_address.session, GNUNET_YES);
649 GST_validation_set_address_use (na->address, na->session, GNUNET_YES, __LINE__); 777 GST_validation_set_address_use (n->primary_address.address, n->primary_address.session, GNUNET_YES);
650 address_change_cb (callback_cls, &address->peer, address);
651 /* FIXME: is this the right place to set quotas? */
652 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); 778 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
653 send_outbound_quota (&address->peer, bandwidth_out); 779 send_outbound_quota (&address->peer, bandwidth_out);
654 } 780 }
781
782 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' switched to address %s\n",
783 GNUNET_i2s (&n->id),
784 GST_plugins_a2s(address));
785
786 neighbour_change_cb (callback_cls,
787 &n->id,
788 n->primary_address.address,
789 n->state, n->timeout,
790 n->primary_address.bandwidth_in,
791 n->primary_address.bandwidth_out);
655} 792}
656 793
657 794
@@ -693,7 +830,7 @@ free_neighbour (struct NeighbourMapEntry *n,
693 GNUNET_NO); 830 GNUNET_NO);
694 disconnect_notify_cb (callback_cls, &n->id); 831 disconnect_notify_cb (callback_cls, &n->id);
695 } 832 }
696 n->state = S_DISCONNECT_FINISHED; 833 set_state (n, S_DISCONNECT_FINISHED);
697 834
698 if (NULL != n->primary_address.address) 835 if (NULL != n->primary_address.address)
699 { 836 {
@@ -892,24 +1029,24 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
892 case S_INIT_ATS: 1029 case S_INIT_ATS:
893 case S_INIT_BLACKLIST: 1030 case S_INIT_BLACKLIST:
894 /* other peer is completely unaware of us, no need to send DISCONNECT */ 1031 /* other peer is completely unaware of us, no need to send DISCONNECT */
895 n->state = S_DISCONNECT_FINISHED; 1032 set_state (n, S_DISCONNECT_FINISHED);
896 free_neighbour (n, GNUNET_NO); 1033 free_neighbour (n, GNUNET_NO);
897 return; 1034 return;
898 case S_CONNECT_SENT: 1035 case S_CONNECT_SENT:
899 send_disconnect (n); 1036 send_disconnect (n);
900 n->state = S_DISCONNECT; 1037 set_state (n, S_DISCONNECT);
901 break; 1038 break;
902 case S_CONNECT_RECV_BLACKLIST_INBOUND: 1039 case S_CONNECT_RECV_BLACKLIST_INBOUND:
903 case S_CONNECT_RECV_ATS: 1040 case S_CONNECT_RECV_ATS:
904 case S_CONNECT_RECV_BLACKLIST: 1041 case S_CONNECT_RECV_BLACKLIST:
905 /* we never ACK'ed the other peer's request, no need to send DISCONNECT */ 1042 /* we never ACK'ed the other peer's request, no need to send DISCONNECT */
906 n->state = S_DISCONNECT_FINISHED; 1043 set_state (n, S_DISCONNECT_FINISHED);
907 free_neighbour (n, GNUNET_NO); 1044 free_neighbour (n, GNUNET_NO);
908 return; 1045 return;
909 case S_CONNECT_RECV_ACK: 1046 case S_CONNECT_RECV_ACK:
910 /* we DID ACK the other peer's request, must send DISCONNECT */ 1047 /* we DID ACK the other peer's request, must send DISCONNECT */
911 send_disconnect (n); 1048 send_disconnect (n);
912 n->state = S_DISCONNECT; 1049 set_state (n, S_DISCONNECT);
913 break; 1050 break;
914 case S_CONNECTED: 1051 case S_CONNECTED:
915 case S_RECONNECT_BLACKLIST: 1052 case S_RECONNECT_BLACKLIST:
@@ -924,7 +1061,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
924 --neighbours_connected, 1061 --neighbours_connected,
925 GNUNET_NO); 1062 GNUNET_NO);
926 disconnect_notify_cb (callback_cls, &n->id); 1063 disconnect_notify_cb (callback_cls, &n->id);
927 n->state = S_DISCONNECT; 1064 set_state (n, S_DISCONNECT);
928 break; 1065 break;
929 case S_RECONNECT_ATS: 1066 case S_RECONNECT_ATS:
930 /* ATS address request timeout, disconnect without sending disconnect message */ 1067 /* ATS address request timeout, disconnect without sending disconnect message */
@@ -933,7 +1070,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
933 --neighbours_connected, 1070 --neighbours_connected,
934 GNUNET_NO); 1071 GNUNET_NO);
935 disconnect_notify_cb (callback_cls, &n->id); 1072 disconnect_notify_cb (callback_cls, &n->id);
936 n->state = S_DISCONNECT; 1073 set_state (n, S_DISCONNECT);
937 break; 1074 break;
938 case S_DISCONNECT: 1075 case S_DISCONNECT:
939 /* already disconnected, ignore */ 1076 /* already disconnected, ignore */
@@ -1268,7 +1405,8 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1268 n->primary_address.keep_alive_nonce = 0; 1405 n->primary_address.keep_alive_nonce = 0;
1269 n->expect_latency_response = GNUNET_NO; 1406 n->expect_latency_response = GNUNET_NO;
1270 n->latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time); 1407 n->latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time);
1271 n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 1408 set_timeout (n, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
1409
1272 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1273 "Latency for peer `%s' is %s\n", 1411 "Latency for peer `%s' is %s\n",
1274 GNUNET_i2s (&n->id), 1412 GNUNET_i2s (&n->id),
@@ -1550,7 +1688,6 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
1550 GNUNET_i2s (peer)); 1688 GNUNET_i2s (peer));
1551 n = GNUNET_new (struct NeighbourMapEntry); 1689 n = GNUNET_new (struct NeighbourMapEntry);
1552 n->id = *peer; 1690 n->id = *peer;
1553 n->state = S_NOT_CONNECTED;
1554 n->latency = GNUNET_TIME_UNIT_FOREVER_REL; 1691 n->latency = GNUNET_TIME_UNIT_FOREVER_REL;
1555 n->last_util_transmission = GNUNET_TIME_absolute_get(); 1692 n->last_util_transmission = GNUNET_TIME_absolute_get();
1556 n->util_payload_bytes_recv = 0; 1693 n->util_payload_bytes_recv = 0;
@@ -1561,6 +1698,7 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
1561 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, 1698 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
1562 MAX_BANDWIDTH_CARRY_S); 1699 MAX_BANDWIDTH_CARRY_S);
1563 n->task = GNUNET_SCHEDULER_add_now (&master_task, n); 1700 n->task = GNUNET_SCHEDULER_add_now (&master_task, n);
1701 set_state_and_timeout (n, S_NOT_CONNECTED, GNUNET_TIME_UNIT_FOREVER_ABS);
1564 GNUNET_assert (GNUNET_OK == 1702 GNUNET_assert (GNUNET_OK ==
1565 GNUNET_CONTAINER_multipeermap_put (neighbours, 1703 GNUNET_CONTAINER_multipeermap_put (neighbours,
1566 &n->id, n, 1704 &n->id, n,
@@ -1664,8 +1802,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
1664 } 1802 }
1665 } 1803 }
1666 n = setup_neighbour (target); 1804 n = setup_neighbour (target);
1667 n->state = S_INIT_ATS; 1805 set_state_and_timeout (n, S_INIT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1668 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
1669 1806
1670 GNUNET_ATS_reset_backoff (GST_ats, target); 1807 GNUNET_ATS_reset_backoff (GST_ats, target);
1671 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, target); 1808 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, target);
@@ -1751,15 +1888,13 @@ handle_test_blacklist_cont (void *cls,
1751 } 1888 }
1752 if (GNUNET_OK == result) 1889 if (GNUNET_OK == result)
1753 { 1890 {
1754 n->timeout = GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT); 1891 set_state_and_timeout (n, S_CONNECT_SENT, GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
1755 n->state = S_CONNECT_SENT;
1756 send_session_connect (&n->primary_address); 1892 send_session_connect (&n->primary_address);
1757 } 1893 }
1758 else 1894 else
1759 { 1895 {
1760 free_address (&n->primary_address); 1896 free_address (&n->primary_address);
1761 n->state = S_INIT_ATS; 1897 set_state_and_timeout (n, S_INIT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1762 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
1763 } 1898 }
1764 break; 1899 break;
1765 case S_CONNECT_SENT: 1900 case S_CONNECT_SENT:
@@ -1774,8 +1909,7 @@ handle_test_blacklist_cont (void *cls,
1774 } 1909 }
1775 break; 1910 break;
1776 case S_CONNECT_RECV_BLACKLIST_INBOUND: 1911 case S_CONNECT_RECV_BLACKLIST_INBOUND:
1777 n->state = S_CONNECT_RECV_ATS; 1912 set_state_and_timeout (n, S_CONNECT_RECV_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1778 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
1779 GNUNET_ATS_reset_backoff (GST_ats, peer); 1913 GNUNET_ATS_reset_backoff (GST_ats, peer);
1780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1781 "Suggesting address for peer %s to ATS\n", 1915 "Suggesting address for peer %s to ATS\n",
@@ -1794,8 +1928,7 @@ handle_test_blacklist_cont (void *cls,
1794 } 1928 }
1795 if (GNUNET_OK == result) 1929 if (GNUNET_OK == result)
1796 { 1930 {
1797 n->timeout = GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT); 1931 set_state_and_timeout (n, S_CONNECT_RECV_ACK, GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
1798 n->state = S_CONNECT_RECV_ACK;
1799 send_session_connect_ack_message (bcc->na.address, 1932 send_session_connect_ack_message (bcc->na.address,
1800 bcc->na.session, 1933 bcc->na.session,
1801 n->connect_ack_timestamp); 1934 n->connect_ack_timestamp);
@@ -1816,8 +1949,7 @@ handle_test_blacklist_cont (void *cls,
1816 } 1949 }
1817 GNUNET_break (NULL != plugin); 1950 GNUNET_break (NULL != plugin);
1818 free_address (&n->primary_address); 1951 free_address (&n->primary_address);
1819 n->state = S_INIT_ATS; 1952 set_state_and_timeout (n, S_INIT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1820 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
1821 GNUNET_ATS_reset_backoff (GST_ats, peer); 1953 GNUNET_ATS_reset_backoff (GST_ats, peer);
1822 } 1954 }
1823 break; 1955 break;
@@ -1855,14 +1987,12 @@ handle_test_blacklist_cont (void *cls,
1855 } 1987 }
1856 if (GNUNET_OK == result) 1988 if (GNUNET_OK == result)
1857 { 1989 {
1858 n->state = S_RECONNECT_SENT; 1990 set_state_and_timeout (n, S_RECONNECT_SENT, GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
1859 send_session_connect (&n->primary_address); 1991 send_session_connect (&n->primary_address);
1860 n->timeout = GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT);
1861 } 1992 }
1862 else 1993 else
1863 { 1994 {
1864 n->state = S_RECONNECT_ATS; 1995 set_state_and_timeout (n, S_RECONNECT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1865 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
1866 } 1996 }
1867 break; 1997 break;
1868 case S_RECONNECT_SENT: 1998 case S_RECONNECT_SENT:
@@ -1886,11 +2016,11 @@ handle_test_blacklist_cont (void *cls,
1886 if (GNUNET_OK == result) 2016 if (GNUNET_OK == result)
1887 { 2017 {
1888 send_session_connect (&n->alternative_address); 2018 send_session_connect (&n->alternative_address);
1889 n->state = S_CONNECTED_SWITCHING_CONNECT_SENT; 2019 set_state (n, S_CONNECTED_SWITCHING_CONNECT_SENT);
1890 } 2020 }
1891 else 2021 else
1892 { 2022 {
1893 n->state = S_CONNECTED; 2023 set_state(n, S_CONNECTED);
1894 free_address (&n->alternative_address); 2024 free_address (&n->alternative_address);
1895 } 2025 }
1896 break; 2026 break;
@@ -2021,13 +2151,13 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
2021 switch (n->state) 2151 switch (n->state)
2022 { 2152 {
2023 case S_NOT_CONNECTED: 2153 case S_NOT_CONNECTED:
2024 n->state = S_CONNECT_RECV_BLACKLIST_INBOUND;
2025 /* Do a blacklist check for the new address */ 2154 /* Do a blacklist check for the new address */
2155 set_state (n, S_CONNECT_RECV_BLACKLIST_INBOUND);
2026 check_blacklist (peer, ts, address, session); 2156 check_blacklist (peer, ts, address, session);
2027 break; 2157 break;
2028 case S_INIT_ATS: 2158 case S_INIT_ATS:
2029 /* CONNECT message takes priority over us asking ATS for address */ 2159 /* CONNECT message takes priority over us asking ATS for address */
2030 n->state = S_CONNECT_RECV_BLACKLIST_INBOUND; 2160 set_state (n, S_CONNECT_RECV_BLACKLIST_INBOUND);
2031 /* fallthrough */ 2161 /* fallthrough */
2032 case S_INIT_BLACKLIST: 2162 case S_INIT_BLACKLIST:
2033 case S_CONNECT_SENT: 2163 case S_CONNECT_SENT:
@@ -2073,7 +2203,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
2073 /* get rid of remains without terminating sessions, ready to re-try */ 2203 /* get rid of remains without terminating sessions, ready to re-try */
2074 free_neighbour (n, GNUNET_YES); 2204 free_neighbour (n, GNUNET_YES);
2075 n = setup_neighbour (peer); 2205 n = setup_neighbour (peer);
2076 n->state = S_CONNECT_RECV_ATS; 2206 set_state (n, S_CONNECT_RECV_ATS);
2077 GNUNET_ATS_reset_backoff (GST_ats, peer); 2207 GNUNET_ATS_reset_backoff (GST_ats, peer);
2078 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, peer); 2208 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, peer);
2079 break; 2209 break;
@@ -2184,44 +2314,41 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2184 free_neighbour (n, GNUNET_NO); 2314 free_neighbour (n, GNUNET_NO);
2185 return; 2315 return;
2186 case S_INIT_ATS: 2316 case S_INIT_ATS:
2187 set_address (&n->primary_address, 2317 set_primary_address (n, address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2188 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2318 set_state_and_timeout (n, S_INIT_BLACKLIST, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2189 n->state = S_INIT_BLACKLIST;
2190 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT);
2191 check_blacklist (&n->id, 2319 check_blacklist (&n->id,
2192 n->connect_ack_timestamp, 2320 n->connect_ack_timestamp,
2193 address, session); 2321 address, session);
2194 break; 2322 break;
2195 case S_INIT_BLACKLIST: 2323 case S_INIT_BLACKLIST:
2196 /* ATS suggests a different address, switch again */ 2324 /* ATS suggests a different address, switch again */
2197 set_address (&n->primary_address, 2325 set_primary_address (n,
2198 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2326 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2199 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); 2327 set_timeout (n, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2200 check_blacklist (&n->id, 2328 check_blacklist (&n->id,
2201 n->connect_ack_timestamp, 2329 n->connect_ack_timestamp,
2202 address, session); 2330 address, session);
2203 break; 2331 break;
2204 case S_CONNECT_SENT: 2332 case S_CONNECT_SENT:
2205 /* ATS suggests a different address, switch again */ 2333 /* ATS suggests a different address, switch again */
2206 set_address (&n->primary_address, 2334 set_primary_address (n, address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2207 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2335 set_state_and_timeout (n, S_INIT_BLACKLIST, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2208 n->state = S_INIT_BLACKLIST;
2209 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT);
2210 check_blacklist (&n->id, 2336 check_blacklist (&n->id,
2211 n->connect_ack_timestamp, 2337 n->connect_ack_timestamp,
2212 address, session); 2338 address, session);
2213 break; 2339 break;
2214 case S_CONNECT_RECV_ATS: 2340 case S_CONNECT_RECV_ATS:
2215 set_address (&n->primary_address, 2341 set_primary_address (n,
2216 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2342 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2217 n->state = S_CONNECT_RECV_BLACKLIST; 2343 set_state_and_timeout (n, S_CONNECT_RECV_BLACKLIST, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2218 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT);
2219 check_blacklist (&n->id, 2344 check_blacklist (&n->id,
2220 n->connect_ack_timestamp, 2345 n->connect_ack_timestamp,
2221 address, session); 2346 address, session);
2222 break; 2347 break;
2223 case S_CONNECT_RECV_BLACKLIST_INBOUND: 2348 case S_CONNECT_RECV_BLACKLIST_INBOUND:
2224 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); 2349 set_timeout (n, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2350 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2351 n->state, n->timeout, bandwidth_in, bandwidth_out);
2225 check_blacklist (&n->id, 2352 check_blacklist (&n->id,
2226 n->connect_ack_timestamp, 2353 n->connect_ack_timestamp,
2227 address, session); 2354 address, session);
@@ -2230,10 +2357,11 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2230 case S_CONNECT_RECV_ACK: 2357 case S_CONNECT_RECV_ACK:
2231 /* ATS asks us to switch while we were trying to connect; switch to new 2358 /* ATS asks us to switch while we were trying to connect; switch to new
2232 address and check blacklist again */ 2359 address and check blacklist again */
2233 set_address (&n->primary_address, 2360 set_primary_address (n,
2234 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2361 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2235 n->state = S_CONNECT_RECV_BLACKLIST; 2362 set_state_and_timeout (n, S_CONNECT_RECV_BLACKLIST, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2236 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); 2363 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2364 n->state, n->timeout, bandwidth_in, bandwidth_out);
2237 check_blacklist (&n->id, 2365 check_blacklist (&n->id,
2238 n->connect_ack_timestamp, 2366 n->connect_ack_timestamp,
2239 address, session); 2367 address, session);
@@ -2244,24 +2372,29 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2244 if (n->primary_address.session == session) 2372 if (n->primary_address.session == session)
2245 { 2373 {
2246 /* not an address change, just a quota change */ 2374 /* not an address change, just a quota change */
2247 set_address (&n->primary_address, 2375 set_primary_address (n,
2248 address, session, bandwidth_in, bandwidth_out, GNUNET_YES); 2376 address, session, bandwidth_in, bandwidth_out, GNUNET_YES);
2377 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2378 n->state, n->timeout, bandwidth_in, bandwidth_out);
2249 break; 2379 break;
2250 } 2380 }
2251 /* ATS asks us to switch a life connection; see if we can get 2381 /* ATS asks us to switch a life connection; see if we can get
2252 a CONNECT_ACK on it before we actually do this! */ 2382 a CONNECT_ACK on it before we actually do this! */
2253 n->state = S_CONNECTED_SWITCHING_BLACKLIST; 2383 set_state (n, S_CONNECTED_SWITCHING_BLACKLIST);
2254 set_address (&n->alternative_address, 2384 set_alternative_address (n,
2255 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2385 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2386 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2387 n->state, n->timeout, bandwidth_in, bandwidth_out);
2256 check_blacklist (&n->id, 2388 check_blacklist (&n->id,
2257 GNUNET_TIME_absolute_get (), 2389 GNUNET_TIME_absolute_get (),
2258 address, session); 2390 address, session);
2259 break; 2391 break;
2260 case S_RECONNECT_ATS: 2392 case S_RECONNECT_ATS:
2261 n->state = S_RECONNECT_BLACKLIST; 2393 set_primary_address (n,
2262 set_address (&n->primary_address,
2263 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2394 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2264 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); 2395 set_state_and_timeout (n, S_RECONNECT_BLACKLIST, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2396 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2397 n->state, n->timeout, bandwidth_in, bandwidth_out);
2265 check_blacklist (&n->id, 2398 check_blacklist (&n->id,
2266 n->connect_ack_timestamp, 2399 n->connect_ack_timestamp,
2267 address, session); 2400 address, session);
@@ -2269,9 +2402,11 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2269 case S_RECONNECT_BLACKLIST: 2402 case S_RECONNECT_BLACKLIST:
2270 /* ATS asks us to switch while we were trying to reconnect; switch to new 2403 /* ATS asks us to switch while we were trying to reconnect; switch to new
2271 address and check blacklist again */ 2404 address and check blacklist again */
2272 set_address (&n->primary_address, 2405 set_primary_address (n,
2273 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2406 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2274 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); 2407 set_timeout (n, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2408 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2409 n->state, n->timeout, bandwidth_in, bandwidth_out);
2275 check_blacklist (&n->id, 2410 check_blacklist (&n->id,
2276 n->connect_ack_timestamp, 2411 n->connect_ack_timestamp,
2277 address, session); 2412 address, session);
@@ -2279,10 +2414,11 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2279 case S_RECONNECT_SENT: 2414 case S_RECONNECT_SENT:
2280 /* ATS asks us to switch while we were trying to reconnect; switch to new 2415 /* ATS asks us to switch while we were trying to reconnect; switch to new
2281 address and check blacklist again */ 2416 address and check blacklist again */
2282 n->state = S_RECONNECT_BLACKLIST; 2417 set_primary_address (n,
2283 set_address (&n->primary_address,
2284 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2418 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2285 n->timeout = GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT); 2419 set_state_and_timeout (n, S_RECONNECT_BLACKLIST, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
2420 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2421 n->state, n->timeout, bandwidth_in, bandwidth_out);
2286 check_blacklist (&n->id, 2422 check_blacklist (&n->id,
2287 n->connect_ack_timestamp, 2423 n->connect_ack_timestamp,
2288 address, session); 2424 address, session);
@@ -2291,13 +2427,15 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2291 if (n->primary_address.session == session) 2427 if (n->primary_address.session == session)
2292 { 2428 {
2293 /* ATS switches back to still-active session */ 2429 /* ATS switches back to still-active session */
2294 n->state = S_CONNECTED; 2430 set_state(n, S_CONNECTED);
2295 free_address (&n->alternative_address); 2431 free_address (&n->alternative_address);
2296 break; 2432 break;
2297 } 2433 }
2298 /* ATS asks us to switch a life connection, update blacklist check */ 2434 /* ATS asks us to switch a life connection, update blacklist check */
2299 set_address (&n->alternative_address, 2435 set_primary_address (n,
2300 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2436 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2437 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2438 n->state, n->timeout, bandwidth_in, bandwidth_out);
2301 check_blacklist (&n->id, 2439 check_blacklist (&n->id,
2302 GNUNET_TIME_absolute_get (), 2440 GNUNET_TIME_absolute_get (),
2303 address, session); 2441 address, session);
@@ -2307,13 +2445,15 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2307 { 2445 {
2308 /* ATS switches back to still-active session */ 2446 /* ATS switches back to still-active session */
2309 free_address (&n->alternative_address); 2447 free_address (&n->alternative_address);
2310 n->state = S_CONNECTED; 2448 set_state (n, S_CONNECTED);
2311 break; 2449 break;
2312 } 2450 }
2313 /* ATS asks us to switch a life connection, update blacklist check */ 2451 /* ATS asks us to switch a life connection, update blacklist check */
2314 n->state = S_CONNECTED_SWITCHING_BLACKLIST; 2452 set_state (n, S_CONNECTED_SWITCHING_BLACKLIST);
2315 set_address (&n->alternative_address, 2453 set_alternative_address (n,
2316 address, session, bandwidth_in, bandwidth_out, GNUNET_NO); 2454 address, session, bandwidth_in, bandwidth_out, GNUNET_NO);
2455 neighbour_change_cb (callback_cls, &n->id, n->primary_address.address,
2456 n->state, n->timeout, bandwidth_in, bandwidth_out);
2317 check_blacklist (&n->id, 2457 check_blacklist (&n->id,
2318 GNUNET_TIME_absolute_get (), 2458 GNUNET_TIME_absolute_get (),
2319 address, session); 2459 address, session);
@@ -2502,7 +2642,7 @@ master_task (void *cls,
2502 case S_NOT_CONNECTED: 2642 case S_NOT_CONNECTED:
2503 /* invalid state for master task, clean up */ 2643 /* invalid state for master task, clean up */
2504 GNUNET_break (0); 2644 GNUNET_break (0);
2505 n->state = S_DISCONNECT_FINISHED; 2645 set_state (n, S_DISCONNECT_FINISHED);
2506 free_neighbour (n, GNUNET_NO); 2646 free_neighbour (n, GNUNET_NO);
2507 return; 2647 return;
2508 case S_INIT_ATS: 2648 case S_INIT_ATS:
@@ -2511,7 +2651,7 @@ master_task (void *cls,
2511 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2651 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2512 "Connection to `%s' timed out waiting for ATS to provide address\n", 2652 "Connection to `%s' timed out waiting for ATS to provide address\n",
2513 GNUNET_i2s (&n->id)); 2653 GNUNET_i2s (&n->id));
2514 n->state = S_DISCONNECT_FINISHED; 2654 set_state (n, S_DISCONNECT_FINISHED);
2515 free_neighbour (n, GNUNET_NO); 2655 free_neighbour (n, GNUNET_NO);
2516 return; 2656 return;
2517 } 2657 }
@@ -2522,7 +2662,7 @@ master_task (void *cls,
2522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2662 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2523 "Connection to `%s' timed out waiting for BLACKLIST to approve address\n", 2663 "Connection to `%s' timed out waiting for BLACKLIST to approve address\n",
2524 GNUNET_i2s (&n->id)); 2664 GNUNET_i2s (&n->id));
2525 n->state = S_DISCONNECT_FINISHED; 2665 set_state (n, S_DISCONNECT_FINISHED);
2526 free_neighbour (n, GNUNET_NO); 2666 free_neighbour (n, GNUNET_NO);
2527 return; 2667 return;
2528 } 2668 }
@@ -2549,7 +2689,7 @@ master_task (void *cls,
2549 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2550 "Connection to `%s' timed out waiting BLACKLIST to approve address to use for received CONNECT\n", 2690 "Connection to `%s' timed out waiting BLACKLIST to approve address to use for received CONNECT\n",
2551 GNUNET_i2s (&n->id)); 2691 GNUNET_i2s (&n->id));
2552 n->state = S_DISCONNECT_FINISHED; 2692 set_state (n, S_DISCONNECT_FINISHED);
2553 free_neighbour (n, GNUNET_NO); 2693 free_neighbour (n, GNUNET_NO);
2554 return; 2694 return;
2555 } 2695 }
@@ -2560,7 +2700,7 @@ master_task (void *cls,
2560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2700 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2561 "Connection to `%s' timed out waiting ATS to provide address to use for CONNECT_ACK\n", 2701 "Connection to `%s' timed out waiting ATS to provide address to use for CONNECT_ACK\n",
2562 GNUNET_i2s (&n->id)); 2702 GNUNET_i2s (&n->id));
2563 n->state = S_DISCONNECT_FINISHED; 2703 set_state (n, S_DISCONNECT_FINISHED);
2564 free_neighbour (n, GNUNET_NO); 2704 free_neighbour (n, GNUNET_NO);
2565 return; 2705 return;
2566 } 2706 }
@@ -2571,7 +2711,7 @@ master_task (void *cls,
2571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2711 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2572 "Connection to `%s' timed out waiting BLACKLIST to approve address to use for CONNECT_ACK\n", 2712 "Connection to `%s' timed out waiting BLACKLIST to approve address to use for CONNECT_ACK\n",
2573 GNUNET_i2s (&n->id)); 2713 GNUNET_i2s (&n->id));
2574 n->state = S_DISCONNECT_FINISHED; 2714 set_state (n, S_DISCONNECT_FINISHED);
2575 free_neighbour (n, GNUNET_NO); 2715 free_neighbour (n, GNUNET_NO);
2576 return; 2716 return;
2577 } 2717 }
@@ -2771,8 +2911,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2771 "CONNECT_ACK ignored as the timestamp does not match our CONNECT request\n"); 2911 "CONNECT_ACK ignored as the timestamp does not match our CONNECT request\n");
2772 return GNUNET_OK; 2912 return GNUNET_OK;
2773 } 2913 }
2774 n->state = S_CONNECTED; 2914 set_state_and_timeout (n, S_CONNECTED, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
2775 n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2776 GNUNET_STATISTICS_set (GST_stats, 2915 GNUNET_STATISTICS_set (GST_stats,
2777 gettext_noop ("# peers connected"), 2916 gettext_noop ("# peers connected"),
2778 ++neighbours_connected, 2917 ++neighbours_connected,
@@ -2784,7 +2923,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2784 GST_ats_add_address (n->primary_address.address, 2923 GST_ats_add_address (n->primary_address.address,
2785 n->primary_address.session, 2924 n->primary_address.session,
2786 NULL, 0); 2925 NULL, 0);
2787 set_address (&n->primary_address, 2926 set_primary_address (n,
2788 n->primary_address.address, 2927 n->primary_address.address,
2789 n->primary_address.session, 2928 n->primary_address.session,
2790 n->primary_address.bandwidth_in, 2929 n->primary_address.bandwidth_in,
@@ -2816,7 +2955,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2816 break; 2955 break;
2817 case S_RECONNECT_SENT: 2956 case S_RECONNECT_SENT:
2818 /* new address worked; go back to connected! */ 2957 /* new address worked; go back to connected! */
2819 n->state = S_CONNECTED; 2958 set_state (n, S_CONNECTED);
2820 send_session_ack_message (n); 2959 send_session_ack_message (n);
2821 break; 2960 break;
2822 case S_CONNECTED_SWITCHING_BLACKLIST: 2961 case S_CONNECTED_SWITCHING_BLACKLIST:
@@ -2825,14 +2964,13 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2825 break; 2964 break;
2826 case S_CONNECTED_SWITCHING_CONNECT_SENT: 2965 case S_CONNECTED_SWITCHING_CONNECT_SENT:
2827 /* new address worked; adopt it and go back to connected! */ 2966 /* new address worked; adopt it and go back to connected! */
2828 n->state = S_CONNECTED; 2967 set_state_and_timeout (n, S_CONNECTED, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
2829 n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2830 GNUNET_break (GNUNET_NO == n->alternative_address.ats_active); 2968 GNUNET_break (GNUNET_NO == n->alternative_address.ats_active);
2831 2969
2832 GST_ats_add_address (n->alternative_address.address, 2970 GST_ats_add_address (n->alternative_address.address,
2833 n->alternative_address.session, 2971 n->alternative_address.session,
2834 NULL, 0); 2972 NULL, 0);
2835 set_address (&n->primary_address, 2973 set_alternative_address (n,
2836 n->alternative_address.address, 2974 n->alternative_address.address,
2837 n->alternative_address.session, 2975 n->alternative_address.session,
2838 n->alternative_address.bandwidth_in, 2976 n->alternative_address.bandwidth_in,
@@ -2902,7 +3040,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
2902 { 3040 {
2903 if ( (S_CONNECTED_SWITCHING_BLACKLIST == n->state) || 3041 if ( (S_CONNECTED_SWITCHING_BLACKLIST == n->state) ||
2904 (S_CONNECTED_SWITCHING_CONNECT_SENT == n->state) ) 3042 (S_CONNECTED_SWITCHING_CONNECT_SENT == n->state) )
2905 n->state = S_CONNECTED; 3043 set_state (n, S_CONNECTED);
2906 else 3044 else
2907 GNUNET_break (0); 3045 GNUNET_break (0);
2908 free_address (&n->alternative_address); 3046 free_address (&n->alternative_address);
@@ -2924,10 +3062,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
2924 case S_INIT_BLACKLIST: 3062 case S_INIT_BLACKLIST:
2925 case S_CONNECT_SENT: 3063 case S_CONNECT_SENT:
2926 free_address (&n->primary_address); 3064 free_address (&n->primary_address);
2927 n->state = S_INIT_ATS; 3065 set_state_and_timeout (n, S_INIT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2928 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
2929 // FIXME: need to ask ATS for suggestions again?
2930 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id);
2931 break; 3066 break;
2932 case S_CONNECT_RECV_BLACKLIST_INBOUND: 3067 case S_CONNECT_RECV_BLACKLIST_INBOUND:
2933 case S_CONNECT_RECV_ATS: 3068 case S_CONNECT_RECV_ATS:
@@ -2938,11 +3073,8 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
2938 free_neighbour (n, GNUNET_NO); 3073 free_neighbour (n, GNUNET_NO);
2939 return GNUNET_YES; 3074 return GNUNET_YES;
2940 case S_CONNECTED: 3075 case S_CONNECTED:
2941 n->state = S_RECONNECT_ATS; 3076 set_state_and_timeout (n, S_INIT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2942 free_address (&n->primary_address); 3077 free_address (&n->primary_address);
2943 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
2944 /* FIXME: is this ATS call needed? */
2945 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id);
2946 break; 3078 break;
2947 case S_RECONNECT_ATS: 3079 case S_RECONNECT_ATS:
2948 /* we don't have an address, how can it go down? */ 3080 /* we don't have an address, how can it go down? */
@@ -2950,28 +3082,23 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
2950 break; 3082 break;
2951 case S_RECONNECT_BLACKLIST: 3083 case S_RECONNECT_BLACKLIST:
2952 case S_RECONNECT_SENT: 3084 case S_RECONNECT_SENT:
2953 n->state = S_RECONNECT_ATS; 3085 set_state_and_timeout (n, S_RECONNECT_ATS, GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2954 n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT);
2955 // FIXME: need to ask ATS for suggestions again?
2956 n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, &n->id);
2957 break; 3086 break;
2958 case S_CONNECTED_SWITCHING_BLACKLIST: 3087 case S_CONNECTED_SWITCHING_BLACKLIST:
2959 /* primary went down while we were checking secondary against 3088 /* primary went down while we were checking secondary against
2960 blacklist, adopt secondary as primary */ 3089 blacklist, adopt secondary as primary */
2961 n->state = S_RECONNECT_BLACKLIST;
2962 free_address (&n->primary_address); 3090 free_address (&n->primary_address);
3091 set_state_and_timeout (n, S_RECONNECT_BLACKLIST, GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
2963 n->primary_address = n->alternative_address; 3092 n->primary_address = n->alternative_address;
2964 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); 3093 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress));
2965 n->timeout = GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT);
2966 break; 3094 break;
2967 case S_CONNECTED_SWITCHING_CONNECT_SENT: 3095 case S_CONNECTED_SWITCHING_CONNECT_SENT:
2968 /* primary went down while we were waiting for CONNECT_ACK on secondary; 3096 /* primary went down while we were waiting for CONNECT_ACK on secondary;
2969 secondary as primary */ 3097 secondary as primary */
2970 n->state = S_RECONNECT_SENT;
2971 free_address (&n->primary_address); 3098 free_address (&n->primary_address);
2972 n->primary_address = n->alternative_address; 3099 n->primary_address = n->alternative_address;
2973 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); 3100 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress));
2974 n->timeout = GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT); 3101 set_state_and_timeout (n, S_RECONNECT_SENT, GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
2975 break; 3102 break;
2976 case S_DISCONNECT: 3103 case S_DISCONNECT:
2977 free_address (&n->primary_address); 3104 free_address (&n->primary_address);
@@ -3047,8 +3174,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3047 GNUNET_NO); 3174 GNUNET_NO);
3048 return GNUNET_OK; 3175 return GNUNET_OK;
3049 } 3176 }
3050 n->state = S_CONNECTED; 3177 set_state_and_timeout (n, S_CONNECTED, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3051 n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
3052 GNUNET_STATISTICS_set (GST_stats, 3178 GNUNET_STATISTICS_set (GST_stats,
3053 gettext_noop ("# peers connected"), 3179 gettext_noop ("# peers connected"),
3054 ++neighbours_connected, 3180 ++neighbours_connected,
@@ -3060,7 +3186,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3060 GST_ats_add_address (n->primary_address.address, 3186 GST_ats_add_address (n->primary_address.address,
3061 n->primary_address.session, 3187 n->primary_address.session,
3062 NULL, 0); 3188 NULL, 0);
3063 set_address (&n->primary_address, 3189 set_primary_address (n,
3064 n->primary_address.address, 3190 n->primary_address.address,
3065 n->primary_address.session, 3191 n->primary_address.session,
3066 n->primary_address.bandwidth_in, 3192 n->primary_address.bandwidth_in,
@@ -3379,13 +3505,13 @@ void
3379GST_neighbours_start (void *cls, 3505GST_neighbours_start (void *cls,
3380 NotifyConnect connect_cb, 3506 NotifyConnect connect_cb,
3381 GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, 3507 GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb,
3382 GNUNET_TRANSPORT_AddressChangeCallback peer_address_cb, 3508 GNUNET_TRANSPORT_NeighbourChangeCallback peer_address_cb,
3383 unsigned int max_fds) 3509 unsigned int max_fds)
3384{ 3510{
3385 callback_cls = cls; 3511 callback_cls = cls;
3386 connect_notify_cb = connect_cb; 3512 connect_notify_cb = connect_cb;
3387 disconnect_notify_cb = disconnect_cb; 3513 disconnect_notify_cb = disconnect_cb;
3388 address_change_cb = peer_address_cb; 3514 neighbour_change_cb = peer_address_cb;
3389 neighbours = GNUNET_CONTAINER_multipeermap_create (NEIGHBOUR_TABLE_SIZE, GNUNET_NO); 3515 neighbours = GNUNET_CONTAINER_multipeermap_create (NEIGHBOUR_TABLE_SIZE, GNUNET_NO);
3390 util_transmission_tk = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL, 3516 util_transmission_tk = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL,
3391 utilization_transmission, NULL); 3517 utilization_transmission, NULL);
@@ -3410,7 +3536,7 @@ disconnect_all_neighbours (void *cls,
3410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3411 "Disconnecting peer `%4s', %s\n", 3537 "Disconnecting peer `%4s', %s\n",
3412 GNUNET_i2s (&n->id), "SHUTDOWN_TASK"); 3538 GNUNET_i2s (&n->id), "SHUTDOWN_TASK");
3413 n->state = S_DISCONNECT_FINISHED; 3539 set_state (n, S_DISCONNECT_FINISHED);
3414 free_neighbour (n, GNUNET_NO); 3540 free_neighbour (n, GNUNET_NO);
3415 return GNUNET_OK; 3541 return GNUNET_OK;
3416} 3542}
@@ -3438,7 +3564,7 @@ GST_neighbours_stop ()
3438 callback_cls = NULL; 3564 callback_cls = NULL;
3439 connect_notify_cb = NULL; 3565 connect_notify_cb = NULL;
3440 disconnect_notify_cb = NULL; 3566 disconnect_notify_cb = NULL;
3441 address_change_cb = NULL; 3567 neighbour_change_cb = NULL;
3442} 3568}
3443 3569
3444 3570
diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h
index 2e0e4e692..01fbe83d7 100644
--- a/src/transport/gnunet-service-transport_neighbours.h
+++ b/src/transport/gnunet-service-transport_neighbours.h
@@ -51,7 +51,7 @@ void
51GST_neighbours_start (void *cls, 51GST_neighbours_start (void *cls,
52 NotifyConnect connect_cb, 52 NotifyConnect connect_cb,
53 GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, 53 GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb,
54 GNUNET_TRANSPORT_AddressChangeCallback peer_address_cb, 54 GNUNET_TRANSPORT_NeighbourChangeCallback peer_address_cb,
55 unsigned int max_fds); 55 unsigned int max_fds);
56 56
57 57
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index d56aac8ad..c86bf67ff 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -264,10 +264,6 @@ struct ValidationEntry
264 */ 264 */
265 int expecting_pong; 265 int expecting_pong;
266 266
267 /* FIXME: DEBUGGING */
268 int last_line_set_to_no;
269 int last_line_set_to_yes;
270
271 enum GNUNET_ATS_Network_Type network; 267 enum GNUNET_ATS_Network_Type network;
272}; 268};
273 269
@@ -720,8 +716,6 @@ find_validation_entry (const struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
720 return NULL; 716 return NULL;
721 ve = GNUNET_new (struct ValidationEntry); 717 ve = GNUNET_new (struct ValidationEntry);
722 ve->in_use = GNUNET_SYSERR; /* not defined */ 718 ve->in_use = GNUNET_SYSERR; /* not defined */
723 ve->last_line_set_to_no = 0;
724 ve->last_line_set_to_yes = 0;
725 ve->address = GNUNET_HELLO_address_copy (address); 719 ve->address = GNUNET_HELLO_address_copy (address);
726 ve->public_key = *public_key; 720 ve->public_key = *public_key;
727 ve->pid = address->peer; 721 ve->pid = address->peer;
@@ -1526,13 +1520,11 @@ GST_validation_get_addresses (const struct GNUNET_PeerIdentity *target,
1526 * @param session the session 1520 * @param session the session
1527 * @param in_use #GNUNET_YES if we are now using the address for a connection, 1521 * @param in_use #GNUNET_YES if we are now using the address for a connection,
1528 * #GNUNET_NO if we are no longer using the address for a connection 1522 * #GNUNET_NO if we are no longer using the address for a connection
1529 * @param line line of caller just for DEBUGGING!
1530 */ 1523 */
1531void 1524void
1532GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, 1525GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address,
1533 struct Session *session, 1526 struct Session *session,
1534 int in_use, 1527 int in_use)
1535 int line)
1536{ 1528{
1537 struct ValidationEntry *ve; 1529 struct ValidationEntry *ve;
1538 1530
@@ -1551,28 +1543,17 @@ GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address,
1551 if (GNUNET_YES == in_use) 1543 if (GNUNET_YES == in_use)
1552 { 1544 {
1553 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1545 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1554 "Error setting address in use for peer `%s' `%s' to USED: set last time by %i, called now by %i\n", 1546 "Error setting address in use for peer `%s' `%s' to USED\n",
1555 GNUNET_i2s (&address->peer), GST_plugins_a2s (address), 1547 GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
1556 ve->last_line_set_to_yes, line);
1557 } 1548 }
1558 if (GNUNET_NO == in_use) 1549 if (GNUNET_NO == in_use)
1559 { 1550 {
1560 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1551 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1561 "Error setting address in use for peer `%s' `%s' to NOT_USED: set last time by %i, called now by %i\n", 1552 "Error setting address in use for peer `%s' `%s' to NOT_USED\n",
1562 GNUNET_i2s (&address->peer), GST_plugins_a2s (address), 1553 GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
1563 ve->last_line_set_to_no, line);
1564 } 1554 }
1565 } 1555 }
1566 1556
1567 if (GNUNET_YES == in_use)
1568 {
1569 ve->last_line_set_to_yes = line;
1570 }
1571 if (GNUNET_NO == in_use)
1572 {
1573 ve->last_line_set_to_no = line;
1574 }
1575
1576 GNUNET_break (ve->in_use != in_use); /* should be different... */ 1557 GNUNET_break (ve->in_use != in_use); /* should be different... */
1577 ve->in_use = in_use; 1558 ve->in_use = in_use;
1578 if (in_use == GNUNET_YES) 1559 if (in_use == GNUNET_YES)
diff --git a/src/transport/gnunet-service-transport_validation.h b/src/transport/gnunet-service-transport_validation.h
index c37484f13..e07afc409 100644
--- a/src/transport/gnunet-service-transport_validation.h
+++ b/src/transport/gnunet-service-transport_validation.h
@@ -57,13 +57,11 @@ GST_validation_stop (void);
57 * @param session the session 57 * @param session the session
58 * @param in_use GNUNET_YES if we are now using the address for a connection, 58 * @param in_use GNUNET_YES if we are now using the address for a connection,
59 * GNUNET_NO if we are no longer using the address for a connection 59 * GNUNET_NO if we are no longer using the address for a connection
60 * @param line line of caller just for DEBUGGING!
61 */ 60 */
62void 61void
63GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, 62GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address,
64 struct Session *session, 63 struct Session *session,
65 int in_use, 64 int in_use);
66 int line);
67 65
68 66
69/** 67/**
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 {
diff --git a/src/transport/transport.h b/src/transport/transport.h
index 43504ec2b..beea4031e 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -441,7 +441,7 @@ struct TrafficMetricMessage
441struct PeerIterateResponseMessage 441struct PeerIterateResponseMessage
442{ 442{
443 /** 443 /**
444 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE 444 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE
445 */ 445 */
446 struct GNUNET_MessageHeader header; 446 struct GNUNET_MessageHeader header;
447 447
diff --git a/src/transport/transport_api_address_to_string.c b/src/transport/transport_api_address_to_string.c
index 0fb0623dc..0cf0111b3 100644
--- a/src/transport/transport_api_address_to_string.c
+++ b/src/transport/transport_api_address_to_string.c
@@ -170,15 +170,15 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle
170/** 170/**
171 * Cancel request for address conversion. 171 * Cancel request for address conversion.
172 * 172 *
173 * @param alc handle for the request to cancel 173 * @param pic the context handle
174 */ 174 */
175void 175void
176GNUNET_TRANSPORT_address_to_string_cancel (struct 176GNUNET_TRANSPORT_address_to_string_cancel (struct
177 GNUNET_TRANSPORT_AddressToStringContext 177 GNUNET_TRANSPORT_AddressToStringContext
178 *alc) 178 *pic)
179{ 179{
180 GNUNET_CLIENT_disconnect (alc->client); 180 GNUNET_CLIENT_disconnect (pic->client);
181 GNUNET_free (alc); 181 GNUNET_free (pic);
182} 182}
183 183
184 184
diff --git a/src/transport/transport_api_monitoring.c b/src/transport/transport_api_monitoring.c
index bfbe1d0a1..746dd47bb 100644
--- a/src/transport/transport_api_monitoring.c
+++ b/src/transport/transport_api_monitoring.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file transport/transport_api_montoring.c 22 * @file transport/transport_api_monitoring.c
23 * @brief montoring api for transport peer status and validation entries 23 * @brief montoring api for transport peer status and validation entries
24 * 24 *
25 * This api provides the ability to query the transport service about 25 * This api provides the ability to query the transport service about
@@ -450,16 +450,16 @@ peer_response_processor (void *cls,
450 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), 450 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL),
451 * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled) 451 * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled)
452 * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO) 452 * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO)
453 * @param peer_address_callback function to call with the results 453 * @param peer_callback function to call with the results
454 * @param peer_address_callback_cls closure for peer_address_callback 454 * @param peer_callback_cls closure for peer_address_callback
455 */ 455 */
456struct GNUNET_TRANSPORT_PeerMonitoringContext * 456struct GNUNET_TRANSPORT_PeerMonitoringContext *
457GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, 457GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
458 const struct GNUNET_PeerIdentity *peer, 458 const struct GNUNET_PeerIdentity *peer,
459 int one_shot, 459 int one_shot,
460 struct GNUNET_TIME_Relative timeout, 460 struct GNUNET_TIME_Relative timeout,
461 GNUNET_TRANSPORT_PeerIterateCallback peer_address_callback, 461 GNUNET_TRANSPORT_PeerIterateCallback peer_callback,
462 void *peer_address_callback_cls) 462 void *peer_callback_cls)
463{ 463{
464 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx; 464 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx;
465 struct GNUNET_CLIENT_Connection *client; 465 struct GNUNET_CLIENT_Connection *client;
@@ -470,8 +470,8 @@ GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
470 if (GNUNET_YES != one_shot) 470 if (GNUNET_YES != one_shot)
471 timeout = GNUNET_TIME_UNIT_FOREVER_REL; 471 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
472 pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext); 472 pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext);
473 pal_ctx->cb = peer_address_callback; 473 pal_ctx->cb = peer_callback;
474 pal_ctx->cb_cls = peer_address_callback_cls; 474 pal_ctx->cb_cls = peer_callback_cls;
475 pal_ctx->cfg = cfg; 475 pal_ctx->cfg = cfg;
476 pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); 476 pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
477 if (NULL != peer) 477 if (NULL != peer)
@@ -485,30 +485,30 @@ GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
485 485
486 486
487/** 487/**
488 * Cancel request for address conversion. 488 * Cancel request to monitor peers
489 * 489 *
490 * @param alc handle for the request to cancel 490 * @param pic handle for the request to cancel
491 */ 491 */
492void 492void
493GNUNET_TRANSPORT_monitor_peers_cancel ( 493GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic)
494 struct GNUNET_TRANSPORT_PeerMonitoringContext *alc)
495{ 494{
496 if (NULL != alc->client) 495 if (NULL != pic->client)
497 { 496 {
498 GNUNET_CLIENT_disconnect (alc->client); 497 GNUNET_CLIENT_disconnect (pic->client);
499 alc->client = NULL; 498 pic->client = NULL;
500 } 499 }
501 if (GNUNET_SCHEDULER_NO_TASK != alc->reconnect_task) 500 if (GNUNET_SCHEDULER_NO_TASK != pic->reconnect_task)
502 { 501 {
503 GNUNET_SCHEDULER_cancel (alc->reconnect_task); 502 GNUNET_SCHEDULER_cancel (pic->reconnect_task);
504 alc->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 503 pic->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
505 } 504 }
506 GNUNET_free (alc); 505 GNUNET_free (pic);
507} 506}
508 507
509 508
510/** 509/**
511 * Return information about a peer's or all current pending validation operations 510 * Return information about pending address validation operations for a specific
511 * or all peers
512 * 512 *
513 * @param cfg configuration to use 513 * @param cfg configuration to use
514 * @param peer a specific peer identity to obtain validation entries for, 514 * @param peer a specific peer identity to obtain validation entries for,
@@ -516,8 +516,8 @@ GNUNET_TRANSPORT_monitor_peers_cancel (
516 * @param one_shot GNUNET_YES to return all entries and then end (with NULL+NULL), 516 * @param one_shot GNUNET_YES to return all entries and then end (with NULL+NULL),
517 * GNUNET_NO to monitor validation entries continuously 517 * GNUNET_NO to monitor validation entries continuously
518 * @param timeout how long is the lookup allowed to take at most 518 * @param timeout how long is the lookup allowed to take at most
519 * @param peer_address_callback function to call with the results 519 * @param validation_callback function to call with the results
520 * @param peer_address_callback_cls closure for peer_address_callback 520 * @param validation_callback_cls closure for peer_address_callback
521 */ 521 */
522struct GNUNET_TRANSPORT_ValidationMonitoringContext * 522struct GNUNET_TRANSPORT_ValidationMonitoringContext *
523GNUNET_TRANSPORT_monitor_validation_entries (const struct 523GNUNET_TRANSPORT_monitor_validation_entries (const struct
@@ -545,4 +545,4 @@ GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_Vali
545} 545}
546 546
547 547
548/* end of transport_api_montoring.c */ 548/* end of transport_api_monitoring.c */