gnunet-cadet.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012, 2017 GNUnet e.V.
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. /**
  18. * @file cadet/gnunet-cadet.c
  19. * @brief Print information about cadet tunnels and peers.
  20. * @author Bartlomiej Polot
  21. * @author Christian Grothoff
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_cadet_service.h"
  26. #include "cadet.h"
  27. /**
  28. * Option -P.
  29. */
  30. static int request_peers;
  31. /**
  32. * Option --peer
  33. */
  34. static char *peer_id;
  35. /**
  36. * Option -T.
  37. */
  38. static int request_tunnels;
  39. /**
  40. * Option --tunnel
  41. */
  42. static char *tunnel_id;
  43. /**
  44. * Option --connection
  45. */
  46. static char *conn_id;
  47. /**
  48. * Option --channel
  49. */
  50. static char *channel_id;
  51. /**
  52. * Port to listen on (-o).
  53. */
  54. static char *listen_port;
  55. /**
  56. * Request echo service
  57. */
  58. static int echo;
  59. /**
  60. * Request a debug dump
  61. */
  62. static int dump;
  63. /**
  64. * Time of last echo request.
  65. */
  66. static struct GNUNET_TIME_Absolute echo_time;
  67. /**
  68. * Task for next echo request.
  69. */
  70. static struct GNUNET_SCHEDULER_Task *echo_task;
  71. /**
  72. * Peer to connect to.
  73. */
  74. static char *target_id;
  75. /**
  76. * Port to connect to
  77. */
  78. static char *target_port = "default";
  79. /**
  80. * Cadet handle.
  81. */
  82. static struct GNUNET_CADET_Handle *mh;
  83. /**
  84. * Channel handle.
  85. */
  86. static struct GNUNET_CADET_Channel *ch;
  87. /**
  88. * HashCode of the given port string
  89. */
  90. static struct GNUNET_HashCode porthash;
  91. /**
  92. * Data structure for ongoing reception of incoming virtual circuits.
  93. */
  94. struct GNUNET_CADET_Port *lp;
  95. /**
  96. * Task for reading from stdin.
  97. */
  98. static struct GNUNET_SCHEDULER_Task *rd_task;
  99. /**
  100. * Task for main job.
  101. */
  102. static struct GNUNET_SCHEDULER_Task *job;
  103. /**
  104. * Wait for input on STDIO and send it out over the #ch.
  105. */
  106. static void
  107. listen_stdio (void);
  108. /**
  109. * Convert encryption status to human readable string.
  110. *
  111. * @param status Encryption status.
  112. *
  113. * @return Human readable string.
  114. */
  115. static const char *
  116. enc_2s (uint16_t status)
  117. {
  118. switch (status)
  119. {
  120. case 0:
  121. return "NULL ";
  122. case 1:
  123. return "KSENT";
  124. case 2:
  125. return "KRECV";
  126. case 3:
  127. return "READY";
  128. default:
  129. return "";
  130. }
  131. }
  132. /**
  133. * Convert connection status to human readable string.
  134. *
  135. * @param status Connection status.
  136. *
  137. * @return Human readable string.
  138. */
  139. static const char *
  140. conn_2s (uint16_t status)
  141. {
  142. switch (status)
  143. {
  144. case 0:
  145. return "NEW ";
  146. case 1:
  147. return "SRCH ";
  148. case 2:
  149. return "WAIT ";
  150. case 3:
  151. return "READY";
  152. case 4:
  153. return "SHUTD";
  154. default:
  155. return "";
  156. }
  157. }
  158. /**
  159. * Task to shut down this application.
  160. *
  161. * @param cls Closure (unused).
  162. */
  163. static void
  164. shutdown_task (void *cls)
  165. {
  166. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  167. "Shutdown\n");
  168. if (NULL != ch)
  169. {
  170. GNUNET_CADET_channel_destroy (ch);
  171. ch = NULL;
  172. }
  173. if (NULL != mh)
  174. {
  175. GNUNET_CADET_disconnect (mh);
  176. mh = NULL;
  177. }
  178. if (NULL != rd_task)
  179. {
  180. GNUNET_SCHEDULER_cancel (rd_task);
  181. rd_task = NULL;
  182. }
  183. if (NULL != echo_task)
  184. {
  185. GNUNET_SCHEDULER_cancel (echo_task);
  186. echo_task = NULL;
  187. }
  188. if (NULL != job)
  189. {
  190. GNUNET_SCHEDULER_cancel (job);
  191. job = NULL;
  192. }
  193. }
  194. /**
  195. * Task run in stdio mode, after some data is available at stdin.
  196. *
  197. * @param cls Closure (unused).
  198. */
  199. static void
  200. read_stdio (void *cls)
  201. {
  202. struct GNUNET_MQ_Envelope *env;
  203. struct GNUNET_MessageHeader *msg;
  204. char buf[60000];
  205. ssize_t data_size;
  206. rd_task = NULL;
  207. data_size = read (0,
  208. buf,
  209. 60000);
  210. if (data_size < 1)
  211. {
  212. GNUNET_SCHEDULER_shutdown();
  213. return;
  214. }
  215. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  216. "Read %u bytes from stdio\n",
  217. (unsigned int) data_size);
  218. env = GNUNET_MQ_msg_extra (msg,
  219. data_size,
  220. GNUNET_MESSAGE_TYPE_CADET_CLI);
  221. GNUNET_memcpy (&msg[1],
  222. buf,
  223. data_size);
  224. GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
  225. env);
  226. if (GNUNET_NO == echo)
  227. {
  228. listen_stdio ();
  229. }
  230. else
  231. {
  232. echo_time = GNUNET_TIME_absolute_get ();
  233. }
  234. }
  235. /**
  236. * Wait for input on STDIO and send it out over the #ch.
  237. */
  238. static void
  239. listen_stdio ()
  240. {
  241. struct GNUNET_NETWORK_FDSet *rs;
  242. /* FIXME: why use 'rs' here, seems overly complicated... */
  243. rs = GNUNET_NETWORK_fdset_create ();
  244. GNUNET_NETWORK_fdset_set_native (rs,
  245. 0); /* STDIN */
  246. rd_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
  247. GNUNET_TIME_UNIT_FOREVER_REL,
  248. rs,
  249. NULL,
  250. &read_stdio,
  251. NULL);
  252. GNUNET_NETWORK_fdset_destroy (rs);
  253. }
  254. /**
  255. * Function called whenever a channel is destroyed. Should clean up
  256. * any associated state.
  257. *
  258. * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
  259. *
  260. * @param cls closure
  261. * @param channel connection to the other end (henceforth invalid)
  262. */
  263. static void
  264. channel_ended (void *cls,
  265. const struct GNUNET_CADET_Channel *channel)
  266. {
  267. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  268. "Channel ended!\n");
  269. GNUNET_assert (channel == ch);
  270. ch = NULL;
  271. GNUNET_SCHEDULER_shutdown ();
  272. }
  273. /**
  274. * Method called whenever another peer has added us to a channel
  275. * the other peer initiated.
  276. * Only called (once) upon reception of data with a message type which was
  277. * subscribed to in #GNUNET_CADET_connect.
  278. *
  279. * A call to #GNUNET_CADET_channel_destroy causes the channel to be ignored.
  280. * In this case the handler MUST return NULL.
  281. *
  282. * @param cls closure
  283. * @param channel new handle to the channel
  284. * @param initiator peer that started the channel
  285. * @return initial channel context for the channel, we use @a channel
  286. */
  287. static void *
  288. channel_incoming (void *cls,
  289. struct GNUNET_CADET_Channel *channel,
  290. const struct GNUNET_PeerIdentity *initiator)
  291. {
  292. GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
  293. "Incoming connection from %s\n",
  294. GNUNET_i2s_full (initiator));
  295. GNUNET_assert (NULL == ch);
  296. GNUNET_assert (NULL != lp);
  297. GNUNET_CADET_close_port (lp);
  298. lp = NULL;
  299. ch = channel;
  300. if (GNUNET_NO == echo)
  301. listen_stdio ();
  302. return channel;
  303. }
  304. /**
  305. * @brief Send an echo request to the remote peer.
  306. *
  307. * @param cls Closure (NULL).
  308. */
  309. static void
  310. send_echo (void *cls)
  311. {
  312. struct GNUNET_MQ_Envelope *env;
  313. struct GNUNET_MessageHeader *msg;
  314. echo_task = NULL;
  315. if (NULL == ch)
  316. return;
  317. env = GNUNET_MQ_msg (msg,
  318. GNUNET_MESSAGE_TYPE_CADET_CLI);
  319. GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
  320. env);
  321. }
  322. /**
  323. * Call CADET's monitor API, request debug dump on the service.
  324. *
  325. * @param cls Closure (unused).
  326. */
  327. static void
  328. request_dump (void *cls)
  329. {
  330. GNUNET_CADET_request_dump (mh);
  331. GNUNET_SCHEDULER_shutdown ();
  332. }
  333. /**
  334. * Check data message sanity. Does nothing so far (all messages are OK).
  335. *
  336. * @param cls Closure (unused).
  337. * @param message The message to check.
  338. * @return #GNUNET_OK to keep the channel open,
  339. * #GNUNET_SYSERR to close it (signal serious error).
  340. */
  341. static int
  342. check_data (void *cls,
  343. const struct GNUNET_MessageHeader *message)
  344. {
  345. return GNUNET_OK; /* all is well-formed */
  346. }
  347. /**
  348. * Function called whenever a message is received.
  349. *
  350. * Each time the function must call #GNUNET_CADET_receive_done on the channel
  351. * in order to receive the next message. This doesn't need to be immediate:
  352. * can be delayed if some processing is done on the message.
  353. *
  354. * @param cls NULL
  355. * @param message The actual message.
  356. */
  357. static void
  358. handle_data (void *cls,
  359. const struct GNUNET_MessageHeader *message)
  360. {
  361. size_t payload_size = ntohs (message->size) - sizeof (*message);
  362. uint16_t len;
  363. ssize_t done;
  364. uint16_t off;
  365. const char *buf;
  366. GNUNET_CADET_receive_done (ch);
  367. if (GNUNET_YES == echo)
  368. {
  369. if (NULL != listen_port)
  370. {
  371. struct GNUNET_MQ_Envelope *env;
  372. struct GNUNET_MessageHeader *msg;
  373. env = GNUNET_MQ_msg_extra (msg,
  374. payload_size,
  375. GNUNET_MESSAGE_TYPE_CADET_CLI);
  376. GNUNET_memcpy (&msg[1],
  377. &message[1],
  378. payload_size);
  379. GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
  380. env);
  381. return;
  382. }
  383. else
  384. {
  385. struct GNUNET_TIME_Relative latency;
  386. latency = GNUNET_TIME_absolute_get_duration (echo_time);
  387. echo_time = GNUNET_TIME_UNIT_FOREVER_ABS;
  388. GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
  389. "time: %s\n",
  390. GNUNET_STRINGS_relative_time_to_string (latency,
  391. GNUNET_NO));
  392. echo_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
  393. &send_echo,
  394. NULL);
  395. }
  396. }
  397. len = ntohs (message->size) - sizeof (*message);
  398. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  399. "Got %u bytes\n",
  400. len);
  401. buf = (const char *) &message[1];
  402. off = 0;
  403. while (off < len)
  404. {
  405. done = write (1,
  406. &buf[off],
  407. len - off);
  408. if (done <= 0)
  409. {
  410. if (-1 == done)
  411. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  412. "write");
  413. GNUNET_SCHEDULER_shutdown ();
  414. return;
  415. }
  416. off += done;
  417. }
  418. }
  419. /**
  420. * Method called to retrieve information about all peers in CADET, called
  421. * once per peer.
  422. *
  423. * After last peer has been reported, an additional call with NULL is done.
  424. *
  425. * @param cls Closure.
  426. * @param peer Peer, or NULL on "EOF".
  427. * @param tunnel Do we have a tunnel towards this peer?
  428. * @param n_paths Number of known paths towards this peer.
  429. * @param best_path How long is the best path?
  430. * (0 = unknown, 1 = ourselves, 2 = neighbor)
  431. */
  432. static void
  433. peers_callback (void *cls,
  434. const struct GNUNET_PeerIdentity *peer,
  435. int tunnel,
  436. unsigned int n_paths,
  437. unsigned int best_path)
  438. {
  439. if (NULL == peer)
  440. {
  441. GNUNET_SCHEDULER_shutdown();
  442. return;
  443. }
  444. FPRINTF (stdout,
  445. "%s tunnel: %c, paths: %u\n",
  446. GNUNET_i2s_full (peer),
  447. tunnel ? 'Y' : 'N',
  448. n_paths);
  449. }
  450. /**
  451. * Method called to retrieve information about a specific peer
  452. * known to the service.
  453. *
  454. * @param cls Closure.
  455. * @param peer Peer ID.
  456. * @param tunnel Do we have a tunnel towards this peer? #GNUNET_YES/#GNUNET_NO
  457. * @param neighbor Is this a direct neighbor? #GNUNET_YES/#GNUNET_NO
  458. * @param n_paths Number of paths known towards peer.
  459. * @param paths Array of PEER_IDs representing all paths to reach the peer.
  460. * Each path starts with the local peer.
  461. * Each path ends with the destination peer (given in @c peer).
  462. */
  463. static void
  464. peer_callback (void *cls,
  465. const struct GNUNET_PeerIdentity *peer,
  466. int tunnel,
  467. int neighbor,
  468. unsigned int n_paths,
  469. const struct GNUNET_PeerIdentity *paths)
  470. {
  471. unsigned int i;
  472. const struct GNUNET_PeerIdentity *p;
  473. FPRINTF (stdout,
  474. "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n",
  475. GNUNET_i2s_full (peer),
  476. tunnel ? "Y" : "N",
  477. neighbor ? "Y" : "N",
  478. n_paths);
  479. p = paths;
  480. for (i = 0; i < n_paths && NULL != p;)
  481. {
  482. FPRINTF (stdout,
  483. "%s ",
  484. GNUNET_i2s (p));
  485. if (0 == memcmp (p,
  486. peer,
  487. sizeof (*p)))
  488. {
  489. FPRINTF (stdout, "\n");
  490. i++;
  491. }
  492. p++;
  493. }
  494. GNUNET_SCHEDULER_shutdown();
  495. }
  496. /**
  497. * Method called to retrieve information about all tunnels in CADET.
  498. *
  499. * @param cls Closure.
  500. * @param peer Destination peer.
  501. * @param channels Number of channels.
  502. * @param connections Number of connections.
  503. * @param estate Encryption state.
  504. * @param cstate Connectivity state.
  505. */
  506. static void
  507. tunnels_callback (void *cls,
  508. const struct GNUNET_PeerIdentity *peer,
  509. unsigned int channels,
  510. unsigned int connections,
  511. uint16_t estate,
  512. uint16_t cstate)
  513. {
  514. if (NULL == peer)
  515. {
  516. GNUNET_SCHEDULER_shutdown();
  517. return;
  518. }
  519. FPRINTF (stdout,
  520. "%s [ENC: %s, CON: %s] CHs: %u, CONNs: %u\n",
  521. GNUNET_i2s_full (peer),
  522. enc_2s (estate),
  523. conn_2s (cstate),
  524. channels,
  525. connections);
  526. }
  527. /**
  528. * Method called to retrieve information about a specific tunnel the cadet peer
  529. * has established, o`r is trying to establish.
  530. *
  531. * @param cls Closure.
  532. * @param peer Peer towards whom the tunnel is directed.
  533. * @param n_channels Number of channels.
  534. * @param n_connections Number of connections.
  535. * @param channels Channels.
  536. * @param connections Connections.
  537. * @param estate Encryption status.
  538. * @param cstate Connectivity status.
  539. */
  540. static void
  541. tunnel_callback (void *cls,
  542. const struct GNUNET_PeerIdentity *peer,
  543. unsigned int n_channels,
  544. unsigned int n_connections,
  545. const struct GNUNET_CADET_ChannelTunnelNumber *channels,
  546. const struct GNUNET_CADET_ConnectionTunnelIdentifier *connections,
  547. unsigned int estate,
  548. unsigned int cstate)
  549. {
  550. unsigned int i;
  551. if (NULL != peer)
  552. {
  553. FPRINTF (stdout, "Tunnel %s\n", GNUNET_i2s_full (peer));
  554. FPRINTF (stdout, "\t%u channels\n", n_channels);
  555. for (i = 0; i < n_channels; i++)
  556. FPRINTF (stdout, "\t\t%X\n", ntohl (channels[i].cn));
  557. FPRINTF (stdout, "\t%u connections\n", n_connections);
  558. for (i = 0; i < n_connections; i++)
  559. FPRINTF (stdout, "\t\t%s\n", GNUNET_sh2s (&connections[i].connection_of_tunnel));
  560. FPRINTF (stdout, "\tencryption state: %s\n", enc_2s (estate));
  561. FPRINTF (stdout, "\tconnection state: %s\n", conn_2s (cstate));
  562. }
  563. GNUNET_SCHEDULER_shutdown ();
  564. }
  565. /**
  566. * Call CADET's meta API, get all peers known to a peer.
  567. *
  568. * @param cls Closure (unused).
  569. */
  570. static void
  571. get_peers (void *cls)
  572. {
  573. job = NULL;
  574. GNUNET_CADET_get_peers (mh, &peers_callback, NULL);
  575. }
  576. /**
  577. * Call CADET's monitor API, get info of one peer.
  578. *
  579. * @param cls Closure (unused).
  580. */
  581. static void
  582. show_peer (void *cls)
  583. {
  584. struct GNUNET_PeerIdentity pid;
  585. job = NULL;
  586. if (GNUNET_OK !=
  587. GNUNET_CRYPTO_eddsa_public_key_from_string (peer_id,
  588. strlen (peer_id),
  589. &pid.public_key))
  590. {
  591. fprintf (stderr,
  592. _("Invalid peer ID `%s'\n"),
  593. peer_id);
  594. GNUNET_SCHEDULER_shutdown();
  595. return;
  596. }
  597. GNUNET_CADET_get_peer (mh, &pid, peer_callback, NULL);
  598. }
  599. /**
  600. * Call CADET's meta API, get all tunnels known to a peer.
  601. *
  602. * @param cls Closure (unused).
  603. */
  604. static void
  605. get_tunnels (void *cls)
  606. {
  607. job = NULL;
  608. GNUNET_CADET_get_tunnels (mh, &tunnels_callback, NULL);
  609. }
  610. /**
  611. * Call CADET's monitor API, get info of one tunnel.
  612. *
  613. * @param cls Closure (unused).
  614. */
  615. static void
  616. show_tunnel (void *cls)
  617. {
  618. struct GNUNET_PeerIdentity pid;
  619. if (GNUNET_OK !=
  620. GNUNET_CRYPTO_eddsa_public_key_from_string (tunnel_id,
  621. strlen (tunnel_id),
  622. &pid.public_key))
  623. {
  624. fprintf (stderr,
  625. _("Invalid tunnel owner `%s'\n"),
  626. tunnel_id);
  627. GNUNET_SCHEDULER_shutdown ();
  628. return;
  629. }
  630. GNUNET_CADET_get_tunnel (mh,
  631. &pid,
  632. &tunnel_callback,
  633. NULL);
  634. }
  635. /**
  636. * Call CADET's monitor API, get info of one channel.
  637. *
  638. * @param cls Closure (unused).
  639. */
  640. static void
  641. show_channel (void *cls)
  642. {
  643. job = NULL;
  644. GNUNET_break (0);
  645. }
  646. /**
  647. * Call CADET's monitor API, get info of one connection.
  648. *
  649. * @param cls Closure (unused).
  650. */
  651. static void
  652. show_connection (void *cls)
  653. {
  654. job = NULL;
  655. GNUNET_break (0);
  656. }
  657. /**
  658. * Main function that will be run by the scheduler.
  659. *
  660. * @param cls closure
  661. * @param args remaining command-line arguments
  662. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  663. * @param cfg configuration
  664. */
  665. static void
  666. run (void *cls,
  667. char *const *args,
  668. const char *cfgfile,
  669. const struct GNUNET_CONFIGURATION_Handle *cfg)
  670. {
  671. struct GNUNET_MQ_MessageHandler handlers[] = {
  672. GNUNET_MQ_hd_var_size (data,
  673. GNUNET_MESSAGE_TYPE_CADET_CLI,
  674. struct GNUNET_MessageHeader,
  675. NULL),
  676. GNUNET_MQ_handler_end ()
  677. };
  678. /* FIXME add option to monitor apps */
  679. target_id = args[0];
  680. if (target_id && args[1])
  681. target_port = args[1];
  682. if ( (0 != (request_peers | request_tunnels)
  683. || NULL != tunnel_id
  684. || NULL != conn_id
  685. || NULL != channel_id)
  686. && target_id != NULL)
  687. {
  688. FPRINTF (stderr,
  689. _("Extra arguments are not applicable "
  690. "in combination with this option.\n"));
  691. return;
  692. }
  693. if (GNUNET_YES == dump)
  694. {
  695. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  696. "Requesting debug dump\n");
  697. job = GNUNET_SCHEDULER_add_now (&request_dump,
  698. NULL);
  699. }
  700. else if (NULL != peer_id)
  701. {
  702. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  703. "Show peer\n");
  704. job = GNUNET_SCHEDULER_add_now (&show_peer,
  705. NULL);
  706. }
  707. else if (NULL != tunnel_id)
  708. {
  709. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  710. "Show tunnel\n");
  711. job = GNUNET_SCHEDULER_add_now (&show_tunnel,
  712. NULL);
  713. }
  714. else if (NULL != channel_id)
  715. {
  716. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  717. "Show channel\n");
  718. job = GNUNET_SCHEDULER_add_now (&show_channel,
  719. NULL);
  720. }
  721. else if (NULL != conn_id)
  722. {
  723. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  724. "Show connection\n");
  725. job = GNUNET_SCHEDULER_add_now (&show_connection,
  726. NULL);
  727. }
  728. else if (GNUNET_YES == request_peers)
  729. {
  730. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  731. "Show all peers\n");
  732. job = GNUNET_SCHEDULER_add_now (&get_peers,
  733. NULL);
  734. }
  735. else if (GNUNET_YES == request_tunnels)
  736. {
  737. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  738. "Show all tunnels\n");
  739. job = GNUNET_SCHEDULER_add_now (&get_tunnels,
  740. NULL);
  741. }
  742. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  743. "Connecting to CADET service\n");
  744. mh = GNUNET_CADET_connect (cfg);
  745. GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
  746. NULL);
  747. if (NULL == mh)
  748. {
  749. GNUNET_SCHEDULER_shutdown ();
  750. return;
  751. }
  752. if (NULL != listen_port)
  753. {
  754. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  755. "Opening CADET listen port\n");
  756. GNUNET_CRYPTO_hash (listen_port,
  757. strlen (listen_port),
  758. &porthash);
  759. lp = GNUNET_CADET_open_port (mh,
  760. &porthash,
  761. &channel_incoming,
  762. NULL,
  763. NULL /* window changes */,
  764. &channel_ended,
  765. handlers);
  766. }
  767. if (NULL != target_id)
  768. {
  769. struct GNUNET_PeerIdentity pid;
  770. enum GNUNET_CADET_ChannelOption opt;
  771. if (GNUNET_OK !=
  772. GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
  773. strlen (target_id),
  774. &pid.public_key))
  775. {
  776. GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
  777. _("Invalid target `%s'\n"),
  778. target_id);
  779. GNUNET_SCHEDULER_shutdown ();
  780. return;
  781. }
  782. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  783. "Connecting to `%s:%s'\n",
  784. target_id,
  785. target_port);
  786. opt = GNUNET_CADET_OPTION_DEFAULT | GNUNET_CADET_OPTION_RELIABLE;
  787. GNUNET_CRYPTO_hash (target_port,
  788. strlen(target_port),
  789. &porthash);
  790. ch = GNUNET_CADET_channel_create (mh,
  791. NULL,
  792. &pid,
  793. &porthash,
  794. opt,
  795. NULL /* window changes */,
  796. &channel_ended,
  797. handlers);
  798. if (GNUNET_YES == echo)
  799. {
  800. echo_task = GNUNET_SCHEDULER_add_now (&send_echo,
  801. NULL);
  802. }
  803. else
  804. {
  805. listen_stdio ();
  806. }
  807. }
  808. if ( (NULL == lp) &&
  809. (NULL == job) &&
  810. (NULL == ch) )
  811. {
  812. GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
  813. _("No action requested\n"));
  814. GNUNET_SCHEDULER_shutdown ();
  815. return;
  816. }
  817. }
  818. /**
  819. * The main function to obtain peer information.
  820. *
  821. * @param argc number of arguments from the command line
  822. * @param argv command line arguments
  823. * @return 0 ok, 1 on error
  824. */
  825. int
  826. main (int argc,
  827. char *const *argv)
  828. {
  829. int res;
  830. const char helpstr[] = "Create tunnels and retrieve info about CADET's status.";
  831. struct GNUNET_GETOPT_CommandLineOption options[] = {
  832. /* I would use the terminology 'circuit' here... --lynX */
  833. GNUNET_GETOPT_option_string ('C',
  834. "connection",
  835. "CONNECTION_ID",
  836. gettext_noop ("Provide information about a particular connection"),
  837. &conn_id),
  838. GNUNET_GETOPT_option_flag ('e',
  839. "echo",
  840. gettext_noop ("Activate echo mode"),
  841. &echo),
  842. GNUNET_GETOPT_option_flag ('d',
  843. "dump",
  844. gettext_noop ("Dump debug information to STDERR"),
  845. &dump),
  846. GNUNET_GETOPT_option_string ('o',
  847. "open-port",
  848. "SHARED_SECRET",
  849. gettext_noop ("Listen for connections using a shared secret among sender and recipient"),
  850. &listen_port),
  851. GNUNET_GETOPT_option_string ('p',
  852. "peer",
  853. "PEER_ID",
  854. gettext_noop ("Provide information about a patricular peer"),
  855. &peer_id),
  856. GNUNET_GETOPT_option_flag ('P',
  857. "peers",
  858. gettext_noop ("Provide information about all peers"),
  859. &request_peers),
  860. GNUNET_GETOPT_option_string ('t',
  861. "tunnel",
  862. "TUNNEL_ID",
  863. gettext_noop ("Provide information about a particular tunnel"),
  864. &tunnel_id),
  865. GNUNET_GETOPT_option_flag ('T',
  866. "tunnels",
  867. gettext_noop ("Provide information about all tunnels"),
  868. &request_tunnels),
  869. GNUNET_GETOPT_OPTION_END
  870. };
  871. if (GNUNET_OK !=
  872. GNUNET_STRINGS_get_utf8_args (argc, argv,
  873. &argc, &argv))
  874. return 2;
  875. res = GNUNET_PROGRAM_run (argc, argv,
  876. "gnunet-cadet (OPTIONS | PEER_ID SHARED_SECRET)",
  877. gettext_noop (helpstr),
  878. options, &run, NULL);
  879. GNUNET_free ((void *) argv);
  880. if (GNUNET_OK == res)
  881. return 0;
  882. return 1;
  883. }
  884. /* end of gnunet-cadet.c */