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 */