/*
This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (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
/**
* How long do we wait for the NAT test to report success?
+ * Should match NAT_SERVER_TIMEOUT in 'nat_test.c'.
*/
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+#define RESOLUTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
/**
* Which peer should we connect to?
*/
static int test_configuration;
+/**
+ * Option -m.
+ */
+static int monitor_connections;
+
/**
* Option -n.
*/
*/
static GNUNET_SCHEDULER_TaskIdentifier end;
+static struct GNUNET_CONTAINER_MultiHashMap *peers;
+
/**
* Selected level of verbosity.
*/
&plugins))
{
FPRINTF (stderr,
- _
- ("No transport plugins configured, peer will never communicate\n"), NULL);
+ "%s",
+ _
+ ("No transport plugins configured, peer will never communicate\n"));
ret = 4;
return;
}
adv_port = bnd_port;
if (NULL == resolver)
resolver =
- GNUNET_OS_start_process (NULL, NULL, "gnunet-service-resolver",
+ GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-resolver",
"gnunet-service-resolver", NULL);
resolver_users++;
GNUNET_RESOLVER_connect (cfg);
traffic_received += ntohs (message->size);
}
+struct ResolutionContext
+{
+ struct GNUNET_HELLO_Address *addrcp;
+
+ int printed;
+};
+
void
process_string (void *cls, const char *address)
{
- struct GNUNET_HELLO_Address *addrcp = cls;
+ 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);
+ rc->printed = GNUNET_YES;
}
else
{
/* done */
- GNUNET_free (addrcp);
+ if (GNUNET_NO == rc->printed)
+ FPRINTF (stdout, _("Peer `%s': %s <unable to resolve address>\n"), GNUNET_i2s (&addrcp->peer), addrcp->transport_name);
+ GNUNET_free (rc->addrcp);
+ GNUNET_free (rc);
}
}
/**
- * Function to call with a human-readable format of an address
+ * Function to call with a binary address
*
* @param cls closure
* @param peer identity of the peer
- * @param transport name of the plugin
- * @param addr binary address
- * @param addrlen number of bytes in addr
+ * @param address binary address (NULL on disconnect)
*/
static void
process_address (void *cls, const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_HELLO_Address *address)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+ struct ResolutionContext *rc;
- if ((address == NULL) || (peer == NULL))
+ if (peer == NULL)
{
/* done */
return;
}
+ if (address == NULL)
+ {
+ FPRINTF (stdout, _("Peer `%s' disconnected\n"), GNUNET_i2s (peer));
+ return;
+ }
+
+ rc = GNUNET_malloc(sizeof (struct ResolutionContext));
+ rc->addrcp = GNUNET_HELLO_address_copy(address);
+ rc->printed = GNUNET_NO;
+
+ GNUNET_assert (NULL != rc);
+
/* Resolve address to string */
GNUNET_TRANSPORT_address_to_string (cfg, address, numeric,
- GNUNET_TIME_UNIT_MINUTES, &process_string,
- GNUNET_HELLO_address_copy(address));
+ RESOLUTION_TIMEOUT, &process_string,
+ rc);
+}
+
+
+/**
+ * Task run in monitor mode when the user presses CTRL-C to abort.
+ * Stops monitoring activity.
+ *
+ * @param cls the 'struct GNUNET_TRANSPORT_PeerIterateContext *'
+ * @param tc scheduler context
+ */
+static void
+shutdown_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_TRANSPORT_PeerIterateContext *pic = cls;
+
+ GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pic);
+
+ if (NULL != peers)
+ {
+ GNUNET_CONTAINER_multihashmap_destroy (peers);
+ peers = NULL;
+ }
}
+
/**
* Main function that will be run by the scheduler.
*
}
if (iterate_connections)
{
+ peers = GNUNET_CONTAINER_multihashmap_create (20);
GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_YES,
- GNUNET_TIME_UNIT_MINUTES,
+ TIMEOUT,
&process_address, (void *) cfg);
}
+ if (monitor_connections)
+ {
+ struct GNUNET_TRANSPORT_PeerIterateContext *pic;
+
+ pic = GNUNET_TRANSPORT_peer_get_active_addresses (cfg, NULL, GNUNET_NO,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &process_address, (void *) cfg);
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ &shutdown_task,
+ pic);
+ }
}
{'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},
+ {'n', "numeric", NULL,
+ gettext_noop ("do not resolve hostnames"),
+ 0, &GNUNET_GETOPT_set_one, &numeric},
{'s', "send", NULL,
gettext_noop
("send data for benchmarking to the other peer (until CTRL-C)"),
{'t', "test", NULL,
gettext_noop ("test transport configuration (involves external server)"),
0, &GNUNET_GETOPT_set_one, &test_configuration},
- {'n', "numeric", NULL,
- gettext_noop ("do not resolve hostnames"),
- 0, &GNUNET_GETOPT_set_one, &numeric},
GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
GNUNET_GETOPT_OPTION_END
};