gnunet

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

gnunet-core.c (6304B)


      1 /*
      2      This file is part of GNUnet.
      3      Copyright (C) 2011, 2012, 2014, 2025 GNUnet e.V.
      4 
      5      GNUnet is free software: you can redistribute it and/or modify it
      6      under the terms of the GNU Affero General Public License as published
      7      by the Free Software Foundation, either version 3 of the License,
      8      or (at your option) any later version.
      9 
     10      GNUnet is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      Affero General Public License for more details.
     14 
     15      You should have received a copy of the GNU Affero General Public License
     16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18      SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 
     21 /**
     22  * @file core/gnunet-core.c
     23  * @brief Print information about other peers known to CORE.
     24  * @author Nathan Evans
     25  * @author Martin Schanzenbach
     26  */
     27 #include "platform.h"
     28 #include "gnunet_time_lib.h"
     29 #include "gnunet_util_lib.h"
     30 #include "gnunet_core_service.h"
     31 
     32 /**
     33  * Return code
     34  */
     35 static int ret;
     36 
     37 /**
     38  * Option -m.
     39  */
     40 static int monitor_connections;
     41 
     42 /**
     43  * Option -s.
     44  */
     45 static int show_conns;
     46 
     47 /**
     48  * Handle to the CORE monitor.
     49  */
     50 static struct GNUNET_CORE_MonitorHandle *mh;
     51 
     52 /**
     53  * Task run in monitor mode when the user presses CTRL-C to abort.
     54  * Stops monitoring activity.
     55  *
     56  * @param cls NULL
     57  */
     58 static void
     59 shutdown_task (void *cls)
     60 {
     61   (void) cls;
     62   if (NULL != mh)
     63   {
     64     GNUNET_CORE_monitor_stop (mh);
     65     mh = NULL;
     66   }
     67 }
     68 
     69 
     70 /**
     71  * Function called to notify core users that another
     72  * peer changed its state with us.
     73  *
     74  * @param cls closure
     75  * @param peer the peer that changed state
     76  * @param state new state of the peer
     77  * @param timeout timeout for the new state
     78  */
     79 static void
     80 monitor_cb (void *cls,
     81             const struct GNUNET_PeerIdentity *peer,
     82             enum GNUNET_CORE_KxState state,
     83             struct GNUNET_TIME_Absolute timeout)
     84 {
     85   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
     86   const char *now_str;
     87   const char *state_str;
     88 
     89   (void) cls;
     90   if (((NULL == peer) || (GNUNET_CORE_KX_ITERATION_FINISHED == state)) &&
     91       (GNUNET_NO == monitor_connections))
     92   {
     93     GNUNET_SCHEDULER_shutdown ();
     94     return;
     95   }
     96 
     97   switch (state)
     98   {
     99   case GNUNET_CORE_KX_STATE_INITIATOR_HELLO_SENT:
    100     state_str = _ ("Hello sent (I)");
    101     break;
    102 
    103   case GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT:
    104     state_str = _ ("Done sent (I)");
    105     break;
    106 
    107   case GNUNET_CORE_KX_STATE_AWAIT_INITIATION:
    108     state_str = _ ("Awaiting initiation (R)");
    109     break;
    110 
    111   case GNUNET_CORE_KX_STATE_INITIATOR_HELLO_RECEIVED:
    112     state_str = _ ("Hello received (R)");
    113     break;
    114 
    115   case GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT:
    116     state_str = _ ("Hello sent (R)");
    117     break;
    118 
    119   case GNUNET_CORE_KX_STATE_RESPONDER_HELLO_RECEIVED:
    120     state_str = _ ("Hello received (I)");
    121     break;
    122 
    123   case GNUNET_CORE_KX_STATE_INITIATOR_CONNECTED:
    124     state_str = _ ("Connected (I)");
    125     break;
    126 
    127   case GNUNET_CORE_KX_STATE_RESPONDER_CONNECTED:
    128     state_str = _ ("Connected (R)");
    129     break;
    130 
    131   case GNUNET_CORE_KX_STATE_DOWN:
    132     /* should never happen, as we immediately send the key */
    133     state_str = _ ("idle");
    134     break;
    135 
    136   case GNUNET_CORE_KX_PEER_DISCONNECT:
    137     state_str = _ ("disconnected");
    138     break;
    139 
    140   case GNUNET_CORE_KX_ITERATION_FINISHED:
    141     return;
    142 
    143   case GNUNET_CORE_KX_CORE_DISCONNECT:
    144     fprintf (stderr,
    145              "%s\n",
    146              _ ("Connection to CORE service lost (reconnecting)"));
    147     return;
    148 
    149   default:
    150     state_str = _ ("unknown state");
    151     break;
    152   }
    153   now_str = GNUNET_STRINGS_absolute_time_to_string (now);
    154   fprintf (stdout,
    155            _ ("%24s: %-30s %4s (timeout in %6s)\n"),
    156            now_str,
    157            state_str,
    158            GNUNET_i2s (peer),
    159            GNUNET_STRINGS_relative_time_to_string (
    160              GNUNET_TIME_absolute_get_remaining (timeout),
    161              GNUNET_YES));
    162 }
    163 
    164 
    165 /**
    166  * Main function that will be run by the scheduler.
    167  *
    168  * @param cls closure
    169  * @param args remaining command-line arguments
    170  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
    171  * @param cfg configuration
    172  */
    173 static void
    174 run (void *cls,
    175      char *const *args,
    176      const char *cfgfile,
    177      const struct GNUNET_CONFIGURATION_Handle *cfg)
    178 {
    179   (void) cls;
    180   (void) cfgfile;
    181 
    182   if (NULL != args[0])
    183   {
    184     fprintf (stderr, _ ("Invalid command line argument `%s'\n"), args[0]);
    185     return;
    186   }
    187   if (! show_conns && ! monitor_connections)
    188   {
    189     fprintf (stderr, "%s", _ ("No argument given.\n"));
    190     ret = 1;
    191     GNUNET_SCHEDULER_shutdown ();
    192     return;
    193   }
    194   GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
    195   if (show_conns || monitor_connections)
    196   {
    197     if (monitor_connections)
    198     {
    199       fprintf (stdout,
    200                _ ("Monitoring connections. Press CTRL-C to quit.\n\n"));
    201     }
    202     mh = GNUNET_CORE_monitor_start (cfg, &monitor_cb, NULL);
    203     if (NULL == mh)
    204     {
    205       fprintf (stderr, "%s", _ ("Failed to connect to CORE service!\n"));
    206       ret = 1;
    207       GNUNET_SCHEDULER_shutdown ();
    208     }
    209     return;
    210   }
    211 }
    212 
    213 
    214 /**
    215  * The main function to obtain peer information from CORE.
    216  *
    217  * @param argc number of arguments from the command line
    218  * @param argv command line arguments
    219  * @return 0 ok, 1 on error
    220  */
    221 int
    222 main (int argc, char *const *argv)
    223 {
    224   int res;
    225   struct GNUNET_GETOPT_CommandLineOption options[] =
    226   { GNUNET_GETOPT_option_flag (
    227       'm',
    228       "monitor",
    229       gettext_noop (
    230         "provide information about all current connections (continuously)"),
    231       &monitor_connections),
    232     GNUNET_GETOPT_option_flag (
    233       's',
    234       "connection-status",
    235       gettext_noop (
    236         "Show current connections"
    237         ),
    238       &show_conns),
    239     GNUNET_GETOPT_OPTION_END };
    240 
    241   res = GNUNET_PROGRAM_run (GNUNET_OS_project_data_gnunet (),
    242                             argc,
    243                             argv,
    244                             "gnunet-core",
    245                             gettext_noop (
    246                               "Print information about connected peers."),
    247                             options,
    248                             &run,
    249                             NULL);
    250 
    251   if (GNUNET_OK == res)
    252     return ret;
    253   return 1;
    254 }
    255 
    256 
    257 /* end of gnunet-core.c */