*/
static int try_connect;
+/**
+ * Option -D.
+ */
+static int try_disconnect;
+
/**
* Option -n.
*/
};
+static struct ValidationResolutionContext *vc_head;
+static struct ValidationResolutionContext *vc_tail;
+
+struct ValidationResolutionContext
+{
+ struct ValidationResolutionContext *next;
+ struct ValidationResolutionContext *prev;
+
+ struct GNUNET_PeerIdentity id;
+ struct GNUNET_HELLO_Address *addrcp;
+ struct GNUNET_TIME_Absolute last_validation;
+ struct GNUNET_TIME_Absolute valid_until;
+ struct GNUNET_TIME_Absolute next_validation;
+ enum GNUNET_TRANSPORT_ValidationState state;
+
+ struct GNUNET_TRANSPORT_AddressToStringContext *asc;
+
+ char *transport;
+ int printed;
+};
+
struct MonitoredPeer
{
enum GNUNET_TRANSPORT_PeerState state;
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_TIME_Relative duration;
+ struct ValidationResolutionContext *cur;
+ struct ValidationResolutionContext *next;
end = GNUNET_SCHEDULER_NO_TASK;
if (GNUNET_SCHEDULER_NO_TASK != op_timeout)
{
GNUNET_TRANSPORT_monitor_validation_entries_cancel (vic);
vic = NULL;
}
+
+ next = vc_head;
+ for (cur = next; NULL != cur; cur = next)
+ {
+ next = cur->next;
+
+ GNUNET_TRANSPORT_address_to_string_cancel (cur->asc);
+ GNUNET_CONTAINER_DLL_remove (vc_head, vc_tail, cur);
+ GNUNET_free (cur->transport);
+ GNUNET_HELLO_address_free (cur->addrcp);
+ GNUNET_free (cur);
+ }
+
if (NULL != th)
{
GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
int printed;
};
-static struct ValidationResolutionContext *vc_head;
-static struct ValidationResolutionContext *vc_tail;
-
-struct ValidationResolutionContext
-{
- struct ValidationResolutionContext *next;
- struct ValidationResolutionContext *prev;
-
- struct GNUNET_PeerIdentity id;
- struct GNUNET_HELLO_Address *addrcp;
- struct GNUNET_TIME_Absolute last_validation;
- struct GNUNET_TIME_Absolute valid_until;
- struct GNUNET_TIME_Absolute next_validation;
- enum GNUNET_TRANSPORT_ValidationState state;
-
- struct GNUNET_TRANSPORT_AddressToStringContext *asc;
- char *transport;
- int printed;
-};
static void
operation_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
if (0 != memcmp (&pid, peer, sizeof(struct GNUNET_PeerIdentity)))
return;
+ if (try_disconnect)
+ {
+ /* all done, terminate instantly */
+ FPRINTF (stdout, _("Successfully disconnected from `%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 != end)
+ GNUNET_SCHEDULER_cancel (end);
+ end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL );
+ return;
+ }
+
if (NULL != th)
{
GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
const char *addr, enum GNUNET_TRANSPORT_PeerState state,
struct GNUNET_TIME_Absolute state_timeout)
{
- if ((GNUNET_YES == iterate_all) || (GNUNET_YES == monitor_connections) )
+
+ if ( ((GNUNET_YES == iterate_connections) && (GNUNET_YES == iterate_all)) ||
+ (GNUNET_YES == monitor_connections) )
{
FPRINTF (stdout, _("Peer `%s': %s %s in state `%s' until %s\n"),
GNUNET_i2s (id),
GNUNET_TRANSPORT_ps2s (state),
GNUNET_STRINGS_absolute_time_to_string (state_timeout));
}
- else
+ else if ( (GNUNET_YES == iterate_connections) &&
+ (GNUNET_TRANSPORT_is_connected(state)) )
{
/* Only connected peers, skip state */
FPRINTF (stdout, _("Peer `%s': %s %s\n"), GNUNET_i2s (id), transport, addr);
}
-
}
static void
{
return; /* No real change */
}
- if ( ((NULL != address) && (NULL != m->address)) &&
+ if ( (m->state == state) && ((NULL != address) && (NULL != m->address)) &&
(0 == GNUNET_HELLO_address_cmp(m->address, address)) )
return; /* No real change */
}
-
if (NULL != m->address)
{
GNUNET_free (m->address);
}
}
+static void
+try_disconnect_cb (void *cls, const int result)
+{
+ static int retries = 0;
+ if (GNUNET_OK == result)
+ {
+ tc_handle = NULL;
+ return;
+ }
+ retries++;
+ if (retries < 10)
+ tc_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, try_disconnect_cb,
+ NULL );
+ else
+ {
+ 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 );
+ return;
+ }
+}
+
/**
* Function called with the result of the check if the 'transport'
* service is running.
}
counter = benchmark_send + benchmark_receive + iterate_connections
- + monitor_connections + monitor_connects + try_connect
+ + monitor_connections + monitor_connects + try_connect + try_disconnect +
+ iterate_validation + monitor_validation;
if (1 < counter)
op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout,
NULL );
+ }
+ else if (try_disconnect) /* -D: Disconnect from peer */
+ {
+ if (NULL == cpid)
+ {
+ FPRINTF (stderr, _("Option `%s' makes no sense without option `%s'.\n"),
+ "-D", "-p");
+ ret = 1;
+ return;
+ }
+ 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;
+ }
+ tc_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, try_disconnect_cb,
+ NULL );
+ if (NULL == tc_handle)
+ {
+ 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 );
+
}
else if (benchmark_send) /* -s: Benchmark sending */
{
GNUNET_break(0);
return;
}
-
+ GNUNET_break (0);
end = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
&shutdown_task, NULL );
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",
+ 0, &GNUNET_GETOPT_set_one, &benchmark_receive },
+ { 'C', "connect",
NULL, gettext_noop ("connect to a peer"), 0,
&GNUNET_GETOPT_set_one, &try_connect },
+ { 'D', "disconnect",
+ NULL, gettext_noop ("disconnect to a peer"), 0,
+ &GNUNET_GETOPT_set_one, &try_disconnect },
{ 'd', "validation", NULL,
gettext_noop ("print information for all pending validations "),
0, &GNUNET_GETOPT_set_one, &iterate_validation },