From 39c000246382f7772c3c6bb4c889373da5df5a9d Mon Sep 17 00:00:00 2001 From: "Nathan S. Evans" Date: Mon, 11 Jul 2011 09:40:00 +0000 Subject: [PATCH] tool to list transport level connections --- src/include/gnunet_protocols.h | 9 +- src/include/gnunet_transport_service.h | 13 ++ src/transport/Makefile.am | 18 +- src/transport/gnunet-service-transport.c | 80 ++++++++- .../gnunet-transport-list-connections.c | 121 +++++++++++++ src/transport/transport.h | 17 ++ src/transport/transport_api_address_iterate.c | 164 ++++++++++++++++++ .../transport_api_peer_address_lookup.c | 12 ++ 8 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 src/transport/gnunet-transport-list-connections.c create mode 100644 src/transport/transport_api_address_iterate.c diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 2800e5b92..7cc8e7239 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -308,15 +308,20 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_PEER_ADDRESS_LOOKUP 59 +/** + * Request to iterate over all known addresses. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE 60 + /** * Welcome message between TCP transports. */ -#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME 60 +#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME 61 /** * Message to force transport to update bandwidth assignment */ -#define GNUNET_MESSAGE_TYPE_TRANSPORT_ATS 61 +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ATS 62 /** * Message to ask NAT server to perform traversal test diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h index 607389ae7..24b9e90af 100644 --- a/src/include/gnunet_transport_service.h +++ b/src/include/gnunet_transport_service.h @@ -662,6 +662,19 @@ GNUNET_TRANSPORT_peer_address_lookup (const struct GNUNET_CONFIGURATION_Handle * void *peer_address_callback_cls); +/** + * Return all the known addresses for a peer. + * + * @param cfg configuration to use + * @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 + */ +void +GNUNET_TRANSPORT_address_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_AddressLookUpCallback peer_address_callback, + void *peer_address_callback_cls); /** * Handle for blacklisting peers. diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 72612e5bb..fce9f3296 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -60,7 +60,8 @@ libgnunettransportnew_la_SOURCES = \ transport_api_new.c transport.h \ transport_api_blacklist.c \ transport_api_address_lookup.c \ - transport_api_peer_address_lookup.c + transport_api_peer_address_lookup.c \ + transport_api_address_iterate.c libgnunettransportnew_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -73,7 +74,8 @@ libgnunettransport_la_SOURCES = \ transport_api.c transport.h \ transport_api_blacklist.c \ transport_api_address_lookup.c \ - transport_api_peer_address_lookup.c + transport_api_peer_address_lookup.c \ + transport_api_address_iterate.c libgnunettransport_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -87,6 +89,7 @@ bin_PROGRAMS = \ gnunet-transport \ $(WLAN_BIN) \ gnunet-service-transport \ + gnunet-transport-list-connections \ $(WLAN_BIN_DUMMY) bin_SCRIPTS = \ @@ -113,6 +116,15 @@ gnunet_transport_wlan_helper_LDADD = \ gnunet_transport_wlan_helper_dummy_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la + +gnunet_transport_list_connections_SOURCES = \ + gnunet-transport-list-connections.c +gnunet_transport_list_connections_LDADD = \ + $(top_builddir)/src/transport/libgnunettransportnew.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +gnunet_transport_list_connections_DEPENDENCIES = \ + libgnunettransportnew.la gnunet_transport_SOURCES = \ gnunet-transport.c @@ -136,7 +148,7 @@ gnunet_service_transport_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_GLPK) \ $(GN_LIBINTL) - + plugin_LTLIBRARIES = \ libgnunet_plugin_transport_tcp.la \ libgnunet_plugin_transport_udp.la \ diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 4c4e848a8..e4c4ce507 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -5824,7 +5824,7 @@ handle_address_lookup (void *cls, } /** - * Handle AddressLookup-message. + * Handle PeerAddressLookupMessage. * * @param cls closure (always NULL) * @param client identification of the client @@ -5909,6 +5909,81 @@ handle_peer_address_lookup (void *cls, GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); } +/** + * Handle AddressIterateMessage + * + * @param cls closure (always NULL) + * @param client identification of the client + * @param message the actual message + */ +static void +handle_address_iterate (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct AddressIterateMessage *address_iterate; + struct NeighbourList *neighbor_iterator; + struct ReadyList *ready_iterator; + struct ForeignAddressList *foreign_address_iterator; + struct TransportPlugin *transport_plugin; + + uint16_t size; + struct GNUNET_SERVER_TransmitContext *tc; + struct GNUNET_TIME_Absolute timeout; + struct GNUNET_TIME_Relative rtimeout; + char *addr_buf; + + size = ntohs (message->size); + if (size < sizeof (struct AddressIterateMessage)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + address_iterate = (const struct AddressIterateMessage *) message; + + timeout = GNUNET_TIME_absolute_ntoh (address_iterate->timeout); + rtimeout = GNUNET_TIME_absolute_get_remaining (timeout); + + GNUNET_SERVER_disable_receive_done_warning (client); + tc = GNUNET_SERVER_transmit_context_create (client); + + neighbor_iterator = neighbours; + while (neighbor_iterator != NULL) + { + ready_iterator = neighbor_iterator->plugins; + while (ready_iterator != NULL) + { + foreign_address_iterator = ready_iterator->addresses; + while (foreign_address_iterator != NULL) + { + transport_plugin = foreign_address_iterator->ready_list->plugin; + if (foreign_address_iterator->addr != NULL) + { + GNUNET_asprintf (&addr_buf, "%s:%s --- %s", + GNUNET_i2s(&neighbor_iterator->peer), + a2s (transport_plugin->short_name, + foreign_address_iterator->addr, + foreign_address_iterator->addrlen), + (foreign_address_iterator->connected + == GNUNET_YES) ? "CONNECTED" + : "DISCONNECTED"); + transmit_address_to_client (tc, addr_buf); + GNUNET_free(addr_buf); + } + + foreign_address_iterator = foreign_address_iterator->next; + } + ready_iterator = ready_iterator->next; + } + neighbor_iterator = neighbor_iterator->next; + } + + GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, + GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); + GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); +} + /** * Setup the environment for this plugin. @@ -6353,6 +6428,9 @@ run (void *cls, {&handle_peer_address_lookup, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_PEER_ADDRESS_LOOKUP, 0}, + {&handle_address_iterate, NULL, + GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE, + 0}, {&handle_blacklist_init, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT, sizeof (struct GNUNET_MessageHeader)}, {&handle_blacklist_reply, NULL, diff --git a/src/transport/gnunet-transport-list-connections.c b/src/transport/gnunet-transport-list-connections.c new file mode 100644 index 000000000..39950467d --- /dev/null +++ b/src/transport/gnunet-transport-list-connections.c @@ -0,0 +1,121 @@ +/* + 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 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 core/gnunet-transport-list-connections.c + * + * @brief Print all known address information about other peers. + * + * Lists all peers and connections that the transport service is + * aware of. Pretty prints addresses, peer id's, and whether + * or not the _address_ is connected. Note that these are not + * core level connections, only transport level connections. + * + * @author Nathan Evans + */ +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_configuration_lib.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_transport_service.h" +#include "gnunet_program_lib.h" + +#define VERBOSE 0 +static int no_resolve; + +#if VERBOSE + static unsigned int connection_count; +#endif + +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Function to call with a human-readable format of an address + * + * @param cls closure + * @param address NULL on error, otherwise 0-terminated printable UTF-8 string + */ +static void +process_address (void *cls, + const char *address) +{ +#if VERBOSE + connection_count++; +#endif + if (address != NULL) + fprintf(stdout, "%s\n", address); +} + + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + + cfg = c; + if (args[0] != NULL) + { + fprintf (stderr, + _("Invalid command line argument `%s'\n"), + args[0]); + return; + } + + GNUNET_TRANSPORT_address_iterate (cfg, + GNUNET_TIME_UNIT_MINUTES, + &process_address, NULL); +} + + +/** + * The main function to obtain peer information. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'n', "numeric", NULL, + gettext_noop ("don't resolve host names"), + 0, &GNUNET_GETOPT_set_one, &no_resolve}, + GNUNET_GETOPT_OPTION_END + }; + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, + argv, + "gnunet-list-connections", + gettext_noop ("Print information about connected peers."), + options, &run, NULL)) ? 0 : 1; +} + +/* end of gnunet-transport-list-connections.c */ diff --git a/src/transport/transport.h b/src/transport/transport.h index 133eb6887..89e50b73f 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -334,6 +334,23 @@ struct PeerAddressLookupMessage struct GNUNET_PeerIdentity peer; }; +/** + * Message from the library to the transport service + * asking for human readable addresses known for a peer. + */ +struct AddressIterateMessage +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE + */ + struct GNUNET_MessageHeader header; + + /** + * timeout to give up. + */ + struct GNUNET_TIME_AbsoluteNBO timeout; +}; + /** * Change in blacklisting (either request or notification, * depending on which direction it is going). diff --git a/src/transport/transport_api_address_iterate.c b/src/transport/transport_api_address_iterate.c new file mode 100644 index 000000000..7bbeb499d --- /dev/null +++ b/src/transport/transport_api_address_iterate.c @@ -0,0 +1,164 @@ +/* + 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_iterate.c + * @brief api for asking transport service to iterate over all + * known addresses + * + * This api provides a single function call to ask the transport + * service to list all peers and their known addresses, as pretty + * printed by the appropriate plugin. Reports whether or not the + * address is connected as well. + */ + +#include "platform.h" +#include "gnunet_client_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_hello_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_server_lib.h" +#include "gnunet_time_lib.h" +#include "gnunet_transport_service.h" +#include "transport.h" + +/** + * Context for the address lookup. + */ +struct AddressLookupCtx +{ + /** + * Function to call with the human-readable address. + */ + GNUNET_TRANSPORT_AddressLookUpCallback cb; + + /** + * Closure for cb. + */ + void *cb_cls; + + /** + * Connection to the service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * When should this operation time out? + */ + struct GNUNET_TIME_Absolute timeout; +}; + + +/** + * Function called with responses from the service. + * + * @param cls our 'struct AddressLookupCtx*' + * @param msg NULL on timeout or error, otherwise presumably a + * message with the human-readable peer and address + */ +static void +peer_address_response_processor (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct AddressLookupCtx *alucb = cls; + const char *address; + uint16_t size; + + if (msg == NULL) + { + alucb->cb (alucb->cb_cls, NULL); + GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO); + GNUNET_free (alucb); + return; + } + GNUNET_break (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); + size = ntohs (msg->size); + if (size == sizeof (struct GNUNET_MessageHeader)) + { + /* done! */ + alucb->cb (alucb->cb_cls, NULL); + GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO); + GNUNET_free (alucb); + return; + } + address = (const char *) &msg[1]; + if (address[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0') + { + /* invalid reply */ + GNUNET_break (0); + alucb->cb (alucb->cb_cls, NULL); + GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO); + GNUNET_free (alucb); + return; + } + /* expect more replies */ + GNUNET_CLIENT_receive (alucb->client, + &peer_address_response_processor, alucb, + GNUNET_TIME_absolute_get_remaining + (alucb->timeout)); + alucb->cb (alucb->cb_cls, address); +} + + +/** + * Return all the known addresses for a peer. + * + * @param cfg configuration to use + * @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 + */ +void +GNUNET_TRANSPORT_address_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_AddressLookUpCallback peer_address_callback, + void *peer_address_callback_cls) +{ + struct AddressIterateMessage msg; + struct GNUNET_TIME_Absolute abs_timeout; + struct AddressLookupCtx *peer_address_lookup_cb; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect ("transport", cfg); + if (client == NULL) + { + peer_address_callback (peer_address_callback_cls, NULL); + return; + } + abs_timeout = GNUNET_TIME_relative_to_absolute (timeout); + + msg.header.size = htons (sizeof(struct AddressLookupMessage)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE); + msg.timeout = GNUNET_TIME_absolute_hton (abs_timeout); + peer_address_lookup_cb = GNUNET_malloc (sizeof (struct AddressLookupCtx)); + peer_address_lookup_cb->cb = peer_address_callback; + peer_address_lookup_cb->cb_cls = peer_address_callback_cls; + peer_address_lookup_cb->timeout = abs_timeout; + peer_address_lookup_cb->client = client; + GNUNET_assert (GNUNET_OK == + GNUNET_CLIENT_transmit_and_get_response (client, + &msg.header, + timeout, + GNUNET_YES, + &peer_address_response_processor, + peer_address_lookup_cb)); +} + +/* end of transport_api_address_iterate.c */ diff --git a/src/transport/transport_api_peer_address_lookup.c b/src/transport/transport_api_peer_address_lookup.c index 6eb241078..2da4b6c69 100644 --- a/src/transport/transport_api_peer_address_lookup.c +++ b/src/transport/transport_api_peer_address_lookup.c @@ -17,6 +17,18 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/** + * @file transport/transport_api_peer_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_client_lib.h" #include "gnunet_arm_service.h" -- 2.25.1