static int monitor_connections;
/**
- * Option -i.
+ * Option -P.
*/
-static int get_info;
+static int request_peers;
+
+/**
+ * Option -T.
+ */
+static int request_tunnels;
/**
* Option --tunnel
*/
static uint32_t listen_port;
+/**
+ * Request echo service
+ */
+int echo;
+
+/**
+ * Time of last echo request.
+ */
+struct GNUNET_TIME_Absolute echo_time;
+
+/**
+ * Task for next echo request.
+ */
+GNUNET_SCHEDULER_TaskIdentifier echo_task;
+
/**
* Peer to connect to.
*/
shutdown_task (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown\n");
if (NULL != ch)
{
GNUNET_MESH_channel_destroy (ch);
GNUNET_assert (size >= total_size);
msg = buf;
- msg->size = ntohs (total_size);
- msg->type = ntohs (GNUNET_MESSAGE_TYPE_MESH_CLI);
+ msg->size = htons (total_size);
+ msg->type = htons (GNUNET_MESSAGE_TYPE_MESH_CLI);
memcpy (&msg[1], cls, data_size);
- listen_stdio ();
+ if (GNUNET_NO == echo)
+ {
+ listen_stdio ();
+ }
+ else
+ {
+ echo_time = GNUNET_TIME_absolute_get ();
+ }
return total_size;
}
read_stdio (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- char buf[60000];
+ static char buf[60000];
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
GNUNET_TIME_UNIT_FOREVER_REL,
rs, NULL,
&read_stdio, NULL);
+ GNUNET_NETWORK_fdset_destroy (rs);
}
channel_incoming (void *cls,
struct GNUNET_MESH_Channel * channel,
const struct GNUNET_PeerIdentity * initiator,
- uint32_t port, enum MeshOption options)
+ uint32_t port, enum GNUNET_MESH_ChannelOption options)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Incoming channel %p on port %u\n",
return NULL;
}
ch = channel;
- listen_stdio ();
+ if (GNUNET_NO == echo)
+ {
+ listen_stdio ();
+ return NULL;
+ }
+ data_size = 0;
return NULL;
}
+/**
+ * @brief Send an echo request to the remote peer.
+ *
+ * @param cls Closure (NULL).
+ * @param tc Task context.
+ */
+static void
+send_echo (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_MESH_notify_transmit_ready (ch, GNUNET_NO,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ sizeof (struct GNUNET_MessageHeader),
+ &data_ready, NULL);
+}
+
/**
create_channel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_PeerIdentity pid;
+ enum GNUNET_MESH_ChannelOption opt;
GNUNET_assert (NULL == ch);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to `%s'\n", target_id);
- ch = GNUNET_MESH_channel_create (mh, NULL, &pid, target_port,
- GNUNET_MESH_OPTION_DEFAULT);
- listen_stdio ();
+ opt = GNUNET_MESH_OPTION_DEFAULT | GNUNET_MESH_OPTION_RELIABLE;
+ ch = GNUNET_MESH_channel_create (mh, NULL, &pid, target_port, opt);
+ if (GNUNET_NO == echo)
+ listen_stdio ();
+ else
+ GNUNET_SCHEDULER_add_now (send_echo, NULL);
}
void **channel_ctx,
const struct GNUNET_MessageHeader *message)
{
- int16_t len;
+ uint16_t len;
+ ssize_t done;
+ uint16_t off;
+ const char *buf;
GNUNET_break (ch == channel);
+ if (GNUNET_YES == echo)
+ {
+ if (0 != listen_port)
+ {
+ /* Just listening to echo incoming messages*/
+ GNUNET_MESH_notify_transmit_ready (channel, GNUNET_NO,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ sizeof (struct GNUNET_MessageHeader),
+ &data_ready, NULL);
+ return GNUNET_OK;
+ }
+ else
+ {
+ struct GNUNET_TIME_Relative latency;
+
+ latency = GNUNET_TIME_absolute_get_duration (echo_time);
+ echo_time = GNUNET_TIME_UNIT_FOREVER_ABS;
+ FPRINTF (stdout, "time: %s\n",
+ GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO));
+ echo_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &send_echo, NULL);
+ }
+ }
+
len = ntohs (message->size) - sizeof (*message);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %u bytes\n", len);
- FPRINTF (stdout, "%.*s", len, (char *) &message[1]);
+ buf = (const char *) &message[1];
+ off = 0;
+ while (off < len)
+ {
+ done = write (1, &buf[off], len - off);
+ if (done <= 0)
+ {
+ if (-1 == done)
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "write");
+ return GNUNET_SYSERR;
+ }
+ off += done;
+ }
return GNUNET_OK;
}
/**
- * Method called to retrieve information about each tunnel the mesh peer
- * is aware of.
+ * Method called to retrieve information about all peers in MESH, called
+ * once per peer.
+ *
+ * After last peer has been reported, an additional call with NULL is done.
*
* @param cls Closure.
- * @param tunnel_number Tunnel number.
- * @param origin that started the tunnel (owner).
- * @param target other endpoint of the tunnel
+ * @param peer Peer, or NULL on "EOF".
+ * @param tunnel Do we have a tunnel towards this peer?
+ * @param n_paths Number of known paths towards this peer.
+ * @param best_path How long is the best path?
+ * (0 = unknown, 1 = ourselves, 2 = neighbor)
*/
-void /* FIXME static */
-tunnels_callback (void *cls,
- uint32_t tunnel_number,
- const struct GNUNET_PeerIdentity *origin,
- const struct GNUNET_PeerIdentity *target)
+static void
+peers_callback (void *cls, const struct GNUNET_PeerIdentity *peer,
+ int tunnel, unsigned int n_paths, unsigned int best_path)
{
- FPRINTF (stdout, "Tunnel %s [%u]\n",
- GNUNET_i2s_full (origin), tunnel_number);
- FPRINTF (stdout, "\n");
+ if (NULL == peer)
+ {
+ if (GNUNET_YES != monitor_connections)
+ {
+ GNUNET_SCHEDULER_shutdown();
+ }
+ return;
+ }
+ FPRINTF (stdout, "%s tunnel: %c, paths: %u\n",
+ GNUNET_i2s_full (peer), tunnel ? 'Y' : 'N', n_paths);
}
/**
- * Method called to retrieve information about each tunnel the mesh peer
- * is aware of.
+ * Method called to retrieve information about all tunnels in MESH.
*
* @param cls Closure.
- * @param peer Peer in the tunnel's tree.
- * @param parent Parent of the current peer. All 0 when peer is root.
+ * @param peer Destination peer.
+ * @param channels Number of channels.
+ * @param connections Number of connections.
+ * @param estate Encryption state.
+ * @param cstate Connectivity state.
+ */
+void
+tunnels_callback (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ unsigned int channels,
+ unsigned int connections,
+ uint16_t estate,
+ uint16_t cstate)
+{
+ if (NULL == peer)
+ {
+ if (GNUNET_YES != monitor_connections)
+ {
+ GNUNET_SCHEDULER_shutdown();
+ }
+ return;
+ }
+ FPRINTF (stdout, "%s [ENC: %u, CON: %u] CHs: %u, CONNs: %u\n",
+ GNUNET_i2s_full (peer), estate, cstate, channels, connections);
+}
+
+
+/**
+ * Method called to retrieve information about a specific tunnel the mesh peer
+ * has established, o`r is trying to establish.
*
+ * @param cls Closure.
+ * @param peer Peer towards whom the tunnel is directed.
+ * @param n_channels Number of channels.
+ * @param n_connections Number of connections.
+ * @param channels Channels.
+ * @param connections Connections.
+ * @param estate Encryption status.
+ * @param cstate Connectivity status.
*/
-void /* FIXME static */
+void
tunnel_callback (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_PeerIdentity *parent)
+ unsigned int n_channels,
+ unsigned int n_connections,
+ uint32_t *channels,
+ struct GNUNET_HashCode *connections,
+ unsigned int estate,
+ unsigned int cstate)
{
+ unsigned int i;
+
+ if (NULL != peer)
+ {
+ FPRINTF (stdout, "Tunnel %s\n", GNUNET_i2s_full (peer));
+ FPRINTF (stdout, "- %u channels\n", n_channels);
+ for (i = 0; i < n_channels; i++)
+ FPRINTF (stdout, " %u\n", channels[i]);
+ FPRINTF (stdout, "- %u connections\n", n_connections);
+ for (i = 0; i < n_connections; i++)
+ FPRINTF (stdout, " %s\n", GNUNET_h2s_full (&connections[i]));
+ FPRINTF (stdout, "- enc state: %u\n", estate);
+ FPRINTF (stdout, "- con state: %u\n", cstate);
+ }
+ if (GNUNET_YES != monitor_connections)
+ {
+ GNUNET_SCHEDULER_shutdown();
+ }
+ return;
+
}
/**
- * Call MESH's monitor API, get all tunnels known to peer.
+ * Call MESH's meta API, get all peers known to a peer.
*
* @param cls Closure (unused).
* @param tc TaskContext
*/
static void
-get_tunnels (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+get_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown\n");
return;
}
-// GNUNET_MESH_get_tunnels (mh, &tunnels_callback, NULL);
- if (GNUNET_YES != monitor_connections)
+ GNUNET_MESH_get_peers (mh, &peers_callback, NULL);
+}
+
+/**
+ * Call MESH's meta API, get all tunnels known to a peer.
+ *
+ * @param cls Closure (unused).
+ * @param tc TaskContext
+ */
+static void
+get_tunnels (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
- GNUNET_SCHEDULER_shutdown();
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown\n");
+ return;
}
+ GNUNET_MESH_get_tunnels (mh, &tunnels_callback, NULL);
}
GNUNET_SCHEDULER_shutdown();
return;
}
-// GNUNET_MESH_show_tunnel (mh, &pid, 0, tunnel_callback, NULL);
+ GNUNET_MESH_get_tunnel (mh, &pid, tunnel_callback, NULL);
}
target_id = args[0];
target_port = args[0] && args[1] ? atoi(args[1]) : 0;
- if ( (0 != get_info
+ if ( (0 != (request_peers | request_tunnels)
|| 0 != monitor_connections
|| NULL != tunnel_id
|| NULL != conn_id
|| NULL != channel_id)
&& target_id != NULL)
{
- FPRINTF (stderr, _("You must NOT give a TARGET when using options\n"));
+ FPRINTF (stderr,
+ _("You must NOT give a TARGET"
+ "when using 'request all' options\n"));
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show connection\n");
GNUNET_SCHEDULER_add_now (&show_connection, NULL);
}
- else if (GNUNET_YES == get_info)
+ else if (GNUNET_YES == request_peers)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all peers\n");
+ GNUNET_SCHEDULER_add_now (&get_peers, NULL);
+ }
+ else if (GNUNET_YES == request_tunnels)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all tunnels\n");
GNUNET_SCHEDULER_add_now (&get_tunnels, NULL);
int res;
const char helpstr[] = "Create channels and retreive info about meshs status.";
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
- {'a', "channel", "TUNNEL_ID:CHANNEL_ID",
- gettext_noop ("provide information about a particular channel"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &channel_id},
- {'b', "connection", "TUNNEL_ID:CONNECTION_ID",
- gettext_noop ("provide information about a particular connection"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id},
- {'i', "info", NULL,
- gettext_noop ("provide information about all tunnels"),
- GNUNET_NO, &GNUNET_GETOPT_set_one, &get_info},
- {'m', "monitor", NULL,
- gettext_noop ("provide information about all tunnels (continuously) NOT IMPLEMENTED"), /* FIXME */
- GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_connections},
+// {'a', "channel", "TUNNEL_ID:CHANNEL_ID",
+// gettext_noop ("provide information about a particular channel"),
+// GNUNET_YES, &GNUNET_GETOPT_set_string, &channel_id},
+// {'b', "connection", "TUNNEL_ID:CONNECTION_ID",
+// gettext_noop ("provide information about a particular connection"),
+// GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id},
+ {'e', "echo", NULL,
+ gettext_noop ("activate echo mode"),
+ GNUNET_NO, &GNUNET_GETOPT_set_one, &echo},
+// {'m', "monitor", NULL,
+// gettext_noop ("provide information about all tunnels (continuously) NOT IMPLEMENTED"), /* FIXME */
+// GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_connections},
{'p', "port", NULL,
gettext_noop ("port to listen to (default; 0)"),
GNUNET_YES, &GNUNET_GETOPT_set_uint, &listen_port},
+ {'P', "peers", NULL,
+ gettext_noop ("provide information about all peers"),
+ GNUNET_NO, &GNUNET_GETOPT_set_one, &request_peers},
{'t', "tunnel", "TUNNEL_ID",
gettext_noop ("provide information about a particular tunnel"),
GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id},
+ {'T', "tunnels", NULL,
+ gettext_noop ("provide information about all tunnels"),
+ GNUNET_NO, &GNUNET_GETOPT_set_one, &request_tunnels},
+
GNUNET_GETOPT_OPTION_END
};
+ monitor_connections = GNUNET_NO;
+
if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
return 2;