aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-01-15 17:18:11 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-01-15 17:18:11 +0000
commit2368c95a00afc72a8f03ab67bca1ff41328eecdf (patch)
tree3bcbc29808d7e91c85ca60ac5c998374b458862e /src
parentb0144a11f14f33ab010fd7cf8c61bdd361f20fd3 (diff)
downloadgnunet-2368c95a00afc72a8f03ab67bca1ff41328eecdf.tar.gz
gnunet-2368c95a00afc72a8f03ab67bca1ff41328eecdf.zip
transport validation monitoring API (not yet complete) + CLI
+ fix for crash in transport/plugin_transport_udp.c
Diffstat (limited to 'src')
-rw-r--r--src/transport/Makefile.am13
-rw-r--r--src/transport/gnunet-service-transport.c34
-rw-r--r--src/transport/gnunet-service-transport_clients.c326
-rw-r--r--src/transport/gnunet-service-transport_clients.h9
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c36
-rw-r--r--src/transport/gnunet-service-transport_validation.c100
-rw-r--r--src/transport/gnunet-service-transport_validation.h30
-rw-r--r--src/transport/gnunet-transport.c37
-rw-r--r--src/transport/plugin_transport_udp.c2
-rw-r--r--src/transport/test_transport_api_monitoring.c20
-rw-r--r--src/transport/test_transport_api_monitoring_validation_peer1.conf6
-rw-r--r--src/transport/test_transport_api_monitoring_validation_peer2.conf7
-rw-r--r--src/transport/transport.h71
-rw-r--r--src/transport/transport_api_monitoring.c270
14 files changed, 864 insertions, 97 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 76dc50af9..acfaa9403 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -408,6 +408,7 @@ check_PROGRAMS = \
408 $(BT_TIMEOUT_TEST) \ 408 $(BT_TIMEOUT_TEST) \
409 test_transport_api_multi \ 409 test_transport_api_multi \
410 test_transport_api_monitoring \ 410 test_transport_api_monitoring \
411 test_transport_api_monitoring_validation \
411 test_transport_blacklisting_no_bl \ 412 test_transport_blacklisting_no_bl \
412 test_transport_blacklisting_outbound_bl_full \ 413 test_transport_blacklisting_outbound_bl_full \
413 test_transport_blacklisting_outbound_bl_plugin \ 414 test_transport_blacklisting_outbound_bl_plugin \
@@ -473,6 +474,7 @@ TESTS = \
473 $(BT_TIMEOUT_TEST) \ 474 $(BT_TIMEOUT_TEST) \
474 test_transport_api_multi \ 475 test_transport_api_multi \
475 test_transport_api_monitoring \ 476 test_transport_api_monitoring \
477 test_transport_api_monitoring_validation \
476 test_transport_blacklisting_no_bl \ 478 test_transport_blacklisting_no_bl \
477 test_transport_blacklisting_outbound_bl_full \ 479 test_transport_blacklisting_outbound_bl_full \
478 test_transport_blacklisting_outbound_bl_plugin \ 480 test_transport_blacklisting_outbound_bl_plugin \
@@ -1100,7 +1102,6 @@ test_transport_api_multi_LDADD = \
1100 $(top_builddir)/src/util/libgnunetutil.la \ 1102 $(top_builddir)/src/util/libgnunetutil.la \
1101 $(top_builddir)/src/transport/libgnunettransporttesting.la 1103 $(top_builddir)/src/transport/libgnunettransporttesting.la
1102 1104
1103
1104test_transport_api_monitoring_SOURCES = \ 1105test_transport_api_monitoring_SOURCES = \
1105 test_transport_api_monitoring.c 1106 test_transport_api_monitoring.c
1106test_transport_api_monitoring_LDADD = \ 1107test_transport_api_monitoring_LDADD = \
@@ -1109,6 +1110,14 @@ test_transport_api_monitoring_LDADD = \
1109 $(top_builddir)/src/util/libgnunetutil.la \ 1110 $(top_builddir)/src/util/libgnunetutil.la \
1110 $(top_builddir)/src/transport/libgnunettransporttesting.la 1111 $(top_builddir)/src/transport/libgnunettransporttesting.la
1111 1112
1113test_transport_api_monitoring_validation_SOURCES = \
1114 test_transport_api_monitoring_validation.c
1115test_transport_api_monitoring_validation_LDADD = \
1116 $(top_builddir)/src/transport/libgnunettransport.la \
1117 $(top_builddir)/src/hello/libgnunethello.la \
1118 $(top_builddir)/src/util/libgnunetutil.la \
1119 $(top_builddir)/src/transport/libgnunettransporttesting.la
1120
1112 1121
1113EXTRA_DIST = \ 1122EXTRA_DIST = \
1114test_plugin_hostkey \ 1123test_plugin_hostkey \
@@ -1207,6 +1216,8 @@ test_transport_api_bluetooth_peer1.conf\
1207test_transport_api_bluetooth_peer2.conf\ 1216test_transport_api_bluetooth_peer2.conf\
1208test_transport_api_monitoring_peer1.conf\ 1217test_transport_api_monitoring_peer1.conf\
1209test_transport_api_monitoring_peer2.conf\ 1218test_transport_api_monitoring_peer2.conf\
1219test_transport_api_monitoring_validation_peer1.conf\
1220test_transport_api_monitoring_validation_peer2.conf\
1210test_transport_defaults.conf\ 1221test_transport_defaults.conf\
1211test_transport_startonly.conf\ 1222test_transport_startonly.conf\
1212test_transport_api_disconnect_tcp_peer1.conf\ 1223test_transport_api_disconnect_tcp_peer1.conf\
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index d52d6ab69..66f177145 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -764,13 +764,43 @@ neighbours_changed_notification (void *cls,
764 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n", 764 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n",
765 GNUNET_i2s (peer), 765 GNUNET_i2s (peer),
766 (NULL != address) ? GST_plugins_a2s (address) : "<none>", 766 (NULL != address) ? GST_plugins_a2s (address) : "<none>",
767 GNUNET_TRANSPORT_p2s (state), 767 GNUNET_TRANSPORT_ps2s (state),
768 GNUNET_STRINGS_absolute_time_to_string (state_timeout)); 768 GNUNET_STRINGS_absolute_time_to_string (state_timeout));
769 769
770 GST_clients_broadcast_peer_notification (peer, address, state, state_timeout); 770 GST_clients_broadcast_peer_notification (peer, address, state, state_timeout);
771} 771}
772 772
773/** 773/**
774 * Function called to notify transport users that a neighbour peer changed its
775 * active address.
776 *
777 * @param cls closure
778 * @param peer peer this update is about (never NULL)
779 * @param address address, NULL on disconnect
780 * @param state current state this peer is in
781 * @param state_timeout timeout for the current state of the peer
782 * @param bandwidth_in bandwidth assigned inbound
783 * @param bandwidth_out bandwidth assigned outbound
784 */
785static void
786validation_changed_notification (void *cls,
787 const struct GNUNET_PeerIdentity *peer,
788 const struct GNUNET_HELLO_Address *address,
789 struct GNUNET_TIME_Absolute last_validation,
790 struct GNUNET_TIME_Absolute valid_until,
791 struct GNUNET_TIME_Absolute next_validation,
792 enum GNUNET_TRANSPORT_ValidationState state)
793{
794 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
795 "Notifying about change for for validation entry for peer `%s' with address `%s'\n",
796 GNUNET_i2s (peer),
797 (NULL != address) ? GST_plugins_a2s (address) : "<none>");
798
799 GST_clients_broadcast_validation_notification (peer, address,
800 last_validation, valid_until, next_validation, state);
801}
802
803/**
774 * Function called when the service shuts down. Unloads our plugins 804 * Function called when the service shuts down. Unloads our plugins
775 * and cancels pending validations. 805 * and cancels pending validations.
776 * 806 *
@@ -918,7 +948,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
918 &neighbours_disconnect_notification, &neighbours_changed_notification, 948 &neighbours_disconnect_notification, &neighbours_changed_notification,
919 (max_fd / 3) * 2); 949 (max_fd / 3) * 2);
920 GST_clients_start (GST_server); 950 GST_clients_start (GST_server);
921 GST_validation_start ((max_fd / 3)); 951 GST_validation_start (&validation_changed_notification, NULL, (max_fd / 3));
922} 952}
923 953
924/** 954/**
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c
index ca7a40539..fb848d0af 100644
--- a/src/transport/gnunet-service-transport_clients.c
+++ b/src/transport/gnunet-service-transport_clients.c
@@ -190,19 +190,34 @@ struct AddressToStringContext *a2s_tail;
190/** 190/**
191 * Head of linked list of monitoring clients. 191 * Head of linked list of monitoring clients.
192 */ 192 */
193static struct MonitoringClient *monitoring_clients_head; 193static struct MonitoringClient *peer_monitoring_clients_head;
194 194
195/** 195/**
196 * Tail of linked list of monitoring clients. 196 * Tail of linked list of monitoring clients.
197 */ 197 */
198static struct MonitoringClient *monitoring_clients_tail; 198static struct MonitoringClient *peer_monitoring_clients_tail;
199
200/**
201 * Head of linked list of validation monitoring clients.
202 */
203static struct MonitoringClient *val_monitoring_clients_head;
204
205/**
206 * Tail of linked list of validation monitoring clients.
207 */
208static struct MonitoringClient *val_monitoring_clients_tail;
199 209
200/** 210/**
201 * Notification context, to send updates on changes to active addresses 211 * Notification context, to send updates on changes to active addresses
202 * of our neighbours. 212 * of our neighbours.
203 */ 213 */
204static struct GNUNET_SERVER_NotificationContext *nc; 214static struct GNUNET_SERVER_NotificationContext *peer_nc;
205 215
216/**
217 * Notification context, to send updates on changes to active addresses
218 * of our neighbours.
219 */
220static struct GNUNET_SERVER_NotificationContext *val_nc;
206 221
207/** 222/**
208 * Find the internal handle associated with the given client handle 223 * Find the internal handle associated with the given client handle
@@ -251,11 +266,12 @@ setup_client (struct GNUNET_SERVER_Client *client)
251 * @return handle to the monitoring client 266 * @return handle to the monitoring client
252 */ 267 */
253static struct MonitoringClient * 268static struct MonitoringClient *
254lookup_monitoring_client (struct GNUNET_SERVER_Client *client) 269lookup_monitoring_client (struct MonitoringClient *head,
270 struct GNUNET_SERVER_Client *client)
255{ 271{
256 struct MonitoringClient *mc; 272 struct MonitoringClient *mc;
257 273
258 for (mc = monitoring_clients_head; NULL != mc; mc = mc->next) 274 for (mc = head; NULL != mc; mc = mc->next)
259 if (mc->client == client) 275 if (mc->client == client)
260 return mc; 276 return mc;
261 return NULL; 277 return NULL;
@@ -272,27 +288,58 @@ lookup_monitoring_client (struct GNUNET_SERVER_Client *client)
272 * @return handle to the new monitoring client 288 * @return handle to the new monitoring client
273 */ 289 */
274static struct MonitoringClient * 290static struct MonitoringClient *
275setup_monitoring_client (struct GNUNET_SERVER_Client *client, 291setup_peer_monitoring_client (struct GNUNET_SERVER_Client *client,
276 struct GNUNET_PeerIdentity *peer) 292 struct GNUNET_PeerIdentity *peer)
277{ 293{
278 struct MonitoringClient *mc; 294 struct MonitoringClient *mc;
279 static struct GNUNET_PeerIdentity all_zeros; 295 static struct GNUNET_PeerIdentity all_zeros;
280 296
281 GNUNET_assert (lookup_monitoring_client (client) == NULL); 297 GNUNET_assert (lookup_monitoring_client (peer_monitoring_clients_head, client) == NULL);
282 mc = GNUNET_new (struct MonitoringClient); 298 mc = GNUNET_new (struct MonitoringClient);
283 mc->client = client; 299 mc->client = client;
284 mc->peer = *peer; 300 mc->peer = *peer;
285 GNUNET_CONTAINER_DLL_insert (monitoring_clients_head, 301 GNUNET_CONTAINER_DLL_insert (peer_monitoring_clients_head, peer_monitoring_clients_tail, mc);
286 monitoring_clients_tail, 302 GNUNET_SERVER_notification_context_add (peer_nc, client);
287 mc);
288 GNUNET_SERVER_notification_context_add (nc, client);
289 303
290 if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity))) 304 if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 305 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
292 "Client %p started monitoring of the peer `%s'\n", 306 "Client %p started monitoring of the peer `%s'\n",
293 mc, GNUNET_i2s (peer)); 307 mc, GNUNET_i2s (peer));
294 else 308 else
295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 309 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
310 "Client %p started monitoring all peers\n", mc);
311 return mc;
312}
313
314/**
315 * Setup a new monitoring client using the given server client handle and
316 * the peer identity.
317 *
318 * @param client server's client handle to create our internal handle for
319 * @param peer identity of the peer to monitor the addresses of,
320 * zero to monitor all neighrours.
321 * @return handle to the new monitoring client
322 */
323static struct MonitoringClient *
324setup_val_monitoring_client (struct GNUNET_SERVER_Client *client,
325 struct GNUNET_PeerIdentity *peer)
326{
327 struct MonitoringClient *mc;
328 static struct GNUNET_PeerIdentity all_zeros;
329
330 GNUNET_assert (lookup_monitoring_client (val_monitoring_clients_head, client) == NULL);
331 mc = GNUNET_new (struct MonitoringClient);
332 mc->client = client;
333 mc->peer = *peer;
334 GNUNET_CONTAINER_DLL_insert (val_monitoring_clients_head, val_monitoring_clients_tail, mc);
335 GNUNET_SERVER_notification_context_add (val_nc, client);
336
337 if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
338 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
339 "Client %p started monitoring of the peer `%s'\n",
340 mc, GNUNET_i2s (peer));
341 else
342 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
296 "Client %p started monitoring all peers\n", mc); 343 "Client %p started monitoring all peers\n", mc);
297 return mc; 344 return mc;
298} 345}
@@ -425,11 +472,19 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
425 472
426 if (client == NULL) 473 if (client == NULL)
427 return; 474 return;
428 mc = lookup_monitoring_client (client); 475 mc = lookup_monitoring_client (peer_monitoring_clients_head, client);
429 if (mc != NULL) 476 if (mc != NULL)
430 { 477 {
431 GNUNET_CONTAINER_DLL_remove (monitoring_clients_head, 478 GNUNET_CONTAINER_DLL_remove (peer_monitoring_clients_head,
432 monitoring_clients_tail, 479 peer_monitoring_clients_tail,
480 mc);
481 GNUNET_free (mc);
482 }
483 mc = lookup_monitoring_client (val_monitoring_clients_head, client);
484 if (mc != NULL)
485 {
486 GNUNET_CONTAINER_DLL_remove (val_monitoring_clients_head,
487 val_monitoring_clients_tail,
433 mc); 488 mc);
434 GNUNET_free (mc); 489 GNUNET_free (mc);
435 } 490 }
@@ -852,7 +907,7 @@ clients_handle_address_to_string (void *cls,
852 907
853 908
854/** 909/**
855 * Compose AddressIterateResponseMessage using the given peer and address. 910 * Compose #PeerIterateResponseMessage using the given peer and address.
856 * 911 *
857 * @param peer identity of the peer 912 * @param peer identity of the peer
858 * @param address the address, NULL on disconnect 913 * @param address the address, NULL on disconnect
@@ -896,8 +951,52 @@ compose_address_iterate_response_message (const struct GNUNET_PeerIdentity *peer
896 return msg; 951 return msg;
897} 952}
898 953
954/**
955 * Compose #PeerIterateResponseMessage using the given peer and address.
956 *
957 * @param peer identity of the peer
958 * @param address the address, NULL on disconnect
959 * @return composed message
960 */
961static struct ValidationIterateResponseMessage *
962compose_validation_iterate_response_message (const struct GNUNET_PeerIdentity *peer,
963 const struct GNUNET_HELLO_Address *address)
964{
965 struct ValidationIterateResponseMessage *msg;
966 size_t size;
967 size_t tlen;
968 size_t alen;
969 char *addr;
970
971 GNUNET_assert (NULL != peer);
972 if (NULL != address)
973 {
974 tlen = strlen (address->transport_name) + 1;
975 alen = address->address_length;
976 }
977 else
978 tlen = alen = 0;
979 size = (sizeof (struct ValidationIterateResponseMessage) + alen + tlen);
980 msg = GNUNET_malloc (size);
981 msg->header.size = htons (size);
982 msg->header.type =
983 htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);
984 msg->reserved = htonl (0);
985 msg->peer = *peer;
986 msg->addrlen = htonl (alen);
987 msg->pluginlen = htonl (tlen);
988
989 if (NULL != address)
990 {
991 msg->local_address_info = htonl((uint32_t) address->local_info);
992 addr = (char *) &msg[1];
993 memcpy (addr, address->address, alen);
994 memcpy (&addr[alen], address->transport_name, tlen);
995 }
996 return msg;
997}
899 998
900struct PeerIterationContext 999struct IterationContext
901{ 1000{
902 struct GNUNET_SERVER_TransmitContext *tc; 1001 struct GNUNET_SERVER_TransmitContext *tc;
903 1002
@@ -918,6 +1017,46 @@ struct PeerIterationContext
918 * @param bandwidth_out outbound quota in NBO 1017 * @param bandwidth_out outbound quota in NBO
919 */ 1018 */
920static void 1019static void
1020send_validation_information (void *cls,
1021 const struct GNUNET_PeerIdentity *peer,
1022 const struct GNUNET_HELLO_Address *address,
1023 struct GNUNET_TIME_Absolute last_validation,
1024 struct GNUNET_TIME_Absolute valid_until,
1025 struct GNUNET_TIME_Absolute next_validation,
1026 enum GNUNET_TRANSPORT_ValidationState state)
1027{
1028 struct IterationContext *pc = cls;
1029 struct ValidationIterateResponseMessage *msg;
1030
1031 if ( (GNUNET_YES == pc->all) ||
1032 (0 == memcmp (peer, &pc->id, sizeof (pc->id))) )
1033 {
1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1035 "Sending information about for validation entry for peer `%s' using address `%s'\n",
1036 GNUNET_i2s(peer), (address != NULL) ? GST_plugins_a2s (address) : "<none>");
1037 msg = compose_validation_iterate_response_message (peer, address);
1038 msg->last_validation = GNUNET_TIME_absolute_hton(last_validation);
1039 msg->valid_until = GNUNET_TIME_absolute_hton(valid_until);
1040 msg->next_validation = GNUNET_TIME_absolute_hton(next_validation);
1041 msg->state = htonl ((uint32_t) state);
1042 GNUNET_SERVER_transmit_context_append_message (pc->tc, &msg->header);
1043 GNUNET_free (msg);
1044 }
1045}
1046
1047
1048/**
1049 * Output information of neighbours to the given client.
1050 *
1051 * @param cls the 'struct PeerIterationContext'
1052 * @param peer identity of the neighbour
1053 * @param address the address
1054 * @param state current state this peer is in
1055 * @param state_timeout timeout for the current state of the peer
1056 * @param bandwidth_in inbound quota in NBO
1057 * @param bandwidth_out outbound quota in NBO
1058 */
1059static void
921send_peer_information (void *cls, 1060send_peer_information (void *cls,
922 const struct GNUNET_PeerIdentity *peer, 1061 const struct GNUNET_PeerIdentity *peer,
923 const struct GNUNET_HELLO_Address *address, 1062 const struct GNUNET_HELLO_Address *address,
@@ -926,7 +1065,7 @@ send_peer_information (void *cls,
926 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 1065 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
927 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 1066 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
928{ 1067{
929 struct PeerIterationContext *pc = cls; 1068 struct IterationContext *pc = cls;
930 struct PeerIterateResponseMessage *msg; 1069 struct PeerIterateResponseMessage *msg;
931 1070
932 if ( (GNUNET_YES == pc->all) || 1071 if ( (GNUNET_YES == pc->all) ||
@@ -936,7 +1075,7 @@ send_peer_information (void *cls,
936 "Sending information about `%s' using address `%s' in state `%s'\n", 1075 "Sending information about `%s' using address `%s' in state `%s'\n",
937 GNUNET_i2s(peer), 1076 GNUNET_i2s(peer),
938 (address != NULL) ? GST_plugins_a2s (address) : "<none>", 1077 (address != NULL) ? GST_plugins_a2s (address) : "<none>",
939 GNUNET_TRANSPORT_p2s (state)); 1078 GNUNET_TRANSPORT_ps2s (state));
940 msg = compose_address_iterate_response_message (peer, address); 1079 msg = compose_address_iterate_response_message (peer, address);
941 msg->state = htonl (state); 1080 msg->state = htonl (state);
942 msg->state_timeout = GNUNET_TIME_absolute_hton(state_timeout); 1081 msg->state_timeout = GNUNET_TIME_absolute_hton(state_timeout);
@@ -947,7 +1086,6 @@ send_peer_information (void *cls,
947 1086
948 1087
949 1088
950
951/** 1089/**
952 * Client asked to obtain information about a specific or all peers 1090 * Client asked to obtain information about a specific or all peers
953 * Process the request. 1091 * Process the request.
@@ -963,7 +1101,7 @@ clients_handle_monitor_peers (void *cls, struct GNUNET_SERVER_Client *client,
963 static struct GNUNET_PeerIdentity all_zeros; 1101 static struct GNUNET_PeerIdentity all_zeros;
964 struct GNUNET_SERVER_TransmitContext *tc; 1102 struct GNUNET_SERVER_TransmitContext *tc;
965 struct PeerMonitorMessage *msg; 1103 struct PeerMonitorMessage *msg;
966 struct PeerIterationContext pc; 1104 struct IterationContext pc;
967 1105
968 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST) 1106 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST)
969 { 1107 {
@@ -979,7 +1117,7 @@ clients_handle_monitor_peers (void *cls, struct GNUNET_SERVER_Client *client,
979 } 1117 }
980 msg = (struct PeerMonitorMessage *) message; 1118 msg = (struct PeerMonitorMessage *) message;
981 if ( (GNUNET_YES != ntohl (msg->one_shot)) && 1119 if ( (GNUNET_YES != ntohl (msg->one_shot)) &&
982 (NULL != lookup_monitoring_client (client)) ) 1120 (NULL != lookup_monitoring_client (peer_monitoring_clients_head, client)) )
983 { 1121 {
984 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 1122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
985 "ServerClient %p tried to start monitoring twice\n", 1123 "ServerClient %p tried to start monitoring twice\n",
@@ -1008,7 +1146,7 @@ clients_handle_monitor_peers (void *cls, struct GNUNET_SERVER_Client *client,
1008 1146
1009 if (GNUNET_YES != ntohl (msg->one_shot)) 1147 if (GNUNET_YES != ntohl (msg->one_shot))
1010 { 1148 {
1011 setup_monitoring_client (client, &msg->peer); 1149 setup_peer_monitoring_client (client, &msg->peer);
1012 } 1150 }
1013 else 1151 else
1014 { 1152 {
@@ -1021,6 +1159,78 @@ clients_handle_monitor_peers (void *cls, struct GNUNET_SERVER_Client *client,
1021 1159
1022 1160
1023/** 1161/**
1162 * Client asked to obtain information about a specific or all validation
1163 * processes
1164 *
1165 * @param cls unused
1166 * @param client the client
1167 * @param message the peer address information request
1168 */
1169static void
1170clients_handle_monitor_validation (void *cls, struct GNUNET_SERVER_Client *client,
1171 const struct GNUNET_MessageHeader *message)
1172{
1173 static struct GNUNET_PeerIdentity all_zeros;
1174 struct GNUNET_SERVER_TransmitContext *tc;
1175 struct PeerMonitorMessage *msg;
1176 struct IterationContext pc;
1177
1178 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_REQUEST)
1179 {
1180 GNUNET_break (0);
1181 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1182 return;
1183 }
1184 if (ntohs (message->size) != sizeof (struct ValidationMonitorMessage))
1185 {
1186 GNUNET_break (0);
1187 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1188 return;
1189 }
1190 msg = (struct PeerMonitorMessage *) message;
1191 if ( (GNUNET_YES != ntohl (msg->one_shot)) &&
1192 (NULL != lookup_monitoring_client (val_monitoring_clients_head, client)) )
1193 {
1194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1195 "ServerClient %p tried to start monitoring twice\n",
1196 client);
1197 GNUNET_break (0);
1198 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1199 return;
1200 }
1201 GNUNET_SERVER_disable_receive_done_warning (client);
1202 pc.tc = tc = GNUNET_SERVER_transmit_context_create (client);
1203
1204 /* Send initial list */
1205 if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
1206 {
1207 /* iterate over all neighbours */
1208 pc.all = GNUNET_YES;
1209 pc.id = msg->peer;
1210 }
1211 else
1212 {
1213 /* just return one neighbour */
1214 pc.all = GNUNET_NO;
1215 pc.id = msg->peer;
1216 }
1217
1218 GST_validation_iterate (&send_validation_information, &pc);
1219
1220 if (GNUNET_YES != ntohl (msg->one_shot))
1221 {
1222 GNUNET_break (0);
1223 setup_val_monitoring_client (client, &msg->peer);
1224 }
1225 else
1226 {
1227 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
1228 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
1229 }
1230 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
1231}
1232
1233/**
1024 * Start handling requests from clients. 1234 * Start handling requests from clients.
1025 * 1235 *
1026 * @param server server used to accept clients from. 1236 * @param server server used to accept clients from.
@@ -1043,6 +1253,9 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server)
1043 {&clients_handle_monitor_peers, NULL, 1253 {&clients_handle_monitor_peers, NULL,
1044 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST, 1254 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST,
1045 sizeof (struct PeerMonitorMessage)}, 1255 sizeof (struct PeerMonitorMessage)},
1256 {&clients_handle_monitor_validation, NULL,
1257 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_REQUEST,
1258 sizeof (struct ValidationMonitorMessage)},
1046 {&GST_blacklist_handle_init, NULL, 1259 {&GST_blacklist_handle_init, NULL,
1047 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT, 1260 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT,
1048 sizeof (struct GNUNET_MessageHeader)}, 1261 sizeof (struct GNUNET_MessageHeader)},
@@ -1053,7 +1266,8 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server)
1053 GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC, 0}, 1266 GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC, 0},
1054 {NULL, NULL, 0, 0} 1267 {NULL, NULL, 0, 0}
1055 }; 1268 };
1056 nc = GNUNET_SERVER_notification_context_create (server, 0); 1269 peer_nc = GNUNET_SERVER_notification_context_create (server, 0);
1270 val_nc = GNUNET_SERVER_notification_context_create (server, 0);
1057 GNUNET_SERVER_add_handlers (server, handlers); 1271 GNUNET_SERVER_add_handlers (server, handlers);
1058 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification, 1272 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification,
1059 NULL); 1273 NULL);
@@ -1074,10 +1288,15 @@ GST_clients_stop ()
1074 GNUNET_CONTAINER_DLL_remove (a2s_head, a2s_tail, cur); 1288 GNUNET_CONTAINER_DLL_remove (a2s_head, a2s_tail, cur);
1075 GNUNET_free (cur); 1289 GNUNET_free (cur);
1076 } 1290 }
1077 if (NULL != nc) 1291 if (NULL != peer_nc)
1292 {
1293 GNUNET_SERVER_notification_context_destroy (peer_nc);
1294 peer_nc = NULL;
1295 }
1296 if (NULL != val_nc)
1078 { 1297 {
1079 GNUNET_SERVER_notification_context_destroy (nc); 1298 GNUNET_SERVER_notification_context_destroy (val_nc);
1080 nc = NULL; 1299 val_nc = NULL;
1081 } 1300 }
1082} 1301}
1083 1302
@@ -1142,7 +1361,7 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
1142 msg = compose_address_iterate_response_message (peer, address); 1361 msg = compose_address_iterate_response_message (peer, address);
1143 msg->state = htonl (state); 1362 msg->state = htonl (state);
1144 msg->state_timeout = GNUNET_TIME_absolute_hton (state_timeout); 1363 msg->state_timeout = GNUNET_TIME_absolute_hton (state_timeout);
1145 mc = monitoring_clients_head; 1364 mc = peer_monitoring_clients_head;
1146 while (mc != NULL) 1365 while (mc != NULL)
1147 { 1366 {
1148 if ((0 == memcmp (&mc->peer, &all_zeros, 1367 if ((0 == memcmp (&mc->peer, &all_zeros,
@@ -1150,7 +1369,7 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
1150 (0 == memcmp (&mc->peer, peer, 1369 (0 == memcmp (&mc->peer, peer,
1151 sizeof (struct GNUNET_PeerIdentity)))) 1370 sizeof (struct GNUNET_PeerIdentity))))
1152 { 1371 {
1153 GNUNET_SERVER_notification_context_unicast (nc, mc->client, 1372 GNUNET_SERVER_notification_context_unicast (peer_nc, mc->client,
1154 &msg->header, GNUNET_NO); 1373 &msg->header, GNUNET_NO);
1155 } 1374 }
1156 1375
@@ -1159,5 +1378,52 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
1159 GNUNET_free (msg); 1378 GNUNET_free (msg);
1160} 1379}
1161 1380
1381/**
1382 * Broadcast the new active address to all clients monitoring the peer.
1383 *
1384 * @param peer peer this update is about (never NULL)
1385 * @param address address, NULL on disconnect
1386 * @param state the current state of the peer
1387 * @param state_timeout the time out for the state
1388 */
1389void
1390GST_clients_broadcast_validation_notification (
1391 const struct GNUNET_PeerIdentity *peer,
1392 const struct GNUNET_HELLO_Address *address,
1393 struct GNUNET_TIME_Absolute last_validation,
1394 struct GNUNET_TIME_Absolute valid_until,
1395 struct GNUNET_TIME_Absolute next_validation,
1396 enum GNUNET_TRANSPORT_ValidationState state)
1397{
1398 struct ValidationIterateResponseMessage *msg;
1399 struct MonitoringClient *mc;
1400 static struct GNUNET_PeerIdentity all_zeros;
1401
1402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1403 "Sending information about for validation entry for peer `%s' using address `%s'\n",
1404 GNUNET_i2s(peer), (address != NULL) ? GST_plugins_a2s (address) : "<none>");
1405
1406 msg = compose_validation_iterate_response_message (peer, address);
1407 msg->last_validation = GNUNET_TIME_absolute_hton(last_validation);
1408 msg->valid_until = GNUNET_TIME_absolute_hton(valid_until);
1409 msg->next_validation = GNUNET_TIME_absolute_hton(next_validation);
1410 msg->state = htonl ((uint32_t) state);
1411 mc = val_monitoring_clients_head;
1412 while (mc != NULL)
1413 {
1414 if ((0 == memcmp (&mc->peer, &all_zeros,
1415 sizeof (struct GNUNET_PeerIdentity))) ||
1416 (0 == memcmp (&mc->peer, peer,
1417 sizeof (struct GNUNET_PeerIdentity))))
1418 {
1419 GNUNET_SERVER_notification_context_unicast (val_nc, mc->client,
1420 &msg->header, GNUNET_NO);
1421
1422 }
1423 mc = mc->next;
1424 }
1425 GNUNET_free (msg);
1426}
1427
1162 1428
1163/* end of file gnunet-service-transport_clients.c */ 1429/* end of file gnunet-service-transport_clients.c */
diff --git a/src/transport/gnunet-service-transport_clients.h b/src/transport/gnunet-service-transport_clients.h
index 5b151382c..29c46c06b 100644
--- a/src/transport/gnunet-service-transport_clients.h
+++ b/src/transport/gnunet-service-transport_clients.h
@@ -85,6 +85,15 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
85 enum GNUNET_TRANSPORT_PeerState state, 85 enum GNUNET_TRANSPORT_PeerState state,
86 struct GNUNET_TIME_Absolute state_timeout); 86 struct GNUNET_TIME_Absolute state_timeout);
87 87
88void
89GST_clients_broadcast_validation_notification (
90 const struct GNUNET_PeerIdentity *peer,
91 const struct GNUNET_HELLO_Address *address,
92 struct GNUNET_TIME_Absolute last_validation,
93 struct GNUNET_TIME_Absolute valid_until,
94 struct GNUNET_TIME_Absolute next_validation,
95 enum GNUNET_TRANSPORT_ValidationState state);
96
88 97
89#endif 98#endif
90/* end of file gnunet-service-transport_clients.h */ 99/* end of file gnunet-service-transport_clients.h */
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 2090c71b5..fbd524f3b 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -589,7 +589,7 @@ set_state (struct NeighbourMapEntry *n, enum GNUNET_TRANSPORT_PeerState s)
589 n->state = s; 589 n->state = s;
590 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' changed state to %s\n", 590 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' changed state to %s\n",
591 GNUNET_i2s (&n->id), 591 GNUNET_i2s (&n->id),
592 GNUNET_TRANSPORT_p2s(s)); 592 GNUNET_TRANSPORT_ps2s(s));
593 neighbour_change_cb (callback_cls, 593 neighbour_change_cb (callback_cls,
594 &n->id, 594 &n->id,
595 n->primary_address.address, 595 n->primary_address.address,
@@ -615,7 +615,7 @@ set_state_and_timeout (struct NeighbourMapEntry *n,
615 n->timeout = timeout; 615 n->timeout = timeout;
616 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' changed state to %s with timeout %s\n", 616 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' changed state to %s with timeout %s\n",
617 GNUNET_i2s (&n->id), 617 GNUNET_i2s (&n->id),
618 GNUNET_TRANSPORT_p2s(s), 618 GNUNET_TRANSPORT_ps2s(s),
619 GNUNET_STRINGS_absolute_time_to_string (timeout)); 619 GNUNET_STRINGS_absolute_time_to_string (timeout));
620 neighbour_change_cb (callback_cls, 620 neighbour_change_cb (callback_cls,
621 &n->id, 621 &n->id,
@@ -1029,7 +1029,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
1029 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1029 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1030 "Disconnecting from peer %s in state %s\n", 1030 "Disconnecting from peer %s in state %s\n",
1031 GNUNET_i2s (&n->id), 1031 GNUNET_i2s (&n->id),
1032 GNUNET_TRANSPORT_p2s (n->state)); 1032 GNUNET_TRANSPORT_ps2s (n->state));
1033 /* depending on state, notify neighbour and/or upper layers of this peer 1033 /* depending on state, notify neighbour and/or upper layers of this peer
1034 about disconnect */ 1034 about disconnect */
1035 switch (n->state) 1035 switch (n->state)
@@ -1091,7 +1091,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
1091 default: 1091 default:
1092 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1092 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1093 "Unhandled state `%s'\n", 1093 "Unhandled state `%s'\n",
1094 GNUNET_TRANSPORT_p2s (n->state)); 1094 GNUNET_TRANSPORT_ps2s (n->state));
1095 GNUNET_break (0); 1095 GNUNET_break (0);
1096 break; 1096 break;
1097 } 1097 }
@@ -1775,7 +1775,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
1775 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1775 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1776 "Asked to connect to peer `%s' (state: %s)\n", 1776 "Asked to connect to peer `%s' (state: %s)\n",
1777 GNUNET_i2s (target), 1777 GNUNET_i2s (target),
1778 (NULL != n) ? GNUNET_TRANSPORT_p2s(n->state) : "NEW PEER"); 1778 (NULL != n) ? GNUNET_TRANSPORT_ps2s(n->state) : "NEW PEER");
1779 if (NULL != n) 1779 if (NULL != n)
1780 { 1780 {
1781 switch (n->state) 1781 switch (n->state)
@@ -1816,7 +1816,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
1816 default: 1816 default:
1817 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1817 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1818 "Unhandled state `%s'\n", 1818 "Unhandled state `%s'\n",
1819 GNUNET_TRANSPORT_p2s (n->state)); 1819 GNUNET_TRANSPORT_ps2s (n->state));
1820 GNUNET_break (0); 1820 GNUNET_break (0);
1821 free_neighbour (n, GNUNET_NO); 1821 free_neighbour (n, GNUNET_NO);
1822 break; 1822 break;
@@ -1876,7 +1876,7 @@ handle_test_blacklist_cont (void *cls,
1876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1877 "Received blacklist result for peer `%s' in state %s/%d\n", 1877 "Received blacklist result for peer `%s' in state %s/%d\n",
1878 GNUNET_i2s (peer), 1878 GNUNET_i2s (peer),
1879 GNUNET_TRANSPORT_p2s (n->state), 1879 GNUNET_TRANSPORT_ps2s (n->state),
1880 n->send_connect_ack); 1880 n->send_connect_ack);
1881 switch (n->state) 1881 switch (n->state)
1882 { 1882 {
@@ -2066,7 +2066,7 @@ handle_test_blacklist_cont (void *cls,
2066 default: 2066 default:
2067 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2067 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2068 "Unhandled state `%s'\n", 2068 "Unhandled state `%s'\n",
2069 GNUNET_TRANSPORT_p2s (n->state)); 2069 GNUNET_TRANSPORT_ps2s (n->state));
2070 GNUNET_break (0); 2070 GNUNET_break (0);
2071 free_neighbour (n, GNUNET_NO); 2071 free_neighbour (n, GNUNET_NO);
2072 break; 2072 break;
@@ -2167,7 +2167,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
2167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2168 "Received SESSION_CONNECT for peer `%s' in state %s/%d\n", 2168 "Received SESSION_CONNECT for peer `%s' in state %s/%d\n",
2169 GNUNET_i2s (peer), 2169 GNUNET_i2s (peer),
2170 GNUNET_TRANSPORT_p2s (n->state), 2170 GNUNET_TRANSPORT_ps2s (n->state),
2171 n->send_connect_ack); 2171 n->send_connect_ack);
2172 switch (n->state) 2172 switch (n->state)
2173 { 2173 {
@@ -2234,7 +2234,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
2234 default: 2234 default:
2235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2236 "Unhandled state `%s'\n", 2236 "Unhandled state `%s'\n",
2237 GNUNET_TRANSPORT_p2s (n->state)); 2237 GNUNET_TRANSPORT_ps2s (n->state));
2238 GNUNET_break (0); 2238 GNUNET_break (0);
2239 return GNUNET_SYSERR; 2239 return GNUNET_SYSERR;
2240 } 2240 }
@@ -2311,7 +2311,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2311 GST_plugins_a2s (address), 2311 GST_plugins_a2s (address),
2312 session, 2312 session,
2313 GNUNET_i2s (peer), 2313 GNUNET_i2s (peer),
2314 GNUNET_TRANSPORT_p2s (n->state), 2314 GNUNET_TRANSPORT_ps2s (n->state),
2315 n->send_connect_ack, 2315 n->send_connect_ack,
2316 ntohl (bandwidth_in.value__), 2316 ntohl (bandwidth_in.value__),
2317 ntohl (bandwidth_out.value__)); 2317 ntohl (bandwidth_out.value__));
@@ -2471,7 +2471,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2471 default: 2471 default:
2472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2473 "Unhandled state `%s'\n", 2473 "Unhandled state `%s'\n",
2474 GNUNET_TRANSPORT_p2s (n->state)); 2474 GNUNET_TRANSPORT_ps2s (n->state));
2475 GNUNET_break (0); 2475 GNUNET_break (0);
2476 break; 2476 break;
2477 } 2477 }
@@ -2638,7 +2638,7 @@ master_task (void *cls,
2638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2639 "Master task runs for neighbour `%s' in state %s with timeout in %s\n", 2639 "Master task runs for neighbour `%s' in state %s with timeout in %s\n",
2640 GNUNET_i2s (&n->id), 2640 GNUNET_i2s (&n->id),
2641 GNUNET_TRANSPORT_p2s(n->state), 2641 GNUNET_TRANSPORT_ps2s(n->state),
2642 GNUNET_STRINGS_relative_time_to_string (delay, 2642 GNUNET_STRINGS_relative_time_to_string (delay,
2643 GNUNET_YES)); 2643 GNUNET_YES));
2644 switch (n->state) 2644 switch (n->state)
@@ -2809,7 +2809,7 @@ master_task (void *cls,
2809 default: 2809 default:
2810 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2810 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2811 "Unhandled state `%s'\n", 2811 "Unhandled state `%s'\n",
2812 GNUNET_TRANSPORT_p2s (n->state)); 2812 GNUNET_TRANSPORT_ps2s (n->state));
2813 GNUNET_break (0); 2813 GNUNET_break (0);
2814 break; 2814 break;
2815 } 2815 }
@@ -2993,7 +2993,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2993 default: 2993 default:
2994 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2994 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2995 "Unhandled state `%s'\n", 2995 "Unhandled state `%s'\n",
2996 GNUNET_TRANSPORT_p2s (n->state)); 2996 GNUNET_TRANSPORT_ps2s (n->state));
2997 GNUNET_break (0); 2997 GNUNET_break (0);
2998 return GNUNET_SYSERR; 2998 return GNUNET_SYSERR;
2999 } 2999 }
@@ -3112,7 +3112,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3112 default: 3112 default:
3113 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3113 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3114 "Unhandled state `%s'\n", 3114 "Unhandled state `%s'\n",
3115 GNUNET_TRANSPORT_p2s (n->state)); 3115 GNUNET_TRANSPORT_ps2s (n->state));
3116 GNUNET_break (0); 3116 GNUNET_break (0);
3117 break; 3117 break;
3118 } 3118 }
@@ -3169,7 +3169,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3170 "Received SESSION_ACK message from peer `%s' in state %s/%d\n", 3170 "Received SESSION_ACK message from peer `%s' in state %s/%d\n",
3171 GNUNET_i2s (peer), 3171 GNUNET_i2s (peer),
3172 GNUNET_TRANSPORT_p2s (n->state), 3172 GNUNET_TRANSPORT_ps2s (n->state),
3173 n->send_connect_ack); 3173 n->send_connect_ack);
3174 GNUNET_STATISTICS_update (GST_stats, 3174 GNUNET_STATISTICS_update (GST_stats,
3175 gettext_noop ("# unexpected SESSION_ACK messages"), 1, 3175 gettext_noop ("# unexpected SESSION_ACK messages"), 1,
@@ -3467,7 +3467,7 @@ GST_neighbour_get_latency (const struct GNUNET_PeerIdentity *peer)
3467 default: 3467 default:
3468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3469 "Unhandled state `%s'\n", 3469 "Unhandled state `%s'\n",
3470 GNUNET_TRANSPORT_p2s (n->state)); 3470 GNUNET_TRANSPORT_ps2s (n->state));
3471 GNUNET_break (0); 3471 GNUNET_break (0);
3472 break; 3472 break;
3473 } 3473 }
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index 07ed2eeca..e18412588 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -218,6 +218,11 @@ struct ValidationEntry
218 struct GNUNET_TIME_Absolute send_time; 218 struct GNUNET_TIME_Absolute send_time;
219 219
220 /** 220 /**
221 * At what time do we send the next validation request (PING)?
222 */
223 struct GNUNET_TIME_Absolute next_validation;
224
225 /**
221 * Until when is this address valid? 226 * Until when is this address valid?
222 * ZERO if it is not currently considered valid. 227 * ZERO if it is not currently considered valid.
223 */ 228 */
@@ -244,6 +249,10 @@ struct ValidationEntry
244 struct GNUNET_TIME_Relative latency; 249 struct GNUNET_TIME_Relative latency;
245 250
246 /** 251 /**
252 * Current state of this validation entry
253 */
254 enum GNUNET_TRANSPORT_ValidationState state;
255 /**
247 * Challenge number we used. 256 * Challenge number we used.
248 */ 257 */
249 uint32_t challenge; 258 uint32_t challenge;
@@ -336,6 +345,9 @@ static unsigned int validations_fast_start_threshold;
336 */ 345 */
337static struct GNUNET_TIME_Absolute validation_next; 346static struct GNUNET_TIME_Absolute validation_next;
338 347
348static GST_ValidationChangedCallback validation_entry_changed_cb;
349static void *validation_entry_changed_cb_cls;
350
339/** 351/**
340 * Context for the validation entry match function. 352 * Context for the validation entry match function.
341 */ 353 */
@@ -377,6 +389,24 @@ validation_entry_match (void *cls, const struct GNUNET_PeerIdentity * key, void
377 return GNUNET_YES; 389 return GNUNET_YES;
378} 390}
379 391
392static void
393validation_entry_changed (struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
394{
395 char *t_sent = GNUNET_strdup(GNUNET_STRINGS_absolute_time_to_string(ve->send_time));
396 char *t_valid = GNUNET_strdup(GNUNET_STRINGS_absolute_time_to_string(ve->valid_until));
397 char *t_next = GNUNET_strdup(GNUNET_STRINGS_absolute_time_to_string(ve->next_validation));
398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Validation entry changed for peer `%s' address `%s':\n\tSent: %s\n\tValid: %s\n\tNext: %s\n",
399 GNUNET_i2s(&ve->pid), GST_plugins_a2s(ve->address),
400 t_sent, t_valid, t_next);
401 ve->state = state;
402
403 GNUNET_free (t_sent);
404 GNUNET_free (t_valid);
405 GNUNET_free (t_next);
406 validation_entry_changed_cb (validation_entry_changed_cb_cls, &ve->pid,
407 ve->address, ve->send_time, ve->valid_until, ve->next_validation, state);
408}
409
380 410
381/** 411/**
382 * Iterate over validation entries and free them. 412 * Iterate over validation entries and free them.
@@ -391,6 +421,12 @@ cleanup_validation_entry (void *cls, const struct GNUNET_PeerIdentity * key, voi
391{ 421{
392 struct ValidationEntry *ve = value; 422 struct ValidationEntry *ve = value;
393 423
424 ve->next_validation = GNUNET_TIME_absolute_get_zero_();
425 ve->valid_until = GNUNET_TIME_UNIT_ZERO_ABS;
426
427 /* Notify about deleted entry */
428 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_REMOVE);
429
394 if (NULL != ve->bc) 430 if (NULL != ve->bc)
395 { 431 {
396 GST_blacklist_test_cancel (ve->bc); 432 GST_blacklist_test_cancel (ve->bc);
@@ -586,6 +622,8 @@ transmit_ping_if_allowed (void *cls,
586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
587 "Validation started, %u validation processes running\n", 623 "Validation started, %u validation processes running\n",
588 validations_running); 624 validations_running);
625 /* Notify about PING sent */
626 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE);
589 } 627 }
590} 628}
591 629
@@ -631,6 +669,7 @@ revalidate_address (void *cls,
631 GST_plugins_a2s (ve->address)); 669 GST_plugins_a2s (ve->address));
632 ve->revalidation_task = 670 ve->revalidation_task =
633 GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve); 671 GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve);
672 ve->next_validation = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), delay);
634 return; 673 return;
635 } 674 }
636 blocked_for = GNUNET_TIME_absolute_get_remaining(validation_next); 675 blocked_for = GNUNET_TIME_absolute_get_remaining(validation_next);
@@ -645,6 +684,7 @@ revalidate_address (void *cls,
645 GST_plugins_a2s (ve->address)); 684 GST_plugins_a2s (ve->address));
646 ve->revalidation_task = 685 ve->revalidation_task =
647 GNUNET_SCHEDULER_add_delayed (blocked_for, &revalidate_address, ve); 686 GNUNET_SCHEDULER_add_delayed (blocked_for, &revalidate_address, ve);
687 ve->next_validation = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), blocked_for);
648 return; 688 return;
649 } 689 }
650 ve->revalidation_block = GNUNET_TIME_relative_to_absolute (canonical_delay); 690 ve->revalidation_block = GNUNET_TIME_relative_to_absolute (canonical_delay);
@@ -675,6 +715,7 @@ revalidate_address (void *cls,
675 GST_plugins_a2s (ve->address)); 715 GST_plugins_a2s (ve->address));
676 ve->revalidation_task = 716 ve->revalidation_task =
677 GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve); 717 GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve);
718 ve->next_validation = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), delay);
678 719
679 /* start PINGing by checking blacklist */ 720 /* start PINGing by checking blacklist */
680 GNUNET_STATISTICS_update (GST_stats, 721 GNUNET_STATISTICS_update (GST_stats,
@@ -730,6 +771,7 @@ find_validation_entry (const struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
730 GNUNET_CONTAINER_multipeermap_put (validation_map, &address->peer, 771 GNUNET_CONTAINER_multipeermap_put (validation_map, &address->peer,
731 ve, 772 ve,
732 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 773 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
774 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_NEW);
733 ve->expecting_pong = GNUNET_NO; 775 ve->expecting_pong = GNUNET_NO;
734 return ve; 776 return ve;
735} 777}
@@ -779,8 +821,10 @@ add_valid_address (void *cls,
779 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
780 "Starting revalidations for valid address `%s'\n", 822 "Starting revalidations for valid address `%s'\n",
781 GST_plugins_a2s (ve->address)); 823 GST_plugins_a2s (ve->address));
824 ve->next_validation = GNUNET_TIME_absolute_get();
782 ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); 825 ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve);
783 } 826 }
827 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE);
784 828
785 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 829 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
786 ats.value = htonl (ve->network); 830 ats.value = htonl (ve->network);
@@ -822,7 +866,7 @@ process_peerinfo_hello (void *cls, const struct GNUNET_PeerIdentity *peer,
822 * @param max_fds maximum number of fds to use 866 * @param max_fds maximum number of fds to use
823 */ 867 */
824void 868void
825GST_validation_start (unsigned int max_fds) 869GST_validation_start (GST_ValidationChangedCallback cb, void *cb_cls, unsigned int max_fds)
826{ 870{
827 /** 871 /**
828 * Initialization for validation throttling 872 * Initialization for validation throttling
@@ -840,6 +884,8 @@ GST_validation_start (unsigned int max_fds)
840 validation_delay.rel_value_us = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us) / (max_fds / 2); 884 validation_delay.rel_value_us = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us) / (max_fds / 2);
841 validations_fast_start_threshold = (max_fds / 2); 885 validations_fast_start_threshold = (max_fds / 2);
842 validations_running = 0; 886 validations_running = 0;
887 validation_entry_changed_cb = cb;
888 validation_entry_changed_cb_cls = cb_cls;
843 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Validation uses a fast start threshold of %u connections and a delay between of %s\n ", 889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Validation uses a fast start threshold of %u connections and a delay between of %s\n ",
844 validations_fast_start_threshold, 890 validations_fast_start_threshold,
845 GNUNET_STRINGS_relative_time_to_string (validation_delay, 891 GNUNET_STRINGS_relative_time_to_string (validation_delay,
@@ -1396,6 +1442,9 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
1396 GNUNET_break (0); 1442 GNUNET_break (0);
1397 } 1443 }
1398 1444
1445 /* Notify about new validity */
1446 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE);
1447
1399 /* build HELLO to store in PEERINFO */ 1448 /* build HELLO to store in PEERINFO */
1400 ve->copied = GNUNET_NO; 1449 ve->copied = GNUNET_NO;
1401 hello = GNUNET_HELLO_create (&ve->public_key, 1450 hello = GNUNET_HELLO_create (&ve->public_key,
@@ -1600,5 +1649,54 @@ GST_validation_get_address_latency (const struct GNUNET_PeerIdentity *sender,
1600 return ve->latency; 1649 return ve->latency;
1601} 1650}
1602 1651
1652/**
1653 * Closure for the validation_entries_iterate function.
1654 */
1655struct ValidationIteratorContext
1656{
1657 /**
1658 * Function to call on each validation entry
1659 */
1660 GST_ValidationChangedCallback cb;
1661
1662 /**
1663 * Closure for 'cb'.
1664 */
1665 void *cb_cls;
1666};
1667
1668static int
1669validation_entries_iterate (void *cls,
1670 const struct GNUNET_PeerIdentity *key,
1671 void *value)
1672{
1673 struct ValidationIteratorContext *ic = cls;
1674 struct ValidationEntry *ve = value;
1675
1676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying about validation entry for peer `%s' address `%s' \n",
1677 GNUNET_i2s (&ve->pid), GST_plugins_a2s (ve->address));
1678 ic->cb (ic->cb_cls, &ve->pid, ve->address, ve->send_time,
1679 ve->valid_until, ve->next_validation, ve->state);
1680
1681 return GNUNET_OK;
1682}
1683
1684/**
1685 * Iterate over all iteration entries
1686 *
1687 * @param cb function to call
1688 * @param cb_cls closure for cb
1689 */
1690void
1691GST_validation_iterate (GST_ValidationChangedCallback cb, void *cb_cls)
1692{
1693 struct ValidationIteratorContext ic;
1694
1695 if (NULL == validation_map)
1696 return; /* can happen during shutdown */
1697 ic.cb = cb;
1698 ic.cb_cls = cb_cls;
1699 GNUNET_CONTAINER_multipeermap_iterate (validation_map, &validation_entries_iterate, &ic);
1700}
1603 1701
1604/* end of file gnunet-service-transport_validation.c */ 1702/* end of file gnunet-service-transport_validation.c */
diff --git a/src/transport/gnunet-service-transport_validation.h b/src/transport/gnunet-service-transport_validation.h
index e07afc409..d117faca5 100644
--- a/src/transport/gnunet-service-transport_validation.h
+++ b/src/transport/gnunet-service-transport_validation.h
@@ -31,6 +31,26 @@
31#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
32#include "gnunet_hello_lib.h" 32#include "gnunet_hello_lib.h"
33 33
34/**
35 * Function called for each address (or address status change) that
36 * the validation module is aware of (for the given target).
37 *
38 * @param cls closure
39 * @param public_key public key for the peer, never NULL
40 * @param valid_until is ZERO if we never validated the address,
41 * otherwise a time up to when we consider it (or was) valid
42 * @param validation_block is FOREVER if the address is for an unsupported plugin (from PEERINFO)
43 * is ZERO if the address is considered valid (no validation needed)
44 * otherwise a time in the future if we're currently denying re-validation
45 * @param address the address
46 */
47typedef void (*GST_ValidationChangedCallback) (void *cls,
48 const struct GNUNET_PeerIdentity *peer,
49 const struct GNUNET_HELLO_Address *address,
50 struct GNUNET_TIME_Absolute last_validation,
51 struct GNUNET_TIME_Absolute valid_until,
52 struct GNUNET_TIME_Absolute next_validation,
53 enum GNUNET_TRANSPORT_ValidationState state);
34 54
35/** 55/**
36 * Start the validation subsystem. 56 * Start the validation subsystem.
@@ -38,7 +58,7 @@
38 * @param max_fds maximum number of fds to use 58 * @param max_fds maximum number of fds to use
39 */ 59 */
40void 60void
41GST_validation_start (unsigned int max_fds); 61GST_validation_start (GST_ValidationChangedCallback cb, void *cb_cls, unsigned int max_fds);
42 62
43 63
44/** 64/**
@@ -79,6 +99,14 @@ GST_validation_get_address_latency (const struct GNUNET_PeerIdentity *sender,
79 const struct GNUNET_HELLO_Address *address, 99 const struct GNUNET_HELLO_Address *address,
80 struct Session *session); 100 struct Session *session);
81 101
102/**
103 * Iterate over all iteration entries
104 *
105 * @param cb function to call
106 * @param cb_cls closure for cb
107 */
108void
109GST_validation_iterate (GST_ValidationChangedCallback cb, void *cb_cls);
82 110
83/** 111/**
84 * We've received a PING. If appropriate, generate a PONG. 112 * We've received a PING. If appropriate, generate a PONG.
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c
index c2d35cd66..c8408b757 100644
--- a/src/transport/gnunet-transport.c
+++ b/src/transport/gnunet-transport.c
@@ -89,6 +89,11 @@ static int benchmark_receive;
89static int iterate_connections; 89static int iterate_connections;
90 90
91/** 91/**
92 * Option -d.
93 */
94static int iterate_validation;
95
96/**
92 * Option -a. 97 * Option -a.
93 */ 98 */
94static int iterate_all; 99static int iterate_all;
@@ -156,7 +161,9 @@ static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers;
156/** 161/**
157 * 162 *
158 */ 163 */
159struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; 164static struct GNUNET_TRANSPORT_PeerMonitoringContext *pic;
165
166static struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic;
160 167
161/** 168/**
162 * Identity of the peer we transmit to / connect to. 169 * Identity of the peer we transmit to / connect to.
@@ -269,6 +276,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
269 GNUNET_TRANSPORT_monitor_peers_cancel (pic); 276 GNUNET_TRANSPORT_monitor_peers_cancel (pic);
270 pic = NULL; 277 pic = NULL;
271 } 278 }
279 if (NULL != vic)
280 {
281 GNUNET_TRANSPORT_monitor_validation_entries_cancel (vic);
282 vic = NULL;
283 }
272 if (NULL != th) 284 if (NULL != th)
273 { 285 {
274 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); 286 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
@@ -430,6 +442,17 @@ fail_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
430 display_test_result (tstc, GNUNET_NO); 442 display_test_result (tstc, GNUNET_NO);
431} 443}
432 444
445void process_validation_cb (void *cls,
446 const struct GNUNET_PeerIdentity *peer,
447 const struct GNUNET_HELLO_Address *address,
448 struct GNUNET_TIME_Absolute last_validation,
449 struct GNUNET_TIME_Absolute valid_until,
450 struct GNUNET_TIME_Absolute next_validation,
451 enum GNUNET_TRANSPORT_ValidationState state)
452{
453 GNUNET_break (0);
454}
455
433/** 456/**
434 * Test our plugin's configuration (NAT traversal, etc.). 457 * Test our plugin's configuration (NAT traversal, etc.).
435 * 458 *
@@ -694,7 +717,7 @@ print_info (const struct GNUNET_PeerIdentity *id, const char *transport,
694 GNUNET_i2s (id), 717 GNUNET_i2s (id),
695 (NULL == transport) ? "<none>" : transport, 718 (NULL == transport) ? "<none>" : transport,
696 (NULL == transport) ? "<none>" : addr, 719 (NULL == transport) ? "<none>" : addr,
697 GNUNET_TRANSPORT_p2s (state), 720 GNUNET_TRANSPORT_ps2s (state),
698 GNUNET_STRINGS_absolute_time_to_string (state_timeout)); 721 GNUNET_STRINGS_absolute_time_to_string (state_timeout));
699 } 722 }
700 else 723 else
@@ -951,7 +974,7 @@ testservice_task (void *cls, int result)
951 } 974 }
952 975
953 counter = benchmark_send + benchmark_receive + iterate_connections 976 counter = benchmark_send + benchmark_receive + iterate_connections
954 + monitor_connections + monitor_connects + try_connect; 977 + monitor_connections + monitor_connects + try_connect + iterate_validation;
955 978
956 if (1 < counter) 979 if (1 < counter)
957 { 980 {
@@ -1060,6 +1083,11 @@ testservice_task (void *cls, int result)
1060 pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, 1083 pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid,
1061 GNUNET_NO, TIMEOUT, &process_peer_monitoring_cb, (void *) cfg); 1084 GNUNET_NO, TIMEOUT, &process_peer_monitoring_cb, (void *) cfg);
1062 } 1085 }
1086 else if (iterate_validation) /* -d: Print information about validations */
1087 {
1088 vic = GNUNET_TRANSPORT_monitor_validation_entries (cfg, (NULL == cpid) ? NULL : &pid,
1089 GNUNET_YES, TIMEOUT, &process_validation_cb, (void *) cfg);
1090 }
1063 else if (monitor_connects) /* -e : Monitor (dis)connect events continuously */ 1091 else if (monitor_connects) /* -e : Monitor (dis)connect events continuously */
1064 { 1092 {
1065 monitor_connect_counter = 0; 1093 monitor_connect_counter = 0;
@@ -1120,6 +1148,9 @@ main (int argc, char * const *argv)
1120 0, &GNUNET_GETOPT_set_one, &benchmark_receive }, { 'C', "connect", 1148 0, &GNUNET_GETOPT_set_one, &benchmark_receive }, { 'C', "connect",
1121 NULL, gettext_noop ("connect to a peer"), 0, 1149 NULL, gettext_noop ("connect to a peer"), 0,
1122 &GNUNET_GETOPT_set_one, &try_connect }, 1150 &GNUNET_GETOPT_set_one, &try_connect },
1151 { 'd', "validation", NULL,
1152 gettext_noop ("print information for all pending validations "),
1153 0, &GNUNET_GETOPT_set_one, &iterate_validation },
1123 { 'i', "information", NULL, 1154 { 'i', "information", NULL,
1124 gettext_noop ("provide information about all current connections (once)"), 1155 gettext_noop ("provide information about all current connections (once)"),
1125 0, &GNUNET_GETOPT_set_one, &iterate_connections }, 1156 0, &GNUNET_GETOPT_set_one, &iterate_connections },
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 9e3fc4fdf..e7ab1a818 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -1308,7 +1308,7 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1308 "Session %p was idle for %s, disconnecting\n", s, 1308 "Session %p was idle for %s, disconnecting\n", s,
1309 GNUNET_STRINGS_relative_time_to_string (UDP_SESSION_TIME_OUT, GNUNET_YES)); 1309 GNUNET_STRINGS_relative_time_to_string (UDP_SESSION_TIME_OUT, GNUNET_YES));
1310 /* call session destroy function */ 1310 /* call session destroy function */
1311 udp_disconnect_session (s->plugin, s); 1311 udp_disconnect_session (plugin, s);
1312} 1312}
1313 1313
1314/** 1314/**
diff --git a/src/transport/test_transport_api_monitoring.c b/src/transport/test_transport_api_monitoring.c
index f726344dd..0767893ed 100644
--- a/src/transport/test_transport_api_monitoring.c
+++ b/src/transport/test_transport_api_monitoring.c
@@ -98,15 +98,20 @@ end ()
98 GNUNET_SCHEDULER_cancel (send_task); 98 GNUNET_SCHEDULER_cancel (send_task);
99 99
100 if (die_task != GNUNET_SCHEDULER_NO_TASK) 100 if (die_task != GNUNET_SCHEDULER_NO_TASK)
101 {
101 GNUNET_SCHEDULER_cancel (die_task); 102 GNUNET_SCHEDULER_cancel (die_task);
103 die_task = GNUNET_SCHEDULER_NO_TASK;
104 }
102 105
103 if (th != NULL) 106 if (th != NULL)
104 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); 107 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
105 th = NULL; 108 th = NULL;
106 109
107 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1); 110 if (NULL != p1)
111 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1);
108 p1 = NULL; 112 p1 = NULL;
109 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2); 113 if (NULL != p2)
114 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2);
110 p2 = NULL; 115 p2 = NULL;
111 116
112 if (NULL != pmc_p1) 117 if (NULL != pmc_p1)
@@ -382,8 +387,8 @@ static void monitor1_cb (void *cls,
382 if ((NULL == peer) || (NULL == p1)) 387 if ((NULL == peer) || (NULL == p1))
383 return; 388 return;
384 389
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Monitor 1: %s %s %s\n", 390 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Monitor 1: %s %s %s\n",
386 GNUNET_i2s (peer), GNUNET_TRANSPORT_p2s(state), GNUNET_STRINGS_absolute_time_to_string(state_timeout)); 391 GNUNET_i2s (peer), GNUNET_TRANSPORT_ps2s(state), GNUNET_STRINGS_absolute_time_to_string(state_timeout));
387 if ((0 == memcmp (peer, &p2->id, sizeof (p2->id)) && 392 if ((0 == memcmp (peer, &p2->id, sizeof (p2->id)) &&
388 (GNUNET_YES == GNUNET_TRANSPORT_is_connected(state)) && 393 (GNUNET_YES == GNUNET_TRANSPORT_is_connected(state)) &&
389 GNUNET_NO == p1_c) ) 394 GNUNET_NO == p1_c) )
@@ -404,8 +409,8 @@ static void monitor2_cb (void *cls,
404 if ((NULL == peer) || (NULL == p2)) 409 if ((NULL == peer) || (NULL == p2))
405 return; 410 return;
406 411
407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Monitor 2: %s %s %s\n", 412 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Monitor 2: %s %s %s\n",
408 GNUNET_i2s (peer), GNUNET_TRANSPORT_p2s (state), GNUNET_STRINGS_absolute_time_to_string(state_timeout)); 413 GNUNET_i2s (peer), GNUNET_TRANSPORT_ps2s (state), GNUNET_STRINGS_absolute_time_to_string(state_timeout));
409 if ((0 == memcmp (peer, &p1->id, sizeof (p1->id)) && 414 if ((0 == memcmp (peer, &p1->id, sizeof (p1->id)) &&
410 (GNUNET_YES == GNUNET_TRANSPORT_is_connected(state)) && 415 (GNUNET_YES == GNUNET_TRANSPORT_is_connected(state)) &&
411 GNUNET_NO == p2_c) ) 416 GNUNET_NO == p2_c) )
@@ -432,13 +437,14 @@ run (void *cls, char *const *args, const char *cfgfile,
432 &notify_disconnect, &start_cb, 437 &notify_disconnect, &start_cb,
433 NULL); 438 NULL);
434 pmc_p1 = GNUNET_TRANSPORT_monitor_peers (p1->cfg, NULL, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, &monitor1_cb, NULL); 439 pmc_p1 = GNUNET_TRANSPORT_monitor_peers (p1->cfg, NULL, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, &monitor1_cb, NULL);
440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 started\n");
435 441
436 p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2, 442 p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2,
437 &notify_receive, &notify_connect, 443 &notify_receive, &notify_connect,
438 &notify_disconnect, &start_cb, 444 &notify_disconnect, &start_cb,
439 NULL); 445 NULL);
440 pmc_p2 = GNUNET_TRANSPORT_monitor_peers (p2->cfg, NULL, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, &monitor2_cb, NULL); 446 pmc_p2 = GNUNET_TRANSPORT_monitor_peers (p2->cfg, NULL, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, &monitor2_cb, NULL);
441 447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 started\n");
442 if ((p1 == NULL) || (p2 == NULL)) 448 if ((p1 == NULL) || (p2 == NULL))
443 { 449 {
444 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n"); 450 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n");
diff --git a/src/transport/test_transport_api_monitoring_validation_peer1.conf b/src/transport/test_transport_api_monitoring_validation_peer1.conf
new file mode 100644
index 000000000..aca9c1e7c
--- /dev/null
+++ b/src/transport/test_transport_api_monitoring_validation_peer1.conf
@@ -0,0 +1,6 @@
1@INLINE@ template_cfg_peer1.conf
2[PATHS]
3GNUNET_TEST_HOME = /tmp/test-transport/api-monitoring-val-p1/
4
5[transport]
6PLUGINS=tcp
diff --git a/src/transport/test_transport_api_monitoring_validation_peer2.conf b/src/transport/test_transport_api_monitoring_validation_peer2.conf
new file mode 100644
index 000000000..86dfcbbbc
--- /dev/null
+++ b/src/transport/test_transport_api_monitoring_validation_peer2.conf
@@ -0,0 +1,7 @@
1@INLINE@ template_cfg_peer2.conf
2[PATHS]
3GNUNET_TEST_HOME = /tmp/test-transport/api-monitoring-val-p2/
4
5[TRANSPORT]
6PLUGINS=tcp
7
diff --git a/src/transport/transport.h b/src/transport/transport.h
index 5a2f04056..dab5415c2 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -341,15 +341,20 @@ struct AddressLookupMessage
341}; 341};
342 342
343 343
344#if 0
345/** 344/**
346 * Message from the library to the transport service 345 * Message from the transport service to the library containing information
347 * asking for human readable addresses known for a peer. 346 * about a peer. Information contained are:
347 * - current address used to communicate with this peer
348 * - state
349 * - state timeout
350 *
351 * Memory layout:
352 * [AddressIterateResponseMessage][address[addrlen]][transportname[pluginlen]]
348 */ 353 */
349struct PeerLookupMessage 354struct ValidationIterateResponseMessage
350{ 355{
351 /** 356 /**
352 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PEER_ADDRESS_LOOKUP 357 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE
353 */ 358 */
354 struct GNUNET_MessageHeader header; 359 struct GNUNET_MessageHeader header;
355 360
@@ -359,16 +364,59 @@ struct PeerLookupMessage
359 uint32_t reserved; 364 uint32_t reserved;
360 365
361 /** 366 /**
362 * timeout to give up. FIXME: remove in the future. 367 * Peer identity
363 */ 368 */
364 struct GNUNET_TIME_RelativeNBO timeout; 369 struct GNUNET_PeerIdentity peer;
370
371 /**
372 * Local info about the address
373 */
374 uint32_t local_address_info GNUNET_PACKED;
375
376 /**
377 * Address length
378 */
379 uint32_t addrlen GNUNET_PACKED;
380
381 /**
382 * Length of the plugin name
383 */
384 uint32_t pluginlen GNUNET_PACKED;
385
386 /**
387 * State
388 */
389 uint32_t state GNUNET_PACKED;
390
391 struct GNUNET_TIME_AbsoluteNBO last_validation;
392
393 struct GNUNET_TIME_AbsoluteNBO valid_until;
394
395 struct GNUNET_TIME_AbsoluteNBO next_validation;
396};
397
398/**
399 * Message from the library to the transport service
400 * asking for binary addresses known for a peer.
401 */
402struct ValidationMonitorMessage
403{
404 /**
405 * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_REQUEST
406 */
407 struct GNUNET_MessageHeader header;
408
409 /**
410 * One shot call or continous replies?
411 */
412 uint32_t one_shot;
365 413
366 /** 414 /**
367 * The identity of the peer to look up. 415 * The identity of the peer to look up.
368 */ 416 */
369 struct GNUNET_PeerIdentity peer; 417 struct GNUNET_PeerIdentity peer;
418
370}; 419};
371#endif
372 420
373 421
374/** 422/**
@@ -378,7 +426,7 @@ struct PeerLookupMessage
378struct PeerMonitorMessage 426struct PeerMonitorMessage
379{ 427{
380 /** 428 /**
381 * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE 429 * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST
382 */ 430 */
383 struct GNUNET_MessageHeader header; 431 struct GNUNET_MessageHeader header;
384 432
@@ -388,11 +436,6 @@ struct PeerMonitorMessage
388 uint32_t one_shot; 436 uint32_t one_shot;
389 437
390 /** 438 /**
391 * timeout to give up. FIXME: remove in the future
392 */
393 struct GNUNET_TIME_AbsoluteNBO timeout;
394
395 /**
396 * The identity of the peer to look up. 439 * The identity of the peer to look up.
397 */ 440 */
398 struct GNUNET_PeerIdentity peer; 441 struct GNUNET_PeerIdentity peer;
diff --git a/src/transport/transport_api_monitoring.c b/src/transport/transport_api_monitoring.c
index 50517cc6c..9820151d5 100644
--- a/src/transport/transport_api_monitoring.c
+++ b/src/transport/transport_api_monitoring.c
@@ -173,7 +173,7 @@ GNUNET_TRANSPORT_is_connected (enum GNUNET_TRANSPORT_PeerState state)
173 default: 173 default:
174 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 174 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
175 "Unhandled state `%s' \n", 175 "Unhandled state `%s' \n",
176 GNUNET_TRANSPORT_p2s (state)); 176 GNUNET_TRANSPORT_ps2s (state));
177 GNUNET_break (0); 177 GNUNET_break (0);
178 break; 178 break;
179 } 179 }
@@ -181,13 +181,13 @@ GNUNET_TRANSPORT_is_connected (enum GNUNET_TRANSPORT_PeerState state)
181} 181}
182 182
183/** 183/**
184 * Convert state to human-readable string. 184 * Convert peer state to human-readable string.
185 * 185 *
186 * @param state the state value 186 * @param state the state value
187 * @return corresponding string 187 * @return corresponding string
188 */ 188 */
189const char * 189const char *
190GNUNET_TRANSPORT_p2s (enum GNUNET_TRANSPORT_PeerState state) 190GNUNET_TRANSPORT_ps2s (enum GNUNET_TRANSPORT_PeerState state)
191{ 191{
192 switch (state) 192 switch (state)
193 { 193 {
@@ -229,6 +229,31 @@ GNUNET_TRANSPORT_p2s (enum GNUNET_TRANSPORT_PeerState state)
229 } 229 }
230} 230}
231 231
232/**
233 * Convert validation state to human-readable string.
234 *
235 * @param state the state value
236 * @return corresponding string
237 */
238const char *
239GNUNET_TRANSPORT_vs2s (enum GNUNET_TRANSPORT_ValidationState state)
240{
241 switch (state)
242 {
243 case GNUNET_TRANSPORT_VS_NEW:
244 return "NEW";
245 case GNUNET_TRANSPORT_VS_REMOVE:
246 return "REMOVE";
247 case GNUNET_TRANSPORT_VS_TIMEOUT:
248 return "TIMEOUT";
249 case GNUNET_TRANSPORT_VS_UPDATE:
250 return "UPDATE";
251 default:
252 GNUNET_break (0);
253 return "UNDEFINED";
254 }
255}
256
232 257
233/** 258/**
234 * Function called with responses from the service. 259 * Function called with responses from the service.
@@ -238,35 +263,67 @@ GNUNET_TRANSPORT_p2s (enum GNUNET_TRANSPORT_PeerState state)
238 * message with the human-readable address 263 * message with the human-readable address
239 */ 264 */
240static void 265static void
241peer_response_processor (void *cls, 266peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg);
242 const struct GNUNET_MessageHeader *msg);
243 267
244 268
245/** 269/**
270 * Function called with responses from the service.
271 *
272 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
273 * @param msg NULL on timeout or error, otherwise presumably a
274 * message with the human-readable address
275 */
276static void
277val_response_processor (void *cls, const struct GNUNET_MessageHeader *msg);
278
279/**
246 * Send our subscription request to the service. 280 * Send our subscription request to the service.
247 * 281 *
248 * @param pal_ctx our context 282 * @param pal_ctx our context
249 */ 283 */
250static void 284static void
251send_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) 285send_peer_mon_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
252{ 286{
253 struct PeerMonitorMessage msg; 287 struct PeerMonitorMessage msg;
254 288
255 msg.header.size = htons (sizeof (struct PeerMonitorMessage)); 289 msg.header.size = htons (sizeof (struct PeerMonitorMessage));
256 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST); 290 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST);
257 msg.one_shot = htonl (pal_ctx->one_shot); 291 msg.one_shot = htonl (pal_ctx->one_shot);
258 msg.timeout = GNUNET_TIME_absolute_hton (pal_ctx->timeout);
259 msg.peer = pal_ctx->peer; 292 msg.peer = pal_ctx->peer;
260 GNUNET_assert (GNUNET_OK == 293 GNUNET_assert (GNUNET_OK ==
261 GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client, 294 GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client,
262 &msg.header, 295 &msg.header,
263 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout), 296 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout),
264 GNUNET_YES, 297 GNUNET_YES,
265 &peer_response_processor, 298 &peer_response_processor,
266 pal_ctx)); 299 pal_ctx));
267} 300}
268 301
269/** 302/**
303 * Send our subscription request to the service.
304 *
305 * @param pal_ctx our context
306 */
307static void
308send_val_mon_request (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
309{
310 struct ValidationMonitorMessage msg;
311
312 msg.header.size = htons (sizeof (struct PeerMonitorMessage));
313 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_REQUEST);
314 msg.one_shot = htonl (val_ctx->one_shot);
315 msg.peer = val_ctx->peer;
316 GNUNET_assert (GNUNET_OK ==
317 GNUNET_CLIENT_transmit_and_get_response (val_ctx->client,
318 &msg.header,
319 GNUNET_TIME_absolute_get_remaining (val_ctx->timeout),
320 GNUNET_YES,
321 &val_response_processor,
322 val_ctx));
323}
324
325
326/**
270 * Task run to re-establish the connection. 327 * Task run to re-establish the connection.
271 * 328 *
272 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' 329 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
@@ -281,7 +338,7 @@ do_connect (void *cls,
281 pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 338 pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
282 pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg); 339 pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg);
283 GNUNET_assert (NULL != pal_ctx->client); 340 GNUNET_assert (NULL != pal_ctx->client);
284 send_request (pal_ctx); 341 send_peer_mon_request (pal_ctx);
285} 342}
286 343
287 344
@@ -302,6 +359,154 @@ reconnect (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
302 pal_ctx); 359 pal_ctx);
303} 360}
304 361
362/**
363 * Function called with responses from the service.
364 *
365 * @param cls our 'struct GNUNET_TRANSPORT_PeerMonitoringContext*'
366 * @param msg NULL on timeout or error, otherwise presumably a
367 * message with the human-readable address
368 */
369static void
370val_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
371{
372 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
373 GNUNET_break (0);
374 if (msg == NULL)
375 {
376 GNUNET_break (0);
377 if (val_ctx->one_shot)
378 {
379 /* Disconnect */
380 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
381 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
382 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
383 GNUNET_TRANSPORT_monitor_peers_cancel (val_ctx);
384 }
385 else
386 {
387 reconnect (val_ctx);
388 }
389 return;
390 }
391
392 /* expect more replies */
393 GNUNET_CLIENT_receive (val_ctx->client, &val_response_processor,
394 val_ctx, GNUNET_TIME_absolute_get_remaining (val_ctx->timeout));
395
396 return;
397
398 struct ValidationIterateResponseMessage *vir_msg;
399 struct GNUNET_HELLO_Address *address;
400 const char *addr;
401 const char *transport_name;
402 uint16_t size;
403 size_t alen;
404 size_t tlen;
405#if 0
406
407 size = ntohs (msg->size);
408 GNUNET_break (ntohs (msg->type) ==
409 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
410 if (size == sizeof (struct GNUNET_MessageHeader))
411 {
412 /* Done! */
413 if (pal_ctx->one_shot)
414 {
415 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
416 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
417 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
418 }
419 else
420 {
421 reconnect (pal_ctx);
422 }
423 return;
424 }
425
426 if ((size < sizeof (struct PeerIterateResponseMessage)) ||
427 (ntohs (msg->type) !=
428 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE))
429 {
430 GNUNET_break (0);
431 if (pal_ctx->one_shot)
432 {
433 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
434 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
435 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
436 }
437 else
438 {
439 reconnect (pal_ctx);
440 }
441 return;
442 }
443
444 pir_msg = (struct PeerIterateResponseMessage *) msg;
445 tlen = ntohl (pir_msg->pluginlen);
446 alen = ntohl (pir_msg->addrlen);
447
448 if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen)
449 {
450 GNUNET_break (0);
451 if (pal_ctx->one_shot)
452 {
453 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
454 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
455 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
456 }
457 else
458 {
459 reconnect (pal_ctx);
460 }
461 return;
462 }
463
464 if ( (0 == tlen) && (0 == alen) )
465 {
466 /* No address available */
467 pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL,
468 ntohl(pir_msg->state),
469 GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
470 }
471 else
472 {
473 if (0 == tlen)
474 {
475 GNUNET_break (0); /* This must not happen: address without plugin */
476 return;
477 }
478 addr = (const char *) &pir_msg[1];
479 transport_name = &addr[alen];
480
481 if (transport_name[tlen - 1] != '\0')
482 {
483 /* Corrupt plugin name */
484 GNUNET_break (0);
485 if (pal_ctx->one_shot)
486 {
487 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
488 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
489 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
490 }
491 else
492 {
493 reconnect (pal_ctx);
494 }
495 return;
496 }
497
498 /* notify client */
499 address = GNUNET_HELLO_address_allocate (&pir_msg->peer,
500 transport_name, addr, alen, ntohl(pir_msg->local_address_info));
501 pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address,
502 ntohl(pir_msg->state),
503 GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
504 GNUNET_HELLO_address_free (address);
505 }
506#endif
507
508}
509
305 510
306/** 511/**
307 * Function called with responses from the service. 512 * Function called with responses from the service.
@@ -321,7 +526,7 @@ peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
321 uint16_t size; 526 uint16_t size;
322 size_t alen; 527 size_t alen;
323 size_t tlen; 528 size_t tlen;
324 529 GNUNET_break (0);
325 if (msg == NULL) 530 if (msg == NULL)
326 { 531 {
327 if (pal_ctx->one_shot) 532 if (pal_ctx->one_shot)
@@ -394,7 +599,6 @@ peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
394 return; 599 return;
395 } 600 }
396 601
397
398 if ( (0 == tlen) && (0 == alen) ) 602 if ( (0 == tlen) && (0 == alen) )
399 { 603 {
400 /* No address available */ 604 /* No address available */
@@ -498,7 +702,7 @@ GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
498 pal_ctx->peer = *peer; 702 pal_ctx->peer = *peer;
499 pal_ctx->one_shot = one_shot; 703 pal_ctx->one_shot = one_shot;
500 pal_ctx->client = client; 704 pal_ctx->client = client;
501 send_request (pal_ctx); 705 send_peer_mon_request (pal_ctx);
502 706
503 return pal_ctx; 707 return pal_ctx;
504} 708}
@@ -548,8 +752,26 @@ GNUNET_TRANSPORT_monitor_validation_entries (const struct
548 GNUNET_TRANSPORT_ValidationIterateCallback validation_callback, 752 GNUNET_TRANSPORT_ValidationIterateCallback validation_callback,
549 void *validation_callback_cls) 753 void *validation_callback_cls)
550{ 754{
551 /* Not implemented */ 755 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx;
552 return NULL; 756 struct GNUNET_CLIENT_Connection *client;
757
758 client = GNUNET_CLIENT_connect ("transport", cfg);
759 if (client == NULL)
760 return NULL;
761 if (GNUNET_YES != one_shot)
762 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
763 val_ctx = GNUNET_new (struct GNUNET_TRANSPORT_ValidationMonitoringContext);
764 val_ctx->cb = validation_callback;
765 val_ctx->cb_cls = validation_callback_cls;
766 val_ctx->cfg = cfg;
767 val_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
768 if (NULL != peer)
769 val_ctx->peer = *peer;
770 val_ctx->one_shot = one_shot;
771 val_ctx->client = client;
772 send_val_mon_request (val_ctx);
773
774 return val_ctx;
553} 775}
554 776
555 777
@@ -561,7 +783,17 @@ GNUNET_TRANSPORT_monitor_validation_entries (const struct
561void 783void
562GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic) 784GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic)
563{ 785{
564 /* Not implemented */ 786 if (NULL != vic->client)
787 {
788 GNUNET_CLIENT_disconnect (vic->client);
789 vic->client = NULL;
790 }
791 if (GNUNET_SCHEDULER_NO_TASK != vic->reconnect_task)
792 {
793 GNUNET_SCHEDULER_cancel (vic->reconnect_task);
794 vic->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
795 }
796 GNUNET_free (vic);
565} 797}
566 798
567 799