GNUnet  0.11.x
transport_api_cmd_start_peer_v3.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2021 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 
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_testing_ng_lib.h"
32 #include "transport-testing-cmds.h"
33 
37 #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
38 
39 
40 static void
41 retrieve_hello (void *cls);
42 
43 
48 static void
49 hello_iter_cb (void *cb_cls,
50  const struct GNUNET_PEERSTORE_Record *record,
51  const char *emsg)
52 {
53  struct StartPeerState_v2 *sps = cb_cls;
54  if (NULL == record)
55  {
56  sps->pic = NULL;
58  return;
59  }
60  // Check record type et al?
61  sps->hello_size = record->value_size;
62  sps->hello = GNUNET_malloc (sps->hello_size);
63  memcpy (sps->hello, record->value, sps->hello_size);
64  sps->hello[sps->hello_size - 1] = '\0';
65 
67  sps->pic = NULL;
68  sps->finished = GNUNET_YES;
69 }
70 
71 
77 static void
78 retrieve_hello (void *cls)
79 {
80  struct StartPeerState_v2 *sps = cls;
81  sps->rh_task = NULL;
82  sps->pic = GNUNET_PEERSTORE_iterate (sps->ph,
83  "transport",
84  &sps->id,
87  sps);
88 
89 }
90 
91 
96 static int
97 start_peer_finish (void *cls,
99  void *cont_cls)
100 {
101  struct StartPeerState_v2 *sps = cls;
102 
103  if (GNUNET_YES == sps->finished)
104  {
105  cont (cont_cls);
106  }
107 
108  return sps->finished;
109 }
110 
111 
116 static void
117 notify_disconnect (void *cls,
118  const struct GNUNET_PeerIdentity *peer,
119  void *handler_cls)
120 {
121  struct StartPeerState_v2 *sps = cls;
122 
124  "Peer %s disconnected from peer %u (`%s')\n",
125  GNUNET_i2s (peer),
126  sps->no,
127  GNUNET_i2s (&sps->id));
128 
129 }
130 
131 
136 static void *
137 notify_connect (void *cls,
138  const struct GNUNET_PeerIdentity *peer,
139  struct GNUNET_MQ_Handle *mq)
140 {
141  struct StartPeerState_v2 *sps = cls;
143  struct GNUNET_HashCode hc;
144  struct GNUNET_CRYPTO_EddsaPublicKey public_key = peer->public_key;
145 
146  void *ret = NULL;
147 
148 
150  "Peer %s connected to peer %u (`%s')\n",
151  GNUNET_i2s (peer),
152  sps->no,
153  GNUNET_i2s (&sps->id));
154 
155  GNUNET_CRYPTO_hash (&public_key, sizeof(public_key), &hc);
156 
157 
158  memcpy (key,
159  &hc,
160  sizeof (*key));
162  key,
163  mq,
165 
166  GNUNET_free (key);
167  // TODO what does the handler function need?
168  return ret;
169 }
170 
171 
176 static void
177 start_peer_run (void *cls,
179 {
180  struct StartPeerState_v2 *sps = cls;
181  char *emsg = NULL;
182  struct GNUNET_PeerIdentity dummy;
183  const struct GNUNET_TESTING_Command *system_cmd;
184  struct GNUNET_TESTING_System *tl_system;
185  char *home;
186  char *transport_unix_path;
187  char *tcp_communicator_unix_path;
188  char *udp_communicator_unix_path;
189  char *bindto;
190 
192  {
194  "File not found: `%s'\n",
195  sps->cfgname);
197  return;
198  }
199 
200 
203  GNUNET_CONFIGURATION_load (sps->cfg, sps->cfgname));
204 
205  GNUNET_asprintf (&home,
206  "$GNUNET_TMP/test-transport/api-tcp-p%u",
207  sps->no);
208 
209  GNUNET_asprintf (&transport_unix_path,
210  "$GNUNET_RUNTIME_DIR/tng-p%u.sock",
211  sps->no);
212 
213  GNUNET_asprintf (&tcp_communicator_unix_path,
214  "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock",
215  sps->no);
216 
217  GNUNET_asprintf (&udp_communicator_unix_path,
218  "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock",
219  sps->no);
220 
221  GNUNET_asprintf (&bindto,
222  "%s:60002",
223  sps->node_ip);
224 
226  "node_ip %s\n",
227  bindto);
228 
229  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "PATHS", "GNUNET_TEST_HOME",
230  home);
231  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "transport", "UNIXPATH",
232  transport_unix_path);
233  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp",
234  "BINDTO",
235  bindto);
236  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-udp",
237  "BINDTO",
238  bindto);
239  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp",
240  "UNIXPATH",
241  tcp_communicator_unix_path);
242  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-udp",
243  "UNIXPATH",
244  udp_communicator_unix_path);
245 
247  sps->system_label);
249  &tl_system);
250 
251  sps->tl_system = tl_system;
252 
253  if (GNUNET_SYSERR ==
255  sps->cfg))
256  {
258  "Testing library failed to create unique configuration based on `%s'\n",
259  sps->cfgname);
262  return;
263  }
264 
266  sps->cfg,
267  sps->no,
268  NULL,
269  &emsg);
270  if (NULL == sps->peer)
271  {
273  "Testing library failed to create unique configuration based on `%s': `%s'\n",
274  sps->cfgname,
275  emsg);
276  GNUNET_free (emsg);
278  return;
279  }
280 
282  {
284  "Testing library failed to create unique configuration based on `%s'\n",
285  sps->cfgname);
286  GNUNET_free (emsg);
288  return;
289  }
290 
291  memset (&dummy,
292  '\0',
293  sizeof(dummy));
294 
296  &sps->id);
297 
298  if (0 == memcmp (&dummy,
299  &sps->id,
300  sizeof(struct GNUNET_PeerIdentity)))
301  {
303  "Testing library failed to obtain peer identity for peer %u\n",
304  sps->no);
305  GNUNET_free (emsg);
307  return;
308  }
310  "Peer %u configured with identity `%s'\n",
311  sps->no,
312  GNUNET_i2s_full (&sps->id));
313 
314  sps->th = GNUNET_TRANSPORT_core_connect (sps->cfg,
315  NULL,
316  sps->handlers,
317  sps,
320  if (NULL == sps->th)
321  {
323  "Failed to connect to transport service for peer `%s': `%s'\n",
324  sps->cfgname,
325  emsg);
326  GNUNET_free (emsg);
328  return;
329  }
330 
331  sps->ph = GNUNET_PEERSTORE_connect (sps->cfg);
332  if (NULL == sps->th)
333  {
335  "Failed to connect to peerstore service for peer `%s': `%s'\n",
336  sps->cfgname,
337  emsg);
338  GNUNET_free (emsg);
340  return;
341  }
342 
344  if (NULL == sps->ah)
345  {
347  "Failed to initialize the TRANSPORT application suggestion client handle for peer `%s': `%s'\n",
348  sps->cfgname,
349  emsg);
350  GNUNET_free (emsg);
352  return;
353  }
355 }
356 
357 
362 static void
364 {
365  struct StartPeerState_v2 *sps = cls;
366 
367  if (NULL != sps->handlers)
368  {
369  GNUNET_free (sps->handlers);
370  sps->handlers = NULL;
371  }
372  if (NULL != sps->cfg)
373  {
375  sps->cfg = NULL;
376  }
377  GNUNET_free (sps->hello);
379  GNUNET_free (sps);
380 }
381 
382 
387 static int
388 start_peer_traits (void *cls,
389  const void **ret,
390  const char *trait,
391  unsigned int index)
392 {
393  struct StartPeerState_v2 *sps = cls;
395  struct GNUNET_PeerIdentity *id = &sps->id;
396  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
397  sps->connected_peers_map;
398  char *hello = sps->hello;
399  size_t hello_size = sps->hello_size;
400 
401 
402  struct GNUNET_TESTING_Trait traits[] = {
403  {
404  .index = 0,
405  .trait_name = "application_handle",
406  .ptr = (const void *) ah,
407  },
408  {
409  .index = 1,
410  .trait_name = "peer_id",
411  .ptr = (const void *) id,
412  },
413  {
414  .index = 2,
415  .trait_name = "connected_peers_map",
416  .ptr = (const void *) connected_peers_map,
417  },
418  {
419  .index = 3,
420  .trait_name = "hello",
421  .ptr = (const void *) hello,
422  },
423  {
424  .index = 4,
425  .trait_name = "hello_size",
426  .ptr = (const void *) hello_size,
427  },
428  {
429  .index = 5,
430  .trait_name = "state",
431  .ptr = (const void *) sps,
432  },
434  };
435 
436  return GNUNET_TESTING_get_trait (traits,
437  ret,
438  trait,
439  index);
440 }
441 
442 
450 int
453  *cmd,
454  struct StartPeerState_v2 **sps)
455 {
456  return cmd->traits (cmd->cls,
457  (const void **) sps,
458  "state",
459  (unsigned int) 5);
460 }
461 
462 
470 int
473  *cmd,
474  size_t **hello_size)
475 {
476  return cmd->traits (cmd->cls,
477  (const void **) hello_size,
478  "hello_size",
479  (unsigned int) 4);
480 }
481 
482 
490 int
493  *cmd,
494  char **hello)
495 {
496  return cmd->traits (cmd->cls,
497  (const void **) hello,
498  "hello",
499  (unsigned int) 3);
500 }
501 
502 
510 int
513  *cmd,
514  struct
516  *
517  *
518  connected_peers_map)
519 {
520  return cmd->traits (cmd->cls,
521  (const void **) connected_peers_map,
522  "connected_peers_map",
523  (unsigned int) 2);
524 }
525 
526 
533 int
536  struct
538  **ah)
539 {
540  return cmd->traits (cmd->cls,
541  (const void **) ah,
542  "application_handle",
543  (unsigned int) 0);
544 }
545 
546 
553 int
556  struct GNUNET_PeerIdentity **id)
557 {
558  return cmd->traits (cmd->cls,
559  (const void **) id,
560  "peer_id",
561  (unsigned int) 1);
562 }
563 
564 
579  const char *system_label,
580  uint32_t no,
581  char *node_ip,
583  const char *cfgname)
584 {
585  struct StartPeerState_v2 *sps;
586  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
588  unsigned int i;
589 
590  sps = GNUNET_new (struct StartPeerState_v2);
591  sps->no = no;
592  sps->system_label = system_label;
593  sps->connected_peers_map = connected_peers_map;
594  sps->cfgname = cfgname;
595  sps->node_ip = node_ip;
596 
597  if (NULL != handlers)
598  {
599  for (i = 0; NULL != handlers[i].cb; i++)
600  ;
601  sps->handlers = GNUNET_new_array (i + 1,
602  struct GNUNET_MQ_MessageHandler);
603  GNUNET_memcpy (sps->handlers,
604  handlers,
605  i * sizeof(struct GNUNET_MQ_MessageHandler));
606  }
607 
608  struct GNUNET_TESTING_Command cmd = {
609  .cls = sps,
610  .label = label,
611  .run = &start_peer_run,
612  .cleanup = &start_peer_cleanup,
613  .traits = &start_peer_traits
614  };
615 
616  return cmd;
617 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static struct GNUNET_NAT_AUTO_AutoHandle * ah
Handle to ongoing autoconfiguration.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
struct GNUNET_TESTING_Trait GNUNET_TESTING_trait_end(void)
"end" trait.
int GNUNET_TESTING_get_trait_test_system(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_TESTING_System **test_system)
Function to get the trait with struct GNUNET_TESTING_System.
const struct GNUNET_TESTING_Command * GNUNET_TESTING_interpreter_lookup_command(struct GNUNET_TESTING_Interpreter *is, const char *label)
Lookup command by label.
enum GNUNET_GenericReturnValue GNUNET_TESTING_get_trait(const struct GNUNET_TESTING_Trait *traits, const void **ret, const char *trait, unsigned int index)
Extract a trait.
void GNUNET_TESTING_interpreter_fail(struct GNUNET_TESTING_Interpreter *is)
Current command failed, clean up and fail the test case.
Bandwidth allocation API for applications to interact with.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
void GNUNET_PEERSTORE_iterate_cancel(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
#define GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY
Key used for storing HELLOs in the peerstore.
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iterate(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Iterate over records matching supplied key information.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
struct GNUNET_TESTING_Peer * GNUNET_TESTING_peer_configure(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg, uint32_t key_number, struct GNUNET_PeerIdentity *id, char **emsg)
Configure a GNUnet peer.
Definition: testing.c:1160
int GNUNET_TESTING_peer_start(struct GNUNET_TESTING_Peer *peer)
Start the peer.
Definition: testing.c:1353
int GNUNET_TESTING_configuration_create(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new configuration using the given configuration as a template; ports and paths will be modif...
Definition: testing.c:1139
void GNUNET_TESTING_peer_get_identity(struct GNUNET_TESTING_Peer *peer, struct GNUNET_PeerIdentity *id)
Obtain the peer identity from a peer handle.
Definition: testing.c:1331
struct GNUNET_TRANSPORT_CoreHandle * GNUNET_TRANSPORT_core_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_PeerIdentity *self, const struct GNUNET_MQ_MessageHandler *handlers, void *cls, GNUNET_TRANSPORT_NotifyConnect nc, GNUNET_TRANSPORT_NotifyDisconnect nd)
Connect to the transport service.
Internal representation of the hash map.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
Single PEERSTORE record.
The identity of the host (wraps the signing key of the peer).
A 256-bit hashcode.
A command to be run by the interpreter.
enum GNUNET_GenericReturnValue(* traits)(void *cls, const void **ret, const char *trait, unsigned int index)
Extract information from a command that is useful for other commands.
const char * label
Label for the command.
void * cls
Closure for all commands with command-specific context information.
Global state of the interpreter, used by a command to access information about other commands.
Handle for a system on which GNUnet peers are executed; a system is used for reserving unique paths a...
Definition: testing.c:93
unsigned int index
Index number associated with the trait.
Handle to the TRANSPORT subsystem for application management.
unsigned int no
An unique number to identify the peer.
struct GNUNET_PeerIdentity id
Peer identity.
struct GNUNET_TESTING_Peer * peer
struct GNUNET_CONFIGURATION_Handle * cfg
Peer's configuration.
size_t hello_size
Hello size.
struct GNUNET_TRANSPORT_ApplicationHandle * ah
Application handle.
struct GNUNET_TESTING_System * tl_system
struct GNUNET_CONTAINER_MultiShortmap * connected_peers_map
char * node_ip
The ip of a node.
struct GNUNET_PEERSTORE_Handle * ph
Peer's PEERSTORE Handle.
struct GNUNET_PEERSTORE_IterateContext * pic
Peer's transport get hello handle to retrieve peer's HELLO message.
struct GNUNET_TRANSPORT_CoreHandle * th
Peer's transport service handle.
struct GNUNET_MQ_MessageHandler * handlers
Receive callback.
struct GNUNET_SCHEDULER_Task * rh_task
Hello get task.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
int GNUNET_TRANSPORT_get_trait_state_v3(const struct GNUNET_TESTING_Command *cmd, struct StartPeerState_v2 **sps)
Function to get the trait with the struct StartPeerState_v2.
int GNUNET_TRANSPORT_get_trait_application_handle_v3(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_TRANSPORT_ApplicationHandle **ah)
Function to get the trait with the transport application handle.
int GNUNET_TRANSPORT_get_trait_hello_size_v3(const struct GNUNET_TESTING_Command *cmd, size_t **hello_size)
Function to get the trait with the size of the hello.
static void start_peer_cleanup(void *cls)
The cleanup function of this cmd frees resources the cmd allocated.
static void hello_iter_cb(void *cb_cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback delivering the hello of this peer from peerstore.
int GNUNET_TRANSPORT_get_trait_connected_peers_map_v3(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_CONTAINER_MultiShortmap **connected_peers_map)
Function to get the trait with the map of connected peers.
int GNUNET_TRANSPORT_get_trait_hello_v3(const struct GNUNET_TESTING_Command *cmd, char **hello)
Function to get the trait with the hello.
static int start_peer_finish(void *cls, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
This function checks StartPeerState_v2::finished, which is set when the hello was retrieved.
static void retrieve_hello(void *cls)
Function to start the retrieval task to retrieve the hello of this peer from the peerstore.
static void * notify_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Connect callback for the connection to the core service.
static int start_peer_traits(void *cls, const void **ret, const char *trait, unsigned int index)
This function prepares an array with traits.
struct GNUNET_TESTING_Command GNUNET_TRANSPORT_cmd_start_peer_v3(const char *label, const char *system_label, uint32_t no, char *node_ip, struct GNUNET_MQ_MessageHandler *handlers, const char *cfgname)
Create command.
#define LOG(kind,...)
Generic logging shortcut.
int GNUNET_TRANSPORT_get_trait_peer_id_v3(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_PeerIdentity **id)
Function to get the trait with the peer id.
static void start_peer_run(void *cls, struct GNUNET_TESTING_Interpreter *is)
The run method of this cmd will start all services of a peer to test the transport service.
static void notify_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *handler_cls)
Disconnect callback for the connection to the core service.