gnunet

Main GNUnet Logic
Log | Files | Refs | Submodules | README | LICENSE

commit 7ad3095903787984e79fc5c1ec4fe5a9877efddf
parent e7ae1d89c44ba1087a69f84535851791fc1877fc
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Fri, 31 Jul 2026 11:08:53 +0200

transport: fotgot file

Diffstat:
Asrc/cli/transport/gnunet-transport.c | 326+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cli/transport/meson.build | 9+++++++++
2 files changed, 335 insertions(+), 0 deletions(-)

diff --git a/src/cli/transport/gnunet-transport.c b/src/cli/transport/gnunet-transport.c @@ -0,0 +1,326 @@ +/* + This file is part of GNUnet. + Copyright (C) 2026 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @file cli/transport/gnunet-transport.c + * @brief Print the virtual links transport currently has, with the flow + * control state CORE rides on. + * @author Martin Schanzenbach + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_transport_monitor_service.h" + +/** + * Return code. + */ +static int ret; + +/** + * Option -a: also show links that are not established yet. + */ +static int include_unconfirmed; + +/** + * Option -V: show the full flow control state of every link. + */ +static int verbose; + +/** + * Option -p: restrict the listing to this peer. + */ +static char *peer_id; + +/** + * Handle to the running listing, NULL once it completed. + */ +static struct GNUNET_TRANSPORT_LinkListContext *llc; + +/** + * Number of links reported so far. + */ +static unsigned int num_links; + + +/** + * Task run when the user aborts us or the listing finished. + * + * @param cls NULL + */ +static void +shutdown_task (void *cls) +{ + (void) cls; + if (NULL != llc) + { + GNUNET_TRANSPORT_links_list_cancel (llc); + llc = NULL; + } +} + + +/** + * Render how a link is routed into @a buf. + * + * @param li link to describe + * @param[out] buf where to write the description + * @param buf_size number of bytes available in @a buf + * @return @a buf + */ +static const char * +route_to_string (const struct GNUNET_TRANSPORT_LinkInformation *li, + char *buf, + size_t buf_size) +{ + if (GNUNET_TRANSPORT_LINK_ROUTE_DIRECT == li->route) + { + GNUNET_snprintf (buf, buf_size, "%s", _ ("direct")); + return buf; + } + /* `distance' counts neither the next hop nor the target, so the number + of hops a user would count is two more. */ + GNUNET_snprintf (buf, buf_size, _ ("dv (%u hops)"), li->distance + 2); + return buf; +} + + +/** + * Print everything we know about @a li, one field per line. + * + * @param peer peer at the other end of the link + * @param li the link to print + */ +static void +print_link_verbose (const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TRANSPORT_LinkInformation *li) +{ + char route[64]; + char *s1; + char *s2; + + fprintf (stdout, "%s\n", GNUNET_i2s_full (peer)); + fprintf (stdout, + _ (" routed: %s over %s (%u queue(s))\n"), + route_to_string (li, route, sizeof (route)), + ('\0' == li->communicators[0]) ? "-" : li->communicators, + li->num_queues); + fprintf (stdout, + _ (" established: %s\n"), + (GNUNET_YES == li->confirmed) ? _ ("yes") : _ ("no")); + fprintf (stdout, + _ (" CORE receive window: %d\n"), + li->core_recv_window); + fprintf (stdout, + _ (" stalled for CORE: %u message(s)\n"), + li->stalled); + fprintf (stdout, + _ (" pending transmission: %u message(s)\n"), + li->pending); + s1 = GNUNET_STRINGS_byte_size_fancy (li->incoming_fc_window_size_used); + s2 = GNUNET_STRINGS_byte_size_fancy (li->incoming_fc_window_size); + fprintf (stdout, _ (" inbound window used: %s of %s\n"), s1, s2); + GNUNET_free (s1); + GNUNET_free (s2); + s1 = GNUNET_STRINGS_byte_size_fancy (li->outbound_fc_window_size_used); + s2 = GNUNET_STRINGS_byte_size_fancy (li->outbound_fc_window_size); + fprintf (stdout, _ (" outbound window used: %s of %s\n"), s1, s2); + GNUNET_free (s1); + GNUNET_free (s2); + s1 = GNUNET_STRINGS_byte_size_fancy (li->incoming_fc_window_size_ram); + s2 = GNUNET_STRINGS_byte_size_fancy (li->available_fc_window_size); + fprintf (stdout, _ (" buffer used: %s of %s\n"), s1, s2); + GNUNET_free (s1); + GNUNET_free (s2); + fprintf (stdout, + _ (" estimated loss: %lld byte(s)\n"), + (long long) li->incoming_fc_window_size_loss); + fprintf (stdout, + _ (" flow control RTT: %s (peer reports %s)\n"), + GNUNET_STRINGS_relative_time_to_string (li->last_fc_rtt, + GNUNET_YES), + GNUNET_STRINGS_relative_time_to_string (li->other_rtt, + GNUNET_YES)); + fprintf (stdout, + _ (" last flow control: %s ago (%u retransmission(s))\n"), + GNUNET_STRINGS_relative_time_to_string ( + GNUNET_TIME_absolute_get_duration (li->last_fc_transmission), + GNUNET_YES), + li->fc_retransmit_count); + fprintf (stdout, "\n"); +} + + +/** + * Function called once per virtual link, and a final time with both + * arguments NULL. + * + * @param cls NULL + * @param peer peer at the other end of the link, NULL when done + * @param li state of the link, NULL when done + */ +static void +link_cb (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TRANSPORT_LinkInformation *li) +{ + char route[64]; + + (void) cls; + if (NULL == peer) + { + /* The listing completed; the handle released itself. */ + llc = NULL; + if (0 == num_links) + fprintf (stdout, "%s\n", _ ("No virtual links.")); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (verbose) + { + print_link_verbose (peer, li); + num_links++; + return; + } + if (0 == num_links) + fprintf (stdout, + "%-10s %-14s %-12s %9s %8s %8s %10s\n", + _ ("PEER"), + _ ("ROUTE"), + _ ("VIA"), + _ ("CORE-WIN"), + _ ("STALLED"), + _ ("PENDING"), + _ ("RTT")); + num_links++; + fprintf (stdout, + "%-10s %-14s %-12s %9d %8u %8u %10s\n", + GNUNET_i2s (peer), + route_to_string (li, route, sizeof (route)), + ('\0' == li->communicators[0]) ? "-" : li->communicators, + li->core_recv_window, + li->stalled, + li->pending, + GNUNET_STRINGS_relative_time_to_string (li->last_fc_rtt, + GNUNET_YES)); +} + + +/** + * 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 (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_PeerIdentity pid; + const struct GNUNET_PeerIdentity *pidp = NULL; + + (void) cls; + (void) cfgfile; + if (NULL != args[0]) + { + fprintf (stderr, _ ("Invalid command line argument `%s'\n"), args[0]); + ret = 1; + return; + } + if (NULL != peer_id) + { + 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); + ret = 1; + return; + } + pidp = &pid; + } + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); + llc = GNUNET_TRANSPORT_links_list (cfg, + pidp, + include_unconfirmed ? GNUNET_YES + : GNUNET_NO, + &link_cb, + NULL); + if (NULL == llc) + { + fprintf (stderr, "%s", _ ("Failed to connect to transport service!\n")); + ret = 1; + GNUNET_SCHEDULER_shutdown (); + } +} + + +/** + * The main function to list the virtual links of the transport service. + * + * @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; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_flag ( + 'a', + "all", + gettext_noop ("also show links that are not established yet"), + &include_unconfirmed), + GNUNET_GETOPT_option_string ( + 'p', + "peer", + "PEERID", + gettext_noop ("only show the link to this peer"), + &peer_id), + GNUNET_GETOPT_option_flag ( + 'V', + "verbose", + gettext_noop ("show the full flow control state of every link"), + &verbose), + GNUNET_GETOPT_OPTION_END + }; + + res = GNUNET_PROGRAM_run (GNUNET_OS_project_data_gnunet (), + argc, + argv, + "gnunet-transport", + gettext_noop ( + "Print information about the virtual links of " + "the transport service."), + options, + &run, + NULL); + if (GNUNET_OK == res) + return ret; + return 1; +} + + +/* end of gnunet-transport.c */ diff --git a/src/cli/transport/meson.build b/src/cli/transport/meson.build @@ -0,0 +1,9 @@ +executable( + 'gnunet-transport', + ['gnunet-transport.c'], + install_rpath: rpath_option, + dependencies: [libgnunettransportmonitor_dep, libgnunetutil_dep], + include_directories: [incdir, configuration_inc], + install: true, + install_dir: get_option('bindir'), +)