123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2012, 2017 GNUnet e.V.
- 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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
- */
- /**
- * @file cadet/gnunet-cadet.c
- * @brief Print information about cadet tunnels and peers.
- * @author Bartlomiej Polot
- * @author Christian Grothoff
- */
- #include "platform.h"
- #include "gnunet_util_lib.h"
- #include "gnunet_cadet_service.h"
- #include "cadet.h"
- /**
- * Option -P.
- */
- static int request_peers;
- /**
- * Option --peer
- */
- static char *peer_id;
- /**
- * Option -T.
- */
- static int request_tunnels;
- /**
- * Option --tunnel
- */
- static char *tunnel_id;
- /**
- * Option --connection
- */
- static char *conn_id;
- /**
- * Option --channel
- */
- static char *channel_id;
- /**
- * Port to listen on (-o).
- */
- static char *listen_port;
- /**
- * Request echo service
- */
- static int echo;
- /**
- * Request a debug dump
- */
- static int dump;
- /**
- * Time of last echo request.
- */
- static struct GNUNET_TIME_Absolute echo_time;
- /**
- * Task for next echo request.
- */
- static struct GNUNET_SCHEDULER_Task *echo_task;
- /**
- * Peer to connect to.
- */
- static char *target_id;
- /**
- * Port to connect to
- */
- static char *target_port = "default";
- /**
- * Cadet handle.
- */
- static struct GNUNET_CADET_Handle *mh;
- /**
- * Channel handle.
- */
- static struct GNUNET_CADET_Channel *ch;
- /**
- * HashCode of the given port string
- */
- static struct GNUNET_HashCode porthash;
- /**
- * Data structure for ongoing reception of incoming virtual circuits.
- */
- struct GNUNET_CADET_Port *lp;
- /**
- * Task for reading from stdin.
- */
- static struct GNUNET_SCHEDULER_Task *rd_task;
- /**
- * Task for main job.
- */
- static struct GNUNET_SCHEDULER_Task *job;
- /**
- * Wait for input on STDIO and send it out over the #ch.
- */
- static void
- listen_stdio (void);
- /**
- * Convert encryption status to human readable string.
- *
- * @param status Encryption status.
- *
- * @return Human readable string.
- */
- static const char *
- enc_2s (uint16_t status)
- {
- switch (status)
- {
- case 0:
- return "NULL ";
- case 1:
- return "KSENT";
- case 2:
- return "KRECV";
- case 3:
- return "READY";
- default:
- return "";
- }
- }
- /**
- * Convert connection status to human readable string.
- *
- * @param status Connection status.
- *
- * @return Human readable string.
- */
- static const char *
- conn_2s (uint16_t status)
- {
- switch (status)
- {
- case 0:
- return "NEW ";
- case 1:
- return "SRCH ";
- case 2:
- return "WAIT ";
- case 3:
- return "READY";
- case 4:
- return "SHUTD";
- default:
- return "";
- }
- }
- /**
- * Task to shut down this application.
- *
- * @param cls Closure (unused).
- */
- static void
- shutdown_task (void *cls)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Shutdown\n");
- if (NULL != ch)
- {
- GNUNET_CADET_channel_destroy (ch);
- ch = NULL;
- }
- if (NULL != mh)
- {
- GNUNET_CADET_disconnect (mh);
- mh = NULL;
- }
- if (NULL != rd_task)
- {
- GNUNET_SCHEDULER_cancel (rd_task);
- rd_task = NULL;
- }
- if (NULL != echo_task)
- {
- GNUNET_SCHEDULER_cancel (echo_task);
- echo_task = NULL;
- }
- if (NULL != job)
- {
- GNUNET_SCHEDULER_cancel (job);
- job = NULL;
- }
- }
- /**
- * Task run in stdio mode, after some data is available at stdin.
- *
- * @param cls Closure (unused).
- */
- static void
- read_stdio (void *cls)
- {
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_MessageHeader *msg;
- char buf[60000];
- ssize_t data_size;
- rd_task = NULL;
- data_size = read (0,
- buf,
- 60000);
- if (data_size < 1)
- {
- GNUNET_SCHEDULER_shutdown();
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Read %u bytes from stdio\n",
- (unsigned int) data_size);
- env = GNUNET_MQ_msg_extra (msg,
- data_size,
- GNUNET_MESSAGE_TYPE_CADET_CLI);
- GNUNET_memcpy (&msg[1],
- buf,
- data_size);
- GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
- env);
- if (GNUNET_NO == echo)
- {
- listen_stdio ();
- }
- else
- {
- echo_time = GNUNET_TIME_absolute_get ();
- }
- }
- /**
- * Wait for input on STDIO and send it out over the #ch.
- */
- static void
- listen_stdio ()
- {
- struct GNUNET_NETWORK_FDSet *rs;
- /* FIXME: why use 'rs' here, seems overly complicated... */
- rs = GNUNET_NETWORK_fdset_create ();
- GNUNET_NETWORK_fdset_set_native (rs,
- 0); /* STDIN */
- rd_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_TIME_UNIT_FOREVER_REL,
- rs,
- NULL,
- &read_stdio,
- NULL);
- GNUNET_NETWORK_fdset_destroy (rs);
- }
- /**
- * Function called whenever a channel is destroyed. Should clean up
- * any associated state.
- *
- * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
- *
- * @param cls closure
- * @param channel connection to the other end (henceforth invalid)
- */
- static void
- channel_ended (void *cls,
- const struct GNUNET_CADET_Channel *channel)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Channel ended!\n");
- GNUNET_assert (channel == ch);
- ch = NULL;
- GNUNET_SCHEDULER_shutdown ();
- }
- /**
- * Method called whenever another peer has added us to a channel
- * the other peer initiated.
- * Only called (once) upon reception of data with a message type which was
- * subscribed to in #GNUNET_CADET_connect.
- *
- * A call to #GNUNET_CADET_channel_destroy causes the channel to be ignored.
- * In this case the handler MUST return NULL.
- *
- * @param cls closure
- * @param channel new handle to the channel
- * @param initiator peer that started the channel
- * @return initial channel context for the channel, we use @a channel
- */
- static void *
- channel_incoming (void *cls,
- struct GNUNET_CADET_Channel *channel,
- const struct GNUNET_PeerIdentity *initiator)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "Incoming connection from %s\n",
- GNUNET_i2s_full (initiator));
- GNUNET_assert (NULL == ch);
- GNUNET_assert (NULL != lp);
- GNUNET_CADET_close_port (lp);
- lp = NULL;
- ch = channel;
- if (GNUNET_NO == echo)
- listen_stdio ();
- return channel;
- }
- /**
- * @brief Send an echo request to the remote peer.
- *
- * @param cls Closure (NULL).
- */
- static void
- send_echo (void *cls)
- {
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_MessageHeader *msg;
- echo_task = NULL;
- if (NULL == ch)
- return;
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_CLI);
- GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
- env);
- }
- /**
- * Call CADET's monitor API, request debug dump on the service.
- *
- * @param cls Closure (unused).
- */
- static void
- request_dump (void *cls)
- {
- GNUNET_CADET_request_dump (mh);
- GNUNET_SCHEDULER_shutdown ();
- }
- /**
- * Check data message sanity. Does nothing so far (all messages are OK).
- *
- * @param cls Closure (unused).
- * @param message The message to check.
- * @return #GNUNET_OK to keep the channel open,
- * #GNUNET_SYSERR to close it (signal serious error).
- */
- static int
- check_data (void *cls,
- const struct GNUNET_MessageHeader *message)
- {
- return GNUNET_OK; /* all is well-formed */
- }
- /**
- * Function called whenever a message is received.
- *
- * Each time the function must call #GNUNET_CADET_receive_done on the channel
- * in order to receive the next message. This doesn't need to be immediate:
- * can be delayed if some processing is done on the message.
- *
- * @param cls NULL
- * @param message The actual message.
- */
- static void
- handle_data (void *cls,
- const struct GNUNET_MessageHeader *message)
- {
- size_t payload_size = ntohs (message->size) - sizeof (*message);
- uint16_t len;
- ssize_t done;
- uint16_t off;
- const char *buf;
- GNUNET_CADET_receive_done (ch);
- if (GNUNET_YES == echo)
- {
- if (NULL != listen_port)
- {
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_MessageHeader *msg;
- env = GNUNET_MQ_msg_extra (msg,
- payload_size,
- GNUNET_MESSAGE_TYPE_CADET_CLI);
- GNUNET_memcpy (&msg[1],
- &message[1],
- payload_size);
- GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
- env);
- return;
- }
- else
- {
- struct GNUNET_TIME_Relative latency;
- latency = GNUNET_TIME_absolute_get_duration (echo_time);
- echo_time = GNUNET_TIME_UNIT_FOREVER_ABS;
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "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);
- 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");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- off += done;
- }
- }
- /**
- * Method called to retrieve information about all peers in CADET, called
- * once per peer.
- *
- * After last peer has been reported, an additional call with NULL is done.
- *
- * @param cls Closure.
- * @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)
- */
- static void
- peers_callback (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- int tunnel,
- unsigned int n_paths,
- unsigned int best_path)
- {
- if (NULL == peer)
- {
- 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 a specific peer
- * known to the service.
- *
- * @param cls Closure.
- * @param peer Peer ID.
- * @param tunnel Do we have a tunnel towards this peer? #GNUNET_YES/#GNUNET_NO
- * @param neighbor Is this a direct neighbor? #GNUNET_YES/#GNUNET_NO
- * @param n_paths Number of paths known towards peer.
- * @param paths Array of PEER_IDs representing all paths to reach the peer.
- * Each path starts with the local peer.
- * Each path ends with the destination peer (given in @c peer).
- */
- static void
- peer_callback (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- int tunnel,
- int neighbor,
- unsigned int n_paths,
- const struct GNUNET_PeerIdentity *paths)
- {
- unsigned int i;
- const struct GNUNET_PeerIdentity *p;
- FPRINTF (stdout,
- "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n",
- GNUNET_i2s_full (peer),
- tunnel ? "Y" : "N",
- neighbor ? "Y" : "N",
- n_paths);
- p = paths;
- for (i = 0; i < n_paths && NULL != p;)
- {
- FPRINTF (stdout,
- "%s ",
- GNUNET_i2s (p));
- if (0 == memcmp (p,
- peer,
- sizeof (*p)))
- {
- FPRINTF (stdout, "\n");
- i++;
- }
- p++;
- }
- GNUNET_SCHEDULER_shutdown();
- }
- /**
- * Method called to retrieve information about all tunnels in CADET.
- *
- * @param cls Closure.
- * @param peer Destination peer.
- * @param channels Number of channels.
- * @param connections Number of connections.
- * @param estate Encryption state.
- * @param cstate Connectivity state.
- */
- static 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)
- {
- GNUNET_SCHEDULER_shutdown();
- return;
- }
- FPRINTF (stdout,
- "%s [ENC: %s, CON: %s] CHs: %u, CONNs: %u\n",
- GNUNET_i2s_full (peer),
- enc_2s (estate),
- conn_2s (cstate),
- channels,
- connections);
- }
- /**
- * Method called to retrieve information about a specific tunnel the cadet 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.
- */
- static void
- tunnel_callback (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- unsigned int n_channels,
- unsigned int n_connections,
- const struct GNUNET_CADET_ChannelTunnelNumber *channels,
- const struct GNUNET_CADET_ConnectionTunnelIdentifier *connections,
- unsigned int estate,
- unsigned int cstate)
- {
- unsigned int i;
- if (NULL != peer)
- {
- FPRINTF (stdout, "Tunnel %s\n", GNUNET_i2s_full (peer));
- FPRINTF (stdout, "\t%u channels\n", n_channels);
- for (i = 0; i < n_channels; i++)
- FPRINTF (stdout, "\t\t%X\n", ntohl (channels[i].cn));
- FPRINTF (stdout, "\t%u connections\n", n_connections);
- for (i = 0; i < n_connections; i++)
- FPRINTF (stdout, "\t\t%s\n", GNUNET_sh2s (&connections[i].connection_of_tunnel));
- FPRINTF (stdout, "\tencryption state: %s\n", enc_2s (estate));
- FPRINTF (stdout, "\tconnection state: %s\n", conn_2s (cstate));
- }
- GNUNET_SCHEDULER_shutdown ();
- }
- /**
- * Call CADET's meta API, get all peers known to a peer.
- *
- * @param cls Closure (unused).
- */
- static void
- get_peers (void *cls)
- {
- job = NULL;
- GNUNET_CADET_get_peers (mh, &peers_callback, NULL);
- }
- /**
- * Call CADET's monitor API, get info of one peer.
- *
- * @param cls Closure (unused).
- */
- static void
- show_peer (void *cls)
- {
- struct GNUNET_PeerIdentity pid;
- job = NULL;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_public_key_from_string (peer_id,
- strlen (peer_id),
- &pid.public_key))
- {
- fprintf (stderr,
- _("Invalid peer ID `%s'\n"),
- peer_id);
- GNUNET_SCHEDULER_shutdown();
- return;
- }
- GNUNET_CADET_get_peer (mh, &pid, peer_callback, NULL);
- }
- /**
- * Call CADET's meta API, get all tunnels known to a peer.
- *
- * @param cls Closure (unused).
- */
- static void
- get_tunnels (void *cls)
- {
- job = NULL;
- GNUNET_CADET_get_tunnels (mh, &tunnels_callback, NULL);
- }
- /**
- * Call CADET's monitor API, get info of one tunnel.
- *
- * @param cls Closure (unused).
- */
- static void
- show_tunnel (void *cls)
- {
- struct GNUNET_PeerIdentity pid;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id,
- strlen (tunnel_id),
- &pid.public_key))
- {
- fprintf (stderr,
- _("Invalid tunnel owner `%s'\n"),
- tunnel_id);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_CADET_get_tunnel (mh,
- &pid,
- &tunnel_callback,
- NULL);
- }
- /**
- * Call CADET's monitor API, get info of one channel.
- *
- * @param cls Closure (unused).
- */
- static void
- show_channel (void *cls)
- {
- job = NULL;
- GNUNET_break (0);
- }
- /**
- * Call CADET's monitor API, get info of one connection.
- *
- * @param cls Closure (unused).
- */
- static void
- show_connection (void *cls)
- {
- job = NULL;
- GNUNET_break (0);
- }
- /**
- * 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 cfg configuration
- */
- static void
- run (void *cls,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
- {
- struct GNUNET_MQ_MessageHandler handlers[] = {
- GNUNET_MQ_hd_var_size (data,
- GNUNET_MESSAGE_TYPE_CADET_CLI,
- struct GNUNET_MessageHeader,
- NULL),
- GNUNET_MQ_handler_end ()
- };
- /* FIXME add option to monitor apps */
- target_id = args[0];
- if (target_id && args[1])
- target_port = args[1];
- if ( (0 != (request_peers | request_tunnels)
- || NULL != tunnel_id
- || NULL != conn_id
- || NULL != channel_id)
- && target_id != NULL)
- {
- FPRINTF (stderr,
- _("Extra arguments are not applicable "
- "in combination with this option.\n"));
- return;
- }
- if (GNUNET_YES == dump)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting debug dump\n");
- job = GNUNET_SCHEDULER_add_now (&request_dump,
- NULL);
- }
- else if (NULL != peer_id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Show peer\n");
- job = GNUNET_SCHEDULER_add_now (&show_peer,
- NULL);
- }
- else if (NULL != tunnel_id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Show tunnel\n");
- job = GNUNET_SCHEDULER_add_now (&show_tunnel,
- NULL);
- }
- else if (NULL != channel_id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Show channel\n");
- job = GNUNET_SCHEDULER_add_now (&show_channel,
- NULL);
- }
- else if (NULL != conn_id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Show connection\n");
- job = GNUNET_SCHEDULER_add_now (&show_connection,
- NULL);
- }
- else if (GNUNET_YES == request_peers)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Show all peers\n");
- job = GNUNET_SCHEDULER_add_now (&get_peers,
- NULL);
- }
- else if (GNUNET_YES == request_tunnels)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Show all tunnels\n");
- job = GNUNET_SCHEDULER_add_now (&get_tunnels,
- NULL);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Connecting to CADET service\n");
- mh = GNUNET_CADET_connect (cfg);
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
- NULL);
- if (NULL == mh)
- {
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- if (NULL != listen_port)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Opening CADET listen port\n");
- GNUNET_CRYPTO_hash (listen_port,
- strlen (listen_port),
- &porthash);
- lp = GNUNET_CADET_open_port (mh,
- &porthash,
- &channel_incoming,
- NULL,
- NULL /* window changes */,
- &channel_ended,
- handlers);
- }
- if (NULL != target_id)
- {
- struct GNUNET_PeerIdentity pid;
- enum GNUNET_CADET_ChannelOption opt;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
- strlen (target_id),
- &pid.public_key))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- _("Invalid target `%s'\n"),
- target_id);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Connecting to `%s:%s'\n",
- target_id,
- target_port);
- opt = GNUNET_CADET_OPTION_DEFAULT | GNUNET_CADET_OPTION_RELIABLE;
- GNUNET_CRYPTO_hash (target_port,
- strlen(target_port),
- &porthash);
- ch = GNUNET_CADET_channel_create (mh,
- NULL,
- &pid,
- &porthash,
- opt,
- NULL /* window changes */,
- &channel_ended,
- handlers);
- if (GNUNET_YES == echo)
- {
- echo_task = GNUNET_SCHEDULER_add_now (&send_echo,
- NULL);
- }
- else
- {
- listen_stdio ();
- }
- }
- if ( (NULL == lp) &&
- (NULL == job) &&
- (NULL == ch) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- _("No action requested\n"));
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- }
- /**
- * 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)
- {
- int res;
- const char helpstr[] = "Create tunnels and retrieve info about CADET's status.";
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- /* I would use the terminology 'circuit' here... --lynX */
- GNUNET_GETOPT_option_string ('C',
- "connection",
- "CONNECTION_ID",
- gettext_noop ("Provide information about a particular connection"),
- &conn_id),
- GNUNET_GETOPT_option_flag ('e',
- "echo",
- gettext_noop ("Activate echo mode"),
- &echo),
- GNUNET_GETOPT_option_flag ('d',
- "dump",
- gettext_noop ("Dump debug information to STDERR"),
- &dump),
- GNUNET_GETOPT_option_string ('o',
- "open-port",
- "SHARED_SECRET",
- gettext_noop ("Listen for connections using a shared secret among sender and recipient"),
- &listen_port),
- GNUNET_GETOPT_option_string ('p',
- "peer",
- "PEER_ID",
- gettext_noop ("Provide information about a patricular peer"),
- &peer_id),
- GNUNET_GETOPT_option_flag ('P',
- "peers",
- gettext_noop ("Provide information about all peers"),
- &request_peers),
- GNUNET_GETOPT_option_string ('t',
- "tunnel",
- "TUNNEL_ID",
- gettext_noop ("Provide information about a particular tunnel"),
- &tunnel_id),
- GNUNET_GETOPT_option_flag ('T',
- "tunnels",
- gettext_noop ("Provide information about all tunnels"),
- &request_tunnels),
- 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-cadet (OPTIONS | PEER_ID SHARED_SECRET)",
- gettext_noop (helpstr),
- options, &run, NULL);
- GNUNET_free ((void *) argv);
- if (GNUNET_OK == res)
- return 0;
- return 1;
- }
- /* end of gnunet-cadet.c */
|