From cfa7d229b27b9c387351c9bf3c8a9eb7994de13a Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Tue, 7 Jan 2014 16:00:27 +0000 Subject: new monitoring API --- src/transport/Makefile.am | 2 +- src/transport/gnunet-service-transport.h | 13 + src/transport/gnunet-service-transport_clients.c | 18 +- .../gnunet-service-transport_neighbours.c | 169 +----- .../gnunet-service-transport_neighbours.h | 3 +- src/transport/gnunet-transport.c | 633 ++++++++++----------- src/transport/transport.h | 34 +- src/transport/transport_api_address_lookup.c | 364 ------------ src/transport/transport_api_monitoring.c | 460 +++++++++++++++ 9 files changed, 801 insertions(+), 895 deletions(-) delete mode 100644 src/transport/transport_api_address_lookup.c create mode 100644 src/transport/transport_api_monitoring.c (limited to 'src/transport') diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index e6ecf4ffe..1221cdbea 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -134,7 +134,7 @@ libgnunettransport_la_SOURCES = \ transport_api.c transport.h \ transport_api_blacklist.c \ transport_api_address_to_string.c \ - transport_api_address_lookup.c + transport_api_monitoring.c libgnunettransport_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h index 1a079e167..cc83f2c83 100644 --- a/src/transport/gnunet-service-transport.h +++ b/src/transport/gnunet-service-transport.h @@ -62,6 +62,19 @@ extern struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key; */ extern struct GNUNET_ATS_SchedulingHandle *GST_ats; + +/** + * Function to call when a peer's address has changed + * + * @param cls closure + * @param peer peer this update is about, + * @param address address, NULL for disconnect notification + */ +typedef void (*GNUNET_TRANSPORT_AddressChangeCallback) (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address); + + /** * Function called by the transport for each received message. * This function should also be called with "NULL" for the diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index 8679f40b4..7c4a9d712 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c @@ -851,11 +851,11 @@ clients_handle_address_to_string (void *cls, * @param address the address, NULL on disconnect * @return composed message */ -static struct AddressIterateResponseMessage * +static struct PeerIterateResponseMessage * compose_address_iterate_response_message (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address) { - struct AddressIterateResponseMessage *msg; + struct PeerIterateResponseMessage *msg; size_t size; size_t tlen; size_t alen; @@ -869,7 +869,7 @@ compose_address_iterate_response_message (const struct GNUNET_PeerIdentity *peer } else tlen = alen = 0; - size = (sizeof (struct AddressIterateResponseMessage) + alen + tlen); + size = (sizeof (struct PeerIterateResponseMessage) + alen + tlen); msg = GNUNET_malloc (size); msg->header.size = htons (size); msg->header.type = @@ -904,7 +904,7 @@ output_address (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) { struct GNUNET_SERVER_TransmitContext *tc = cls; - struct AddressIterateResponseMessage *msg; + struct PeerIterateResponseMessage *msg; msg = compose_address_iterate_response_message (peer, address); GNUNET_SERVER_transmit_context_append_message (tc, &msg->header); @@ -927,7 +927,7 @@ clients_handle_address_iterate (void *cls, struct GNUNET_SERVER_Client *client, { static struct GNUNET_PeerIdentity all_zeros; struct GNUNET_SERVER_TransmitContext *tc; - struct AddressIterateMessage *msg; + struct PeerIterateMessage *msg; struct GNUNET_HELLO_Address *address; if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE) @@ -936,13 +936,13 @@ clients_handle_address_iterate (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - if (ntohs (message->size) != sizeof (struct AddressIterateMessage)) + if (ntohs (message->size) != sizeof (struct PeerIterateMessage)) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - msg = (struct AddressIterateMessage *) message; + msg = (struct PeerIterateMessage *) message; if ( (GNUNET_YES != ntohl (msg->one_shot)) && (NULL != lookup_monitoring_client (client)) ) { @@ -1000,7 +1000,7 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING, 0}, {&clients_handle_address_iterate, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE, - sizeof (struct AddressIterateMessage)}, + sizeof (struct PeerIterateMessage)}, {&GST_blacklist_handle_init, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT, sizeof (struct GNUNET_MessageHeader)}, @@ -1090,7 +1090,7 @@ void GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address) { - struct AddressIterateResponseMessage *msg; + struct PeerIterateResponseMessage *msg; struct MonitoringClient *mc; static struct GNUNET_PeerIdentity all_zeros; msg = compose_address_iterate_response_message (peer, address); diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 7183f1f84..d451991f1 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -231,167 +231,6 @@ struct MessageQueue }; -/** - * Possible state of a neighbour. Initially, we are #S_NOT_CONNECTED. - * - * Then, there are two main paths. If we receive a CONNECT message, we - * first run a check against the blacklist (#S_CONNECT_RECV_BLACKLIST_INBOUND). - * If this check is successful, we give the inbound address to ATS. - * After the check we ask ATS for a suggestion (S_CONNECT_RECV_ATS). - * If ATS makes a suggestion, we ALSO give that suggestion to the blacklist - * (#S_CONNECT_RECV_BLACKLIST). Once the blacklist approves the - * address we got from ATS, we send our CONNECT_ACK and go to - * #S_CONNECT_RECV_ACK. If we receive a SESSION_ACK, we go to - * #S_CONNECTED (and notify everyone about the new connection). If the - * operation times out, we go to #S_DISCONNECT. - * - * The other case is where we transmit a CONNECT message first. We - * start with #S_INIT_ATS. If we get an address, we enter - * #S_INIT_BLACKLIST and check the blacklist. If the blacklist is OK - * with the connection, we actually send the CONNECT message and go to - * state S_CONNECT_SENT. Once we receive a CONNECT_ACK, we go to - * #S_CONNECTED (and notify everyone about the new connection and send - * back a SESSION_ACK). If the operation times out, we go to - * #S_DISCONNECT. - * - * If the session is in trouble (i.e. transport-level disconnect or - * timeout), we go to #S_RECONNECT_ATS where we ask ATS for a new - * address (we don't notify anyone about the disconnect yet). Once we - * have a new address, we go to #S_RECONNECT_BLACKLIST to check the new - * address against the blacklist. If the blacklist approves, we enter - * #S_RECONNECT_SENT and send a CONNECT message. If we receive a - * CONNECT_ACK, we go to #S_CONNECTED and nobody noticed that we had - * trouble; we also send a SESSION_ACK at this time just in case. If - * the operation times out, we go to S_DISCONNECT (and notify everyone - * about the lost connection). - * - * If ATS decides to switch addresses while we have a normal - * connection, we go to #S_CONNECTED_SWITCHING_BLACKLIST to check the - * new address against the blacklist. If the blacklist approves, we - * go to #S_CONNECTED_SWITCHING_CONNECT_SENT and send a - * SESSION_CONNECT. If we get a SESSION_ACK back, we switch the - * primary connection to the suggested alternative from ATS, go back - * to #S_CONNECTED and send a SESSION_ACK to the other peer just to be - * sure. If the operation times out (or the blacklist disapproves), - * we go to #S_CONNECTED (and notify ATS that the given alternative - * address is "invalid"). - * - * Once a session is in #S_DISCONNECT, it is cleaned up and then goes - * to (#S_DISCONNECT_FINISHED). If we receive an explicit disconnect - * request, we can go from any state to #S_DISCONNECT, possibly after - * generating disconnect notifications. - * - * Note that it is quite possible that while we are in any of these - * states, we could receive a 'CONNECT' request from the other peer. - * We then enter a 'weird' state where we pursue our own primary state - * machine (as described above), but with the 'send_connect_ack' flag - * set to 1. If our state machine allows us to send a 'CONNECT_ACK' - * (because we have an acceptable address), we send the 'CONNECT_ACK' - * and set the 'send_connect_ack' to 2. If we then receive a - * 'SESSION_ACK', we go to #S_CONNECTED (and reset 'send_connect_ack' - * to 0). - * - */ -enum State -{ - /** - * fresh peer or completely disconnected - */ - S_NOT_CONNECTED = 0, - - /** - * Asked to initiate connection, trying to get address from ATS - */ - S_INIT_ATS, - - /** - * Asked to initiate connection, trying to get address approved - * by blacklist. - */ - S_INIT_BLACKLIST, - - /** - * Sent CONNECT message to other peer, waiting for CONNECT_ACK - */ - S_CONNECT_SENT, - - /** - * Received a CONNECT, do a blacklist check for inbound address - */ - S_CONNECT_RECV_BLACKLIST_INBOUND, - - /** - * Received a CONNECT, asking ATS about address suggestions. - */ - S_CONNECT_RECV_ATS, - - /** - * Received CONNECT from other peer, got an address, checking with blacklist. - */ - S_CONNECT_RECV_BLACKLIST, - - /** - * CONNECT request from other peer was SESSION_ACK'ed, waiting for - * SESSION_ACK. - */ - S_CONNECT_RECV_ACK, - - /** - * Got our CONNECT_ACK/SESSION_ACK, connection is up. - */ - S_CONNECTED, - - /** - * Connection got into trouble, rest of the system still believes - * it to be up, but we're getting a new address from ATS. - */ - S_RECONNECT_ATS, - - /** - * Connection got into trouble, rest of the system still believes - * it to be up; we are checking the new address against the blacklist. - */ - S_RECONNECT_BLACKLIST, - - /** - * Sent CONNECT over new address (either by ATS telling us to switch - * addresses or from RECONNECT_ATS); if this fails, we need to tell - * the rest of the system about a disconnect. - */ - S_RECONNECT_SENT, - - /** - * We have some primary connection, but ATS suggested we switch - * to some alternative; we're now checking the alternative against - * the blacklist. - */ - S_CONNECTED_SWITCHING_BLACKLIST, - - /** - * We have some primary connection, but ATS suggested we switch - * to some alternative; we now sent a CONNECT message for the - * alternative session to the other peer and waiting for a - * CONNECT_ACK to make this our primary connection. - */ - S_CONNECTED_SWITCHING_CONNECT_SENT, - - /** - * Disconnect in progress (we're sending the DISCONNECT message to the - * other peer; after that is finished, the state will be cleaned up). - */ - S_DISCONNECT, - - /** - * We're finished with the disconnect; and are cleaning up the state - * now! We put the struct into this state when we are really in the - * task that calls 'free' on it and are about to remove the record - * from the map. We should never find a 'struct NeighbourMapEntry' - * in this state in the map. Accessing a 'struct NeighbourMapEntry' - * in this state virtually always means using memory that has been - * freed (the exception being the cleanup code in #free_neighbour()). - */ - S_DISCONNECT_FINISHED -}; /** @@ -534,7 +373,7 @@ struct NeighbourMapEntry /** * The current state of the peer. */ - enum State state; + enum GNUNET_TRANSPORT_PeerState state; /** * Did we sent an KEEP_ALIVE message and are we expecting a response? @@ -641,7 +480,7 @@ static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb; /** * Function to call when we changed an active address of a neighbour. */ -static GNUNET_TRANSPORT_PeerIterateCallback address_change_cb; +static GNUNET_TRANSPORT_AddressChangeCallback address_change_cb; /** * counter for connected neighbours @@ -681,7 +520,7 @@ lookup_neighbour (const struct GNUNET_PeerIdentity *pid) * @return corresponding string */ static const char * -print_state (enum State state) +print_state (enum GNUNET_TRANSPORT_PeerState state) { switch (state) { @@ -3616,7 +3455,7 @@ void GST_neighbours_start (void *cls, NotifyConnect connect_cb, GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, - GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb, + GNUNET_TRANSPORT_AddressChangeCallback peer_address_cb, unsigned int max_fds) { callback_cls = cls; diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index b5abcf5da..c72b298c5 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h @@ -29,6 +29,7 @@ #include "gnunet_statistics_service.h" #include "gnunet_transport_service.h" #include "gnunet_transport_plugin.h" +#include "gnunet-service-transport.h" #include "transport.h" #include "gnunet_util_lib.h" @@ -50,7 +51,7 @@ void GST_neighbours_start (void *cls, NotifyConnect connect_cb, GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, - GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb, + GNUNET_TRANSPORT_AddressChangeCallback peer_address_cb, unsigned int max_fds); diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index aff4d30aa..a6ffb2bab 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c @@ -1,22 +1,22 @@ /* - This file is part of GNUnet. - (C) 2011 Christian Grothoff (and other contributing authors) + This file is part of GNUnet. + (C) 2011 Christian Grothoff (and other contributing authors) - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ /** * @file src/transport/gnunet-transport.c @@ -48,7 +48,6 @@ */ #define BLOCKSIZE 4 - /** * Which peer should we connect to? */ @@ -89,6 +88,11 @@ static int benchmark_receive; */ static int iterate_connections; +/** + * Option -a. + */ +static int iterate_all; + /** * Option -t. */ @@ -147,7 +151,7 @@ static struct GNUNET_TRANSPORT_TransmitHandle *th; /** * */ -struct GNUNET_TRANSPORT_PeerIterateContext *pic; +struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; /** * Identity of the peer we transmit to / connect to. @@ -213,7 +217,6 @@ struct TestContext }; - /** * Task run in monitor mode when the user presses CTRL-C to abort. * Stops monitoring activity. @@ -222,54 +225,53 @@ struct TestContext * @param tc scheduler context */ static void -shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_TIME_Relative duration; end = GNUNET_SCHEDULER_NO_TASK; if (GNUNET_SCHEDULER_NO_TASK != op_timeout) { - GNUNET_SCHEDULER_cancel (op_timeout); - op_timeout = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; } if (NULL != tc_handle) { - GNUNET_TRANSPORT_try_connect_cancel (tc_handle); - tc_handle = NULL; + GNUNET_TRANSPORT_try_connect_cancel (tc_handle); + tc_handle = NULL; } if (NULL != pic) { - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic); - pic = NULL; + GNUNET_TRANSPORT_monitor_peers_cancel (pic); + pic = NULL; } if (NULL != th) { - GNUNET_TRANSPORT_notify_transmit_ready_cancel(th); + GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); th = NULL; } if (NULL != handle) { - GNUNET_TRANSPORT_disconnect(handle); + GNUNET_TRANSPORT_disconnect (handle); handle = NULL; } if (benchmark_send) { duration = GNUNET_TIME_absolute_get_duration (start_time); FPRINTF (stdout, _("Transmitted %llu bytes/s (%llu bytes in %s)\n"), - 1000LL * 1000LL * traffic_sent / (1 + duration.rel_value_us), traffic_sent, - GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); + 1000LL * 1000LL * traffic_sent / (1 + duration.rel_value_us), + traffic_sent, + GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); } if (benchmark_receive) { duration = GNUNET_TIME_absolute_get_duration (start_time); FPRINTF (stdout, _("Received %llu bytes/s (%llu bytes in %s)\n"), - 1000LL * 1000LL * traffic_received / (1 + duration.rel_value_us), - traffic_received, - GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); + 1000LL * 1000LL * traffic_received / (1 + duration.rel_value_us), + traffic_received, + GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); } } - static struct ResolutionContext *rc_head; static struct ResolutionContext *rc_tail; @@ -282,50 +284,45 @@ struct ResolutionContext int printed; }; - static void -operation_timeout (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +operation_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct ResolutionContext *cur; struct ResolutionContext *next; op_timeout = GNUNET_SCHEDULER_NO_TASK; - if ((try_connect) || (benchmark_send) || - (benchmark_receive)) + if ((try_connect) || (benchmark_send) || (benchmark_receive)) { - FPRINTF (stdout, _("Failed to connect to `%s'\n"), GNUNET_i2s_full (&pid)); - if (GNUNET_SCHEDULER_NO_TASK != end) - GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); - ret = 1; - return; + FPRINTF (stdout, _("Failed to connect to `%s'\n"), GNUNET_i2s_full (&pid)); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); + ret = 1; + return; } if (iterate_connections) { - next = rc_head; - while (NULL != (cur = next)) - { - next = cur->next; - FPRINTF (stdout, _("Failed to resolve address for peer `%s'\n"), - GNUNET_i2s (&cur->addrcp->peer)); - - GNUNET_CONTAINER_DLL_remove (rc_head, rc_tail, cur); - GNUNET_TRANSPORT_address_to_string_cancel (cur->asc); - GNUNET_free (cur->addrcp); - GNUNET_free (cur); - - } - FPRINTF (stdout, "%s", _("Failed to list connections, timeout occured\n")); - if (GNUNET_SCHEDULER_NO_TASK != end) - GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); - ret = 1; - return; - } + next = rc_head; + while (NULL != (cur = next)) + { + next = cur->next; + FPRINTF (stdout, _("Failed to resolve address for peer `%s'\n"), + GNUNET_i2s (&cur->addrcp->peer)); -} + GNUNET_CONTAINER_DLL_remove(rc_head, rc_tail, cur); + GNUNET_TRANSPORT_address_to_string_cancel (cur->asc); + GNUNET_free(cur->addrcp); + GNUNET_free(cur); + } + FPRINTF (stdout, "%s", _("Failed to list connections, timeout occured\n") ); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); + ret = 1; + return; + } +} /** * Display the result of the test. @@ -354,17 +351,16 @@ display_test_result (struct TestContext *tc, int result) GNUNET_NAT_test_stop (tc->tst); tc->tst = NULL; } - GNUNET_free (tc); + GNUNET_free(tc); resolver_users--; if ((0 == resolver_users) && (NULL != resolver)) { - GNUNET_break (0 == GNUNET_OS_process_kill (resolver, GNUNET_TERM_SIG)); + GNUNET_break(0 == GNUNET_OS_process_kill (resolver, GNUNET_TERM_SIG)); GNUNET_OS_process_destroy (resolver); resolver = NULL; } } - /** * Function called by NAT on success. * Clean up and update GUI (with success). @@ -374,16 +370,13 @@ display_test_result (struct TestContext *tc, int result) * @param emsg error message, NULL on success */ static void -result_callback (void *cls, - int success, - const char *emsg) +result_callback (void *cls, int success, const char *emsg) { struct TestContext *tc = cls; display_test_result (tc, success); } - /** * Function called if NAT failed to confirm success. * Clean up and update GUI (with failure). @@ -400,7 +393,6 @@ fail_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) display_test_result (tstc, GNUNET_NO); } - /** * Test our plugin's configuration (NAT traversal, etc.). * @@ -416,53 +408,47 @@ do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) struct TestContext *tc; char *binary; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "transport", "plugins", - &plugins)) + if (GNUNET_OK + != GNUNET_CONFIGURATION_get_value_string (cfg, "transport", "plugins", + &plugins)) { - FPRINTF (stderr, - "%s", - _ - ("No transport plugins configured, peer will never communicate\n")); + FPRINTF (stderr, "%s", _ + ("No transport plugins configured, peer will never communicate\n") ); ret = 4; return; } - for (tok = strtok (plugins, " "); tok != NULL; tok = strtok (NULL, " ")) + for (tok = strtok (plugins, " "); tok != NULL ; tok = strtok (NULL, " ")) { char section[12 + strlen (tok)]; - GNUNET_snprintf (section, sizeof (section), "transport-%s", tok); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, section, "PORT", &bnd_port)) + GNUNET_snprintf (section, sizeof(section), "transport-%s", tok); + if (GNUNET_OK + != GNUNET_CONFIGURATION_get_value_number (cfg, section, "PORT", + &bnd_port)) { FPRINTF (stderr, - _("No port configured for plugin `%s', cannot test it\n"), tok); + _("No port configured for plugin `%s', cannot test it\n"), tok); continue; } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, section, "ADVERTISED_PORT", - &adv_port)) + if (GNUNET_OK + != GNUNET_CONFIGURATION_get_value_number (cfg, section, + "ADVERTISED_PORT", &adv_port)) adv_port = bnd_port; if (NULL == resolver) { binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver"); - resolver = - GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, - binary, - "gnunet-service-resolver", NULL); - GNUNET_free (binary); + resolver = GNUNET_OS_start_process (GNUNET_YES, + GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, binary, + "gnunet-service-resolver", NULL ); + GNUNET_free(binary); } resolver_users++; GNUNET_RESOLVER_connect (cfg); tc = GNUNET_new (struct TestContext); tc->name = GNUNET_strdup (tok); - tc->tst = - GNUNET_NAT_test_start (cfg, - (0 == - strcasecmp (tok, - "udp")) ? GNUNET_NO : GNUNET_YES, - (uint16_t) bnd_port, (uint16_t) adv_port, - &result_callback, tc); + tc->tst = GNUNET_NAT_test_start (cfg, + (0 == strcasecmp (tok, "udp")) ? GNUNET_NO : GNUNET_YES, + (uint16_t) bnd_port, (uint16_t) adv_port, &result_callback, tc); if (NULL == tc->tst) { display_test_result (tc, GNUNET_SYSERR); @@ -470,10 +456,9 @@ do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) } tc->tsk = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &fail_timeout, tc); } - GNUNET_free (plugins); + GNUNET_free(plugins); } - /** * Function called to notify a client about the socket * begin ready to queue more data. @a buf will be @@ -496,22 +481,20 @@ transmit_data (void *cls, size_t size, void *buf) return 0; } - GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); - GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); + GNUNET_assert(size >= sizeof(struct GNUNET_MessageHeader)); + GNUNET_assert(size < GNUNET_SERVER_MAX_MESSAGE_SIZE); m->size = ntohs (size); m->type = ntohs (GNUNET_MESSAGE_TYPE_DUMMY); - memset (&m[1], 52, size - sizeof (struct GNUNET_MessageHeader)); + memset (&m[1], 52, size - sizeof(struct GNUNET_MessageHeader)); traffic_sent += size; - th = GNUNET_TRANSPORT_notify_transmit_ready (handle, &pid, BLOCKSIZE * 1024, 0, - GNUNET_TIME_UNIT_FOREVER_REL, - &transmit_data, NULL); + th = GNUNET_TRANSPORT_notify_transmit_ready (handle, &pid, BLOCKSIZE * 1024, + 0, GNUNET_TIME_UNIT_FOREVER_REL, &transmit_data, NULL ); if (verbosity > 0) FPRINTF (stdout, _("Transmitting %u bytes to %s\n"), (unsigned int) size, - GNUNET_i2s (&pid)); + GNUNET_i2s (&pid)); return size; } - /** * Function called to notify transport users that another * peer connected to us. @@ -522,27 +505,26 @@ transmit_data (void *cls, size_t size, void *buf) static void notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer) { - if (0 != memcmp (&pid, peer, sizeof (struct GNUNET_PeerIdentity))) + if (0 != memcmp (&pid, peer, sizeof(struct GNUNET_PeerIdentity))) return; ret = 0; if (try_connect) { - /* all done, terminate instantly */ - FPRINTF (stdout, - _("Successfully connected to `%s'\n"), - GNUNET_i2s_full (peer)); - ret = 0; + /* all done, terminate instantly */ + FPRINTF (stdout, _("Successfully connected to `%s'\n"), + GNUNET_i2s_full (peer)); + ret = 0; - if (GNUNET_SCHEDULER_NO_TASK != op_timeout) - { - GNUNET_SCHEDULER_cancel (op_timeout); - op_timeout = GNUNET_SCHEDULER_NO_TASK; - } + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + { + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; + } - if (GNUNET_SCHEDULER_NO_TASK != end) - GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); - return; + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); + return; } if (benchmark_send) { @@ -552,21 +534,20 @@ notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer) op_timeout = GNUNET_SCHEDULER_NO_TASK; } if (verbosity > 0) - FPRINTF (stdout, _("Successfully connected to `%s', starting to send benchmark data in %u Kb blocks\n"), + FPRINTF (stdout, + _("Successfully connected to `%s', starting to send benchmark data in %u Kb blocks\n"), GNUNET_i2s (&pid), BLOCKSIZE); start_time = GNUNET_TIME_absolute_get (); if (NULL == th) th = GNUNET_TRANSPORT_notify_transmit_ready (handle, peer, - BLOCKSIZE * 1024, 0, - GNUNET_TIME_UNIT_FOREVER_REL, - &transmit_data, NULL); + BLOCKSIZE * 1024, 0, GNUNET_TIME_UNIT_FOREVER_REL, &transmit_data, + NULL ); else - GNUNET_break (0); + GNUNET_break(0); return; } } - /** * Function called to notify transport users that another * peer disconnected from us. @@ -577,7 +558,7 @@ notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer) static void notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) { - if (0 != memcmp (&pid, peer, sizeof (struct GNUNET_PeerIdentity))) + if (0 != memcmp (&pid, peer, sizeof(struct GNUNET_PeerIdentity))) return; if (NULL != th) @@ -587,10 +568,11 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) } if (benchmark_send) { - FPRINTF (stdout, _("Disconnected from peer `%s' while benchmarking\n"), GNUNET_i2s (&pid)); - if (GNUNET_SCHEDULER_NO_TASK != end) - GNUNET_SCHEDULER_cancel (end); - return; + FPRINTF (stdout, _("Disconnected from peer `%s' while benchmarking\n"), + GNUNET_i2s (&pid)); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + return; } } @@ -604,19 +586,14 @@ notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) static void monitor_notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer) { - monitor_connect_counter ++; - struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); + monitor_connect_counter++; + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); const char *now_str = GNUNET_STRINGS_absolute_time_to_string (now); - FPRINTF (stdout, - _("%24s: %-17s %4s (%u connections in total)\n"), - now_str, - _("Connected to"), - GNUNET_i2s (peer), - monitor_connect_counter); + FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"), now_str, + _("Connected to"), GNUNET_i2s (peer), monitor_connect_counter); } - /** * Function called to notify transport users that another * peer disconnected from us. @@ -627,22 +604,16 @@ monitor_notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer) static void monitor_notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) { - struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); const char *now_str = GNUNET_STRINGS_absolute_time_to_string (now); - GNUNET_assert (monitor_connect_counter > 0); - monitor_connect_counter --; + GNUNET_assert(monitor_connect_counter > 0); + monitor_connect_counter--; - FPRINTF (stdout, - _("%24s: %-17s %4s (%u connections in total)\n"), - now_str, - _("Disconnected from"), - GNUNET_i2s (peer), - monitor_connect_counter); + FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"), now_str, + _("Disconnected from"), GNUNET_i2s (peer), monitor_connect_counter); } - - /** * Function called by the transport for each received message. * @@ -652,16 +623,15 @@ monitor_notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) */ static void notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_MessageHeader *message) { if (benchmark_receive) { if (GNUNET_MESSAGE_TYPE_DUMMY != ntohs (message->type)) return; if (verbosity > 0) - FPRINTF (stdout, - _("Received %u bytes from %s\n"), - (unsigned int) ntohs (message->size), GNUNET_i2s (peer)); + FPRINTF (stdout, _("Received %u bytes from %s\n"), + (unsigned int) ntohs (message->size), GNUNET_i2s (peer)); if (traffic_received == 0) start_time = GNUNET_TIME_absolute_get (); @@ -670,11 +640,8 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer, } } - static void -resolve_address (const struct GNUNET_HELLO_Address *address, - int numeric); - +resolve_address (const struct GNUNET_HELLO_Address *address, int numeric); static void process_string (void *cls, const char *address) @@ -682,136 +649,133 @@ process_string (void *cls, const char *address) struct ResolutionContext *rc = cls; struct GNUNET_HELLO_Address *addrcp = rc->addrcp; - if (address != NULL) + if (address != NULL ) { - FPRINTF (stdout, - _("Peer `%s': %s %s\n"), - GNUNET_i2s (&addrcp->peer), - addrcp->transport_name, - address); + FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (&addrcp->peer), + addrcp->transport_name, address); rc->printed = GNUNET_YES; } else { /* done */ - GNUNET_assert (address_resolutions > 0); - address_resolutions --; + GNUNET_assert(address_resolutions > 0); + address_resolutions--; if (GNUNET_NO == rc->printed) { if (numeric == GNUNET_NO) { - resolve_address (rc->addrcp, GNUNET_YES ); /* Failed to resolve address, try numeric lookup */ + resolve_address (rc->addrcp, GNUNET_YES); /* Failed to resolve address, try numeric lookup */ } else - FPRINTF (stdout, - _("Peer `%s': %s \n"), - GNUNET_i2s (&addrcp->peer), - addrcp->transport_name); + FPRINTF (stdout, _("Peer `%s': %s \n"), + GNUNET_i2s (&addrcp->peer), addrcp->transport_name); } - GNUNET_free (rc->addrcp); - GNUNET_CONTAINER_DLL_remove (rc_head, rc_tail, rc); - GNUNET_free (rc); + GNUNET_free(rc->addrcp); + GNUNET_CONTAINER_DLL_remove(rc_head, rc_tail, rc); + GNUNET_free(rc); if ((0 == address_resolutions) && (iterate_connections)) { - if (GNUNET_SCHEDULER_NO_TASK != end) - { - GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_NO_TASK; - } - if (GNUNET_SCHEDULER_NO_TASK != op_timeout) - { - GNUNET_SCHEDULER_cancel (op_timeout); - op_timeout = GNUNET_SCHEDULER_NO_TASK; - } - ret = 0; - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + if (GNUNET_SCHEDULER_NO_TASK != end) + { + GNUNET_SCHEDULER_cancel (end); + end = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_SCHEDULER_NO_TASK != op_timeout) + { + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_NO_TASK; + } + ret = 0; + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); } } } - static void -resolve_address (const struct GNUNET_HELLO_Address *address, - int numeric) +resolve_address (const struct GNUNET_HELLO_Address *address, int numeric) { struct ResolutionContext *rc; rc = GNUNET_new (struct ResolutionContext); - GNUNET_assert (NULL != rc); - GNUNET_CONTAINER_DLL_insert (rc_head, rc_tail, rc); - address_resolutions ++; + GNUNET_assert(NULL != rc); + GNUNET_CONTAINER_DLL_insert(rc_head, rc_tail, rc); + address_resolutions++; - rc->addrcp = GNUNET_HELLO_address_copy(address); + rc->addrcp = GNUNET_HELLO_address_copy (address); rc->printed = GNUNET_NO; /* Resolve address to string */ rc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric, - RESOLUTION_TIMEOUT, &process_string, - rc); + RESOLUTION_TIMEOUT, &process_string, rc); } /** - * Function to call with a binary address + * Function called with information about a peers * * @param cls closure - * @param peer identity of the peer - * @param address binary address (NULL on disconnect) + * @param peer identity of the peer, NULL for final callback when operation done + * @param address binary address used to communicate with this peer, + * NULL on disconnect or when done + * @param state current state this peer is in + * @param state_timeout time out for the current state + * */ static void -process_address (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_HELLO_Address *address) +process_peer_cb (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + enum GNUNET_TRANSPORT_PeerState state, + struct GNUNET_TIME_Absolute state_timeout) { - if (peer == NULL) + if (peer == NULL ) { /* done */ address_resolution_in_progress = GNUNET_NO; pic = NULL; if (GNUNET_SCHEDULER_NO_TASK != end) GNUNET_SCHEDULER_cancel (end); - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); return; } - if (address == NULL) + if (address == NULL ) { FPRINTF (stdout, _("Peer `%s' disconnected\n"), GNUNET_i2s (peer)); return; } if (GNUNET_SCHEDULER_NO_TASK != op_timeout) - GNUNET_SCHEDULER_cancel (op_timeout); - op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, - &operation_timeout, NULL); + GNUNET_SCHEDULER_cancel (op_timeout); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, + NULL ); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received address for peer `%s': %s\n", - GNUNET_i2s (peer), address->transport_name); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received address for peer `%s': %s\n", + GNUNET_i2s (peer), address->transport_name); resolve_address (address, numeric); } - static void -try_connect_cb (void *cls, - const int result) +try_connect_cb (void *cls, const int result) { static int retries = 0; if (GNUNET_OK == result) { - tc_handle = NULL; - return; + tc_handle = NULL; + return; } - retries ++; + retries++; if (retries < 10) - tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, NULL); + tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, + NULL ); else { - FPRINTF (stderr, "%s", _("Failed to send connect request to transport service\n")); + FPRINTF (stderr, "%s", + _("Failed to send connect request to transport service\n") ); if (GNUNET_SCHEDULER_NO_TASK != end) GNUNET_SCHEDULER_cancel (end); ret = 1; - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL ); return; } } - /** * Function called with the result of the check if the 'transport' * service is running. @@ -820,43 +784,43 @@ try_connect_cb (void *cls, * @param result #GNUNET_YES if transport is running */ static void -testservice_task (void *cls, - int result) +testservice_task (void *cls, int result) { int counter = 0; ret = 1; if (GNUNET_YES != result) { - FPRINTF (stderr, - _("Service `%s' is not running\n"), "transport"); + FPRINTF (stderr, _("Service `%s' is not running\n"), "transport"); return; } - if ( (NULL != cpid) && - (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string (cpid, - strlen (cpid), - &pid.public_key))) + if ((NULL != cpid) + && (GNUNET_OK + != GNUNET_CRYPTO_eddsa_public_key_from_string (cpid, strlen (cpid), + &pid.public_key))) { FPRINTF (stderr, _("Failed to parse peer identity `%s'\n"), cpid); return; } - counter = benchmark_send + benchmark_receive + iterate_connections + - monitor_connections + monitor_connects + try_connect; + counter = benchmark_send + benchmark_receive + iterate_connections + + monitor_connections + monitor_connects + try_connect; if (1 < counter) { FPRINTF (stderr, - _("Multiple operations given. Please choose only one operation: %s, %s, %s, %s, %s, %s\n"), - "connect", "benchmark send", "benchmark receive", "information", "monitor", "events"); + _("Multiple operations given. Please choose only one operation: %s, %s, %s, %s, %s, %s\n"), + "connect", "benchmark send", "benchmark receive", "information", + "monitor", "events"); return; } if (0 == counter) { FPRINTF (stderr, - _("No operation given. Please choose one operation: %s, %s, %s, %s, %s, %s\n"), - "connect", "benchmark send", "benchmark receive", "information", "monitor", "events"); + _("No operation given. Please choose one operation: %s, %s, %s, %s, %s, %s\n"), + "connect", "benchmark send", "benchmark receive", "information", + "monitor", "events"); return; } @@ -864,35 +828,30 @@ testservice_task (void *cls, { if (NULL == cpid) { - FPRINTF (stderr, - _("Option `%s' makes no sense without option `%s'.\n"), - "-C", "-p"); + FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"), + "-C", "-p"); ret = 1; return; } - handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, - ¬ify_receive, - ¬ify_connect, - ¬ify_disconnect); + handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); if (NULL == handle) { - FPRINTF (stderr, - "%s", - _("Failed to connect to transport service\n")); - ret = 1; - return; + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n") ); + ret = 1; + return; } - tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, NULL); + tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, + NULL ); if (NULL == tc_handle) { - FPRINTF (stderr, - "%s", - _("Failed to send request to transport service\n")); + FPRINTF (stderr, "%s", + _("Failed to send request to transport service\n") ); ret = 1; return; } - op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, - &operation_timeout, NULL); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, + NULL ); } else if (benchmark_send) /* -s: Benchmark sending */ @@ -900,76 +859,68 @@ testservice_task (void *cls, if (NULL == cpid) { FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"), - "-s", "-p"); + "-s", "-p"); ret = 1; return; } - handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, - ¬ify_receive, - ¬ify_connect, - ¬ify_disconnect); + handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, + ¬ify_connect, ¬ify_disconnect); if (NULL == handle) { - FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); - ret = 1; - return; + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n") ); + ret = 1; + return; } - tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, NULL); + tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, + NULL ); if (NULL == tc_handle) { - FPRINTF (stderr, "%s", _("Failed to send request to transport service\n")); - ret = 1; - return; + FPRINTF (stderr, "%s", + _("Failed to send request to transport service\n") ); + ret = 1; + return; } start_time = GNUNET_TIME_absolute_get (); - op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, - &operation_timeout, NULL); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, + NULL ); } else if (benchmark_receive) /* -b: Benchmark receiving */ { - handle = - GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, - NULL, NULL); + handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, NULL, + NULL ); if (NULL == handle) { - FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); - ret = 1; - return; + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n") ); + ret = 1; + return; } if (verbosity > 0) - FPRINTF (stdout, "%s", _("Starting to receive benchmark data\n")); + FPRINTF (stdout, "%s", _("Starting to receive benchmark data\n") ); start_time = GNUNET_TIME_absolute_get (); } - else if (iterate_connections) /* -i: List all active addresses once */ + else if (iterate_connections) /* -i: List information about peers once */ { address_resolution_in_progress = GNUNET_YES; - pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, - (NULL == cpid) ? NULL : &pid, - GNUNET_YES, - TIMEOUT, - &process_address, (void *) cfg); - op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, - &operation_timeout, NULL); + pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, + GNUNET_YES, TIMEOUT, &process_peer_cb, (void *) cfg); + op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, + NULL ); } - else if (monitor_connections) /* -m: List all active addresses continously */ + else if (monitor_connections) /* -m: List information about peers continuously */ { address_resolution_in_progress = GNUNET_YES; - pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, - (NULL == cpid) ? NULL : &pid, - GNUNET_NO, - TIMEOUT, - &process_address, (void *) cfg); + pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, + GNUNET_NO, TIMEOUT, &process_peer_cb, (void *) cfg); } - else if (monitor_connects) /* -e : Monitor (dis)connect events continously */ + else if (monitor_connects) /* -e : Monitor (dis)connect events continuously */ { monitor_connect_counter = 0; handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, NULL, - &monitor_notify_connect, - &monitor_notify_disconnect); + &monitor_notify_connect, &monitor_notify_disconnect); if (NULL == handle) { - FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); + FPRINTF (stderr, "%s", _("Failed to connect to transport service\n") ); ret = 1; return; } @@ -977,17 +928,15 @@ testservice_task (void *cls, } else { - GNUNET_break (0); + GNUNET_break(0); return; } end = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, - NULL); + &shutdown_task, NULL ); } - /** * Main function that will be run by the scheduler. * @@ -997,8 +946,8 @@ testservice_task (void *cls, * @param mycfg configuration */ static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *mycfg) +run (void *cls, char * const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *mycfg) { cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg; if (test_configuration) @@ -1006,62 +955,54 @@ run (void *cls, char *const *args, const char *cfgfile, do_test_configuration (cfg); return; } - GNUNET_CLIENT_service_test ("transport", cfg, - GNUNET_TIME_UNIT_SECONDS, - &testservice_task, - (void *) cfg); + GNUNET_CLIENT_service_test ("transport", cfg, GNUNET_TIME_UNIT_SECONDS, + &testservice_task, (void *) cfg); } - int -main (int argc, char *const *argv) +main (int argc, char * const *argv) { int res; - static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'b', "benchmark", NULL, - gettext_noop ("measure how fast we are receiving data from all peers (until CTRL-C)"), - 0, &GNUNET_GETOPT_set_one, &benchmark_receive}, - {'C', "connect", NULL, - gettext_noop ("connect to a peer"), - 0, &GNUNET_GETOPT_set_one, &try_connect}, - {'i', "information", NULL, - gettext_noop ("provide information about all current connections (once)"), - 0, &GNUNET_GETOPT_set_one, &iterate_connections}, - {'m', "monitor", NULL, - gettext_noop ("provide information about all current connections (continuously)"), - 0, &GNUNET_GETOPT_set_one, &monitor_connections}, - {'e', "events", NULL, - gettext_noop ("provide information about all connects and disconnect events (continuously)"), - 0, &GNUNET_GETOPT_set_one, &monitor_connects}, - {'n', "numeric", NULL, - gettext_noop ("do not resolve hostnames"), - 0, &GNUNET_GETOPT_set_one, &numeric}, - {'p', "peer", "PEER", - gettext_noop ("peer identity"), - 1, &GNUNET_GETOPT_set_string, &cpid}, - {'s', "send", NULL, - gettext_noop - ("send data for benchmarking to the other peer (until CTRL-C)"), - 0, &GNUNET_GETOPT_set_one, &benchmark_send}, - {'t', "test", NULL, - gettext_noop ("test transport configuration (involves external server)"), - 0, &GNUNET_GETOPT_set_one, &test_configuration}, - GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), - GNUNET_GETOPT_OPTION_END - }; + static const struct GNUNET_GETOPT_CommandLineOption options[] = + { + { 'a', "all", NULL, + gettext_noop ("print information for all peers (instead of only connected peers )"), + 0, &GNUNET_GETOPT_set_one, &iterate_all }, + { 'b', "benchmark", NULL, + gettext_noop ("measure how fast we are receiving data from all peers (until CTRL-C)"), + 0, &GNUNET_GETOPT_set_one, &benchmark_receive }, { 'C', "connect", + NULL, gettext_noop ("connect to a peer"), 0, + &GNUNET_GETOPT_set_one, &try_connect }, + { 'i', "information", NULL, + gettext_noop ("provide information about all current connections (once)"), + 0, &GNUNET_GETOPT_set_one, &iterate_connections }, + { 'm', "monitor", NULL, + gettext_noop ("provide information about all current connections (continuously)"), + 0, &GNUNET_GETOPT_set_one, &monitor_connections }, + { 'e', "events", NULL, + gettext_noop ("provide information about all connects and disconnect events (continuously)"), + 0, &GNUNET_GETOPT_set_one, &monitor_connects }, { 'n', "numeric", + NULL, gettext_noop ("do not resolve hostnames"), 0, + &GNUNET_GETOPT_set_one, &numeric }, { 'p', "peer", "PEER", + gettext_noop ("peer identity"), 1, &GNUNET_GETOPT_set_string, + &cpid }, { 's', "send", NULL, gettext_noop + ("send data for benchmarking to the other peer (until CTRL-C)"), 0, + &GNUNET_GETOPT_set_one, &benchmark_send }, + { 't', "test", NULL, + gettext_noop ("test transport configuration (involves external server)"), + 0, &GNUNET_GETOPT_set_one, &test_configuration }, + GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), + GNUNET_GETOPT_OPTION_END }; if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) return 2; - res = GNUNET_PROGRAM_run (argc, argv, "gnunet-transport", - gettext_noop - ("Direct access to transport service."), options, - &run, NULL); - GNUNET_free ((void *) argv); + res = GNUNET_PROGRAM_run (argc, argv, "gnunet-transport", gettext_noop + ("Direct access to transport service."), options, &run, NULL ); + GNUNET_free((void * ) argv); if (GNUNET_OK == res) return ret; return 1; } - /* end of gnunet-transport.c */ diff --git a/src/transport/transport.h b/src/transport/transport.h index f1376f5a7..75cdd729c 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -341,11 +341,12 @@ struct AddressLookupMessage }; +#if 0 /** * Message from the library to the transport service * asking for human readable addresses known for a peer. */ -struct PeerAddressLookupMessage +struct PeerLookupMessage { /** * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PEER_ADDRESS_LOOKUP @@ -367,13 +368,14 @@ struct PeerAddressLookupMessage */ struct GNUNET_PeerIdentity peer; }; +#endif /** * Message from the library to the transport service * asking for binary addresses known for a peer. */ -struct AddressIterateMessage +struct PeerIterateMessage { /** * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE @@ -427,15 +429,19 @@ struct TrafficMetricMessage /** - * Message from the transport service to the library - * containing binary addresses known for a peer. + * Message from the transport service to the library containing information + * about a peer. Information contained are: + * - current address used to communicate with this peer + * - state + * - state timeout + * * Memory layout: * [AddressIterateResponseMessage][address[addrlen]][transportname[pluginlen]] */ -struct AddressIterateResponseMessage +struct PeerIterateResponseMessage { /** - * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE + * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE */ struct GNUNET_MessageHeader header; @@ -444,18 +450,28 @@ struct AddressIterateResponseMessage */ uint32_t reserved; - /** + /** * Peer identity */ struct GNUNET_PeerIdentity peer; /** - * address length + * Timeout for the state this peer is in + */ + struct GNUNET_TIME_AbsoluteNBO state_timeout; + + /** + * State this peer is in as #GNUNET_TRANSPORT_PeerState enumeration element + */ + uint32_t state GNUNET_PACKED; + + /** + * Address length */ uint32_t addrlen GNUNET_PACKED; /** - * length of the plugin name + * Length of the plugin name */ uint32_t pluginlen GNUNET_PACKED; diff --git a/src/transport/transport_api_address_lookup.c b/src/transport/transport_api_address_lookup.c deleted file mode 100644 index d547b8ed8..000000000 --- a/src/transport/transport_api_address_lookup.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -/** - * @file transport/transport_api_address_lookup.c - * @brief given a peer id, get all known addresses from transport service - * - * This api provides the ability to query the transport service about - * the status of connections to a specific peer. Calls back with a - * pretty printed string of the address, as formatted by the appropriate - * transport plugin, and whether or not the address given is currently - * in the 'connected' state (according to the transport service). - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" -#include "gnunet_hello_lib.h" -#include "gnunet_protocols.h" -#include "gnunet_transport_service.h" -#include "transport.h" - -/** - * Context for the address lookup. - */ -struct GNUNET_TRANSPORT_PeerIterateContext -{ - /** - * Function to call with the binary address. - */ - GNUNET_TRANSPORT_PeerIterateCallback cb; - - /** - * Closure for cb. - */ - void *cb_cls; - - /** - * Connection to the service. - */ - struct GNUNET_CLIENT_Connection *client; - - /** - * Configuration we use. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * When should this operation time out? - */ - struct GNUNET_TIME_Absolute timeout; - - /** - * Backoff for reconnect. - */ - struct GNUNET_TIME_Relative backoff; - - /** - * Task ID for reconnect. - */ - GNUNET_SCHEDULER_TaskIdentifier reconnect_task; - - /** - * Identity of the peer to monitor. - */ - struct GNUNET_PeerIdentity peer; - - /** - * Was this a one-shot request? - */ - int one_shot; -}; - - -/** - * Function called with responses from the service. - * - * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' - * @param msg NULL on timeout or error, otherwise presumably a - * message with the human-readable address - */ -static void -peer_address_response_processor (void *cls, - const struct GNUNET_MessageHeader *msg); - - -/** - * Send our subscription request to the service. - * - * @param pal_ctx our context - */ -static void -send_request (struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx) -{ - struct AddressIterateMessage msg; - - msg.header.size = htons (sizeof (struct AddressIterateMessage)); - msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE); - msg.one_shot = htonl (pal_ctx->one_shot); - msg.timeout = GNUNET_TIME_absolute_hton (pal_ctx->timeout); - msg.peer = pal_ctx->peer; - GNUNET_assert (GNUNET_OK == - GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client, - &msg.header, - GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout), - GNUNET_YES, - &peer_address_response_processor, - pal_ctx)); -} - -/** - * Task run to re-establish the connection. - * - * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' - * @param tc scheduler context, unused - */ -static void -do_connect (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx = cls; - - pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg); - GNUNET_assert (NULL != pal_ctx->client); - send_request (pal_ctx); -} - - -/** - * Cut the existing connection and reconnect. - * - * @param pal_ctx our context - */ -static void -reconnect (struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx) -{ - GNUNET_assert (GNUNET_NO == pal_ctx->one_shot); - GNUNET_CLIENT_disconnect (pal_ctx->client); - pal_ctx->client = NULL; - pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff); - pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff, - &do_connect, - pal_ctx); -} - - -/** - * Function called with responses from the service. - * - * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' - * @param msg NULL on timeout or error, otherwise presumably a - * message with the human-readable address - */ -static void -peer_address_response_processor (void *cls, - const struct GNUNET_MessageHeader *msg) -{ - struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx = cls; - struct AddressIterateResponseMessage *air_msg; - struct GNUNET_HELLO_Address *address; - const char *addr; - const char *transport_name; - uint16_t size; - size_t alen; - size_t tlen; - - if (msg == NULL) - { - if (pal_ctx->one_shot) - { - pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); - } - else - { - reconnect (pal_ctx); - } - return; - } - size = ntohs (msg->size); - GNUNET_break (ntohs (msg->type) == - GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); - if (size == sizeof (struct GNUNET_MessageHeader)) - { - /* done! */ - if (pal_ctx->one_shot) - { - pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); - } - else - { - reconnect (pal_ctx); - } - return; - } - - if ((size < sizeof (struct AddressIterateResponseMessage)) || - (ntohs (msg->type) != - GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE)) - { - GNUNET_break (0); - if (pal_ctx->one_shot) - { - pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); - } - else - { - reconnect (pal_ctx); - } - return; - } - - air_msg = (struct AddressIterateResponseMessage *) msg; - tlen = ntohl (air_msg->pluginlen); - alen = ntohl (air_msg->addrlen); - - if (size != sizeof (struct AddressIterateResponseMessage) + tlen + alen) - { - GNUNET_break (0); - if (pal_ctx->one_shot) - { - pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); - } - else - { - reconnect (pal_ctx); - } - return; - } - - if (alen == 0 && tlen == 0) - { - pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, NULL); - } - else - { - addr = (const char *) &air_msg[1]; - transport_name = &addr[alen]; - - if (transport_name[tlen - 1] != '\0') - { - GNUNET_break (0); - if (pal_ctx->one_shot) - { - pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); - GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); - } - else - { - reconnect (pal_ctx); - } - return; - } - - /* notify client */ - address = - GNUNET_HELLO_address_allocate (&air_msg->peer, transport_name, addr, - alen); - pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, address); - GNUNET_HELLO_address_free (address); - } - - /* expect more replies */ - GNUNET_CLIENT_receive (pal_ctx->client, &peer_address_response_processor, - pal_ctx, - GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout)); -} - - -/** - * Return all the known addresses for a specific peer or all peers. - * Returns continuously all address if one_shot is set to GNUNET_NO - * - * CHANGE: Returns the address(es) that we are currently using for this - * peer. Upon completion, the 'AddressLookUpCallback' is called one more - * time with 'NULL' for the address and the peer. After this, the operation must no - * longer be explicitly canceled. - * - * @param cfg configuration to use - * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers - * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), - * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled) - * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO) - * @param peer_address_callback function to call with the results - * @param peer_address_callback_cls closure for peer_address_callback - */ -struct GNUNET_TRANSPORT_PeerIterateContext * -GNUNET_TRANSPORT_peer_get_active_addresses (const struct - GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_PeerIdentity - *peer, int one_shot, - struct GNUNET_TIME_Relative timeout, - GNUNET_TRANSPORT_PeerIterateCallback - peer_address_callback, - void *peer_address_callback_cls) -{ - struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx; - struct GNUNET_CLIENT_Connection *client; - - client = GNUNET_CLIENT_connect ("transport", cfg); - if (client == NULL) - return NULL; - if (GNUNET_YES != one_shot) - timeout = GNUNET_TIME_UNIT_FOREVER_REL; - pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerIterateContext); - pal_ctx->cb = peer_address_callback; - pal_ctx->cb_cls = peer_address_callback_cls; - pal_ctx->cfg = cfg; - pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); - if (NULL != peer) - pal_ctx->peer = *peer; - pal_ctx->one_shot = one_shot; - pal_ctx->client = client; - send_request (pal_ctx); - - return pal_ctx; -} - - -/** - * Cancel request for address conversion. - * - * @param alc handle for the request to cancel - */ -void -GNUNET_TRANSPORT_peer_get_active_addresses_cancel (struct - GNUNET_TRANSPORT_PeerIterateContext - *alc) -{ - if (NULL != alc->client) - { - GNUNET_CLIENT_disconnect (alc->client); - alc->client = NULL; - } - if (GNUNET_SCHEDULER_NO_TASK != alc->reconnect_task) - { - GNUNET_SCHEDULER_cancel (alc->reconnect_task); - alc->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - } - GNUNET_free (alc); -} - - -/* end of transport_api_peer_address_lookup.c */ diff --git a/src/transport/transport_api_monitoring.c b/src/transport/transport_api_monitoring.c new file mode 100644 index 000000000..d7bc56e09 --- /dev/null +++ b/src/transport/transport_api_monitoring.c @@ -0,0 +1,460 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file transport/transport_api_montoring.c + * @brief montoring api for transport peer status and validation entries + * + * This api provides the ability to query the transport service about + * the status of a specific or all peers as well as address validation entries. + * + * Calls back with information about peer(s) including address used, state and + * state timeout for peer requests and address, address lifetime and next revalidation + * for validation entries. + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_hello_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_transport_service.h" +#include "transport.h" + +/** + * Context for iterating validation entries. + */ +struct GNUNET_TRANSPORT_PeerMonitoringContext +{ + /** + * Function to call with the binary address. + */ + GNUNET_TRANSPORT_PeerIterateCallback cb; + + /** + * Closure for cb. + */ + void *cb_cls; + + /** + * Connection to the service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Configuration we use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * When should this operation time out? + */ + struct GNUNET_TIME_Absolute timeout; + + /** + * Backoff for reconnect. + */ + struct GNUNET_TIME_Relative backoff; + + /** + * Task ID for reconnect. + */ + GNUNET_SCHEDULER_TaskIdentifier reconnect_task; + + /** + * Identity of the peer to monitor. + */ + struct GNUNET_PeerIdentity peer; + + /** + * Was this a one-shot request? + */ + int one_shot; +}; + + +/** + * Context for the address lookup. + */ +struct GNUNET_TRANSPORT_ValidationMonitoringContext +{ + /** + * Function to call with the binary address. + */ + GNUNET_TRANSPORT_ValidationIterateCallback cb; + + /** + * Closure for cb. + */ + void *cb_cls; + + /** + * Connection to the service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Configuration we use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * When should this operation time out? + */ + struct GNUNET_TIME_Absolute timeout; + + /** + * Backoff for reconnect. + */ + struct GNUNET_TIME_Relative backoff; + + /** + * Task ID for reconnect. + */ + GNUNET_SCHEDULER_TaskIdentifier reconnect_task; + + /** + * Identity of the peer to monitor. + */ + struct GNUNET_PeerIdentity peer; + + /** + * Was this a one-shot request? + */ + int one_shot; +}; + + + +/** + * Function called with responses from the service. + * + * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' + * @param msg NULL on timeout or error, otherwise presumably a + * message with the human-readable address + */ +static void +peer_address_response_processor (void *cls, + const struct GNUNET_MessageHeader *msg); + + +/** + * Send our subscription request to the service. + * + * @param pal_ctx our context + */ +static void +send_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) +{ + struct PeerIterateMessage msg; + + msg.header.size = htons (sizeof (struct PeerIterateMessage)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE); + msg.one_shot = htonl (pal_ctx->one_shot); + msg.timeout = GNUNET_TIME_absolute_hton (pal_ctx->timeout); + msg.peer = pal_ctx->peer; + GNUNET_assert (GNUNET_OK == + GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client, + &msg.header, + GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout), + GNUNET_YES, + &peer_address_response_processor, + pal_ctx)); +} + +/** + * Task run to re-establish the connection. + * + * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' + * @param tc scheduler context, unused + */ +static void +do_connect (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; + + pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg); + GNUNET_assert (NULL != pal_ctx->client); + send_request (pal_ctx); +} + + +/** + * Cut the existing connection and reconnect. + * + * @param pal_ctx our context + */ +static void +reconnect (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) +{ + GNUNET_assert (GNUNET_NO == pal_ctx->one_shot); + GNUNET_CLIENT_disconnect (pal_ctx->client); + pal_ctx->client = NULL; + pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff); + pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff, + &do_connect, + pal_ctx); +} + + +/** + * Function called with responses from the service. + * + * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*' + * @param msg NULL on timeout or error, otherwise presumably a + * message with the human-readable address + */ +static void +peer_address_response_processor (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; + struct PeerIterateResponseMessage *air_msg; + struct GNUNET_HELLO_Address *address; + const char *addr; + const char *transport_name; + uint16_t size; + size_t alen; + size_t tlen; + + if (msg == NULL) + { + if (pal_ctx->one_shot) + { + pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, + S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); + GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); + } + else + { + reconnect (pal_ctx); + } + return; + } + size = ntohs (msg->size); + GNUNET_break (ntohs (msg->type) == + GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); + if (size == sizeof (struct GNUNET_MessageHeader)) + { + /* done! */ + if (pal_ctx->one_shot) + { + pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, + S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); + GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); + } + else + { + reconnect (pal_ctx); + } + return; + } + + if ((size < sizeof (struct PeerIterateResponseMessage)) || + (ntohs (msg->type) != + GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE)) + { + GNUNET_break (0); + if (pal_ctx->one_shot) + { + pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, + S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); + GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); + } + else + { + reconnect (pal_ctx); + } + return; + } + + air_msg = (struct PeerIterateResponseMessage *) msg; + tlen = ntohl (air_msg->pluginlen); + alen = ntohl (air_msg->addrlen); + + if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen) + { + GNUNET_break (0); + if (pal_ctx->one_shot) + { + pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, + S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); + GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); + } + else + { + reconnect (pal_ctx); + } + return; + } + + if (alen == 0 && tlen == 0) + { + pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, NULL, + S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); + } + else + { + addr = (const char *) &air_msg[1]; + transport_name = &addr[alen]; + + if (transport_name[tlen - 1] != '\0') + { + GNUNET_break (0); + if (pal_ctx->one_shot) + { + pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, + S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); + GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); + } + else + { + reconnect (pal_ctx); + } + return; + } + + /* notify client */ + address = GNUNET_HELLO_address_allocate (&air_msg->peer, + transport_name, addr, alen); + pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, address, + ntohl(air_msg->state), + GNUNET_TIME_absolute_ntoh (air_msg->state_timeout)); + GNUNET_HELLO_address_free (address); + } + + /* expect more replies */ + GNUNET_CLIENT_receive (pal_ctx->client, &peer_address_response_processor, + pal_ctx, + GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout)); +} + + +/** + * Return all the known addresses for a specific peer or all peers. + * Returns continuously all address if one_shot is set to GNUNET_NO + * + * CHANGE: Returns the address(es) that we are currently using for this + * peer. Upon completion, the 'AddressLookUpCallback' is called one more + * time with 'NULL' for the address and the peer. After this, the operation must no + * longer be explicitly canceled. + * + * @param cfg configuration to use + * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers + * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), + * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled) + * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO) + * @param peer_address_callback function to call with the results + * @param peer_address_callback_cls closure for peer_address_callback + */ +struct GNUNET_TRANSPORT_PeerMonitoringContext * +GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *peer, + int one_shot, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_PeerIterateCallback peer_address_callback, + void *peer_address_callback_cls) +{ + struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect ("transport", cfg); + if (client == NULL) + return NULL; + if (GNUNET_YES != one_shot) + timeout = GNUNET_TIME_UNIT_FOREVER_REL; + pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext); + pal_ctx->cb = peer_address_callback; + pal_ctx->cb_cls = peer_address_callback_cls; + pal_ctx->cfg = cfg; + pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); + if (NULL != peer) + pal_ctx->peer = *peer; + pal_ctx->one_shot = one_shot; + pal_ctx->client = client; + send_request (pal_ctx); + + return pal_ctx; +} + + +/** + * Cancel request for address conversion. + * + * @param alc handle for the request to cancel + */ +void +GNUNET_TRANSPORT_monitor_peers_cancel ( + struct GNUNET_TRANSPORT_PeerMonitoringContext *alc) +{ + if (NULL != alc->client) + { + GNUNET_CLIENT_disconnect (alc->client); + alc->client = NULL; + } + if (GNUNET_SCHEDULER_NO_TASK != alc->reconnect_task) + { + GNUNET_SCHEDULER_cancel (alc->reconnect_task); + alc->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_free (alc); +} + + +/** + * Return information about a peer's or all current pending validation operations + * + * @param cfg configuration to use + * @param peer a specific peer identity to obtain validation entries for, + * NULL for all peers + * @param one_shot GNUNET_YES to return all entries and then end (with NULL+NULL), + * GNUNET_NO to monitor validation entries continuously + * @param timeout how long is the lookup allowed to take at most + * @param peer_address_callback function to call with the results + * @param peer_address_callback_cls closure for peer_address_callback + */ +struct GNUNET_TRANSPORT_ValidationMonitoringContext * +GNUNET_TRANSPORT_monitor_validation_entries (const struct + GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *peer, + int one_shot, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_ValidationIterateCallback validation_callback, + void *validation_callback_cls) +{ + /* Not implemented */ + return NULL; +} + + +/** + * Return information about all current pending validation operations + * + * @param vic handle for the request to cancel + */ +void +GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic) +{ + /* Not implemented */ +} + + +/* end of transport_api_montoring.c */ -- cgit v1.2.3