GNUnet  0.11.x
transport_api_cmd_start_peer_v2.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  int node_number;
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  // TODO we need to store with a key identifying the netns node in the future. For now we have only one connecting node.
156  node_number = 1;
157  GNUNET_CRYPTO_hash (&node_number, sizeof(node_number), &hc);
158 
159 
160  memcpy (key,
161  &hc,
162  sizeof (*key));
164  key,
165  mq,
167 
168  GNUNET_free (key);
169  // TODO what does the handler function need?
170  return ret;
171 }
172 
173 
178 static void
179 start_peer_run (void *cls,
180  const struct GNUNET_TESTING_Command *cmd,
182 {
183  struct StartPeerState_v2 *sps = cls;
184  char *emsg = NULL;
185  struct GNUNET_PeerIdentity dummy;
186  const struct GNUNET_TESTING_Command *system_cmd;
187  struct GNUNET_TESTING_System *tl_system;
188  char *home;
189  char *transport_unix_path;
190  char *communicator_unix_path;
191  char *bindto;
192 
194  {
196  "File not found: `%s'\n",
197  sps->cfgname);
199  return;
200  }
201 
202 
205  GNUNET_CONFIGURATION_load (sps->cfg, sps->cfgname));
206 
207  GNUNET_asprintf (&home,
208  "$GNUNET_TMP/test-transport/api-tcp-p%u",
209  sps->no);
210 
211  GNUNET_asprintf (&transport_unix_path,
212  "$GNUNET_RUNTIME_DIR/tng-p%u.sock",
213  sps->no);
214 
215  GNUNET_asprintf (&communicator_unix_path,
216  "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock",
217  sps->no);
218 
219  GNUNET_asprintf (&bindto,
220  "%s:60002",
221  sps->node_ip);
222 
223 
224  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "PATHS", "GNUNET_TEST_HOME",
225  home);
226  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "transport", "UNIXPATH",
227  transport_unix_path);
228  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp",
229  "BINDTO",
230  bindto);
231  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp",
232  "UNIXPATH",
233  communicator_unix_path);
234 
237  &tl_system);
238 
239  sps->tl_system = tl_system;
240 
241  if (GNUNET_SYSERR ==
243  sps->cfg))
244  {
246  "Testing library failed to create unique configuration based on `%s'\n",
247  sps->cfgname);
250  return;
251  }
252 
254  sps->cfg,
255  sps->no,
256  NULL,
257  &emsg);
258  if (NULL == sps->peer)
259  {
261  "Testing library failed to create unique configuration based on `%s': `%s'\n",
262  sps->cfgname,
263  emsg);
264  GNUNET_free (emsg);
266  return;
267  }
268 
270  {
272  "Testing library failed to create unique configuration based on `%s'\n",
273  sps->cfgname);
274  GNUNET_free (emsg);
276  return;
277  }
278 
279  memset (&dummy,
280  '\0',
281  sizeof(dummy));
282 
284  &sps->id);
285 
286  if (0 == memcmp (&dummy,
287  &sps->id,
288  sizeof(struct GNUNET_PeerIdentity)))
289  {
291  "Testing library failed to obtain peer identity for peer %u\n",
292  sps->no);
293  GNUNET_free (emsg);
295  return;
296  }
298  "Peer %u configured with identity `%s'\n",
299  sps->no,
300  GNUNET_i2s_full (&sps->id));
301 
302  sps->th = GNUNET_TRANSPORT_core_connect (sps->cfg,
303  NULL,
304  sps->handlers,
305  sps,
308  if (NULL == sps->th)
309  {
311  "Failed to connect to transport service for peer `%s': `%s'\n",
312  sps->cfgname,
313  emsg);
314  GNUNET_free (emsg);
316  return;
317  }
318 
319  sps->ph = GNUNET_PEERSTORE_connect (sps->cfg);
320  if (NULL == sps->th)
321  {
323  "Failed to connect to peerstore service for peer `%s': `%s'\n",
324  sps->cfgname,
325  emsg);
326  GNUNET_free (emsg);
328  return;
329  }
330 
332  if (NULL == sps->ah)
333  {
335  "Failed to initialize the TRANSPORT application suggestion client handle for peer `%s': `%s'\n",
336  sps->cfgname,
337  emsg);
338  GNUNET_free (emsg);
340  return;
341  }
343 }
344 
345 
350 static void
352  const struct GNUNET_TESTING_Command *cmd)
353 {
354  struct StartPeerState_v2 *sps = cls;
355 
356  if (NULL != sps->handlers)
357  {
358  GNUNET_free (sps->handlers);
359  sps->handlers = NULL;
360  }
361  if (NULL != sps->cfg)
362  {
364  sps->cfg = NULL;
365  }
366  GNUNET_free (sps->hello);
368  GNUNET_free (sps);
369 }
370 
371 
376 static int
377 start_peer_traits (void *cls,
378  const void **ret,
379  const char *trait,
380  unsigned int index)
381 {
382  struct StartPeerState_v2 *sps = cls;
384  struct GNUNET_PeerIdentity *id = &sps->id;
385  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
386  sps->connected_peers_map;
387  char *hello = sps->hello;
388  size_t hello_size = sps->hello_size;
389 
390 
391  struct GNUNET_TESTING_Trait traits[] = {
392  {
393  .index = 0,
394  .trait_name = "application_handle",
395  .ptr = (const void *) ah,
396  },
397  {
398  .index = 1,
399  .trait_name = "peer_id",
400  .ptr = (const void *) id,
401  },
402  {
403  .index = 2,
404  .trait_name = "connected_peers_map",
405  .ptr = (const void *) connected_peers_map,
406  },
407  {
408  .index = 3,
409  .trait_name = "hello",
410  .ptr = (const void *) hello,
411  },
412  {
413  .index = 4,
414  .trait_name = "hello_size",
415  .ptr = (const void *) hello_size,
416  },
417  {
418  .index = 5,
419  .trait_name = "state",
420  .ptr = (const void *) sps,
421  },
423  };
424 
425  return GNUNET_TESTING_get_trait (traits,
426  ret,
427  trait,
428  index);
429 }
430 
431 
439 int
442  *cmd,
443  struct StartPeerState_v2 **sps)
444 {
445  return cmd->traits (cmd->cls,
446  (const void **) sps,
447  "state",
448  (unsigned int) 5);
449 }
450 
451 
459 int
462  *cmd,
463  size_t **hello_size)
464 {
465  return cmd->traits (cmd->cls,
466  (const void **) hello_size,
467  "hello_size",
468  (unsigned int) 4);
469 }
470 
471 
479 int
482  *cmd,
483  char **hello)
484 {
485  return cmd->traits (cmd->cls,
486  (const void **) hello,
487  "hello",
488  (unsigned int) 3);
489 }
490 
491 
499 int
502  *cmd,
503  struct
505  *
506  *
507  connected_peers_map)
508 {
509  return cmd->traits (cmd->cls,
510  (const void **) connected_peers_map,
511  "connected_peers_map",
512  (unsigned int) 2);
513 }
514 
515 
522 int
525  struct
527  **ah)
528 {
529  return cmd->traits (cmd->cls,
530  (const void **) ah,
531  "application_handle",
532  (unsigned int) 0);
533 }
534 
535 
542 int
545  struct GNUNET_PeerIdentity **id)
546 {
547  return cmd->traits (cmd->cls,
548  (const void **) id,
549  "peer_id",
550  (unsigned int) 1);
551 }
552 
553 
568  const char *system_label,
569  uint32_t no,
570  char *node_ip,
572  const char *cfgname)
573 {
574  struct StartPeerState_v2 *sps;
575  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
577  unsigned int i;
578 
579  sps = GNUNET_new (struct StartPeerState_v2);
580  sps->no = no;
581  sps->system_label = system_label;
582  sps->connected_peers_map = connected_peers_map;
583  sps->cfgname = cfgname;
584  sps->node_ip = node_ip;
585 
586  if (NULL != handlers)
587  {
588  for (i = 0; NULL != handlers[i].cb; i++)
589  ;
590  sps->handlers = GNUNET_new_array (i + 1,
591  struct GNUNET_MQ_MessageHandler);
592  GNUNET_memcpy (sps->handlers,
593  handlers,
594  i * sizeof(struct GNUNET_MQ_MessageHandler));
595  }
596 
597  struct GNUNET_TESTING_Command cmd = {
598  .cls = sps,
599  .label = label,
600  .run = &start_peer_run,
601  .finish = &start_peer_finish,
602  .cleanup = &start_peer_cleanup,
603  .traits = &start_peer_traits
604  };
605 
606  return cmd;
607 }
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 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
void GNUNET_TESTING_interpreter_fail()
Current command failed, clean up and fail the test case.
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(const char *label)
Lookup command by label.
int GNUNET_TESTING_get_trait(const struct GNUNET_TESTING_Trait *traits, const void **ret, const char *trait, unsigned int index)
Extract a trait.
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.
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.
int(* 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.
Definition: testing.h:35
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.
struct GNUNET_TESTING_Interpreter * is
int GNUNET_TRANSPORT_get_trait_peer_id_v2(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_PeerIdentity **id)
Function to get the trait with the peer id.
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_hello_v2(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 start_peer_cleanup(void *cls, const struct GNUNET_TESTING_Command *cmd)
The cleanup function of this cmd frees resources the cmd allocated.
int GNUNET_TRANSPORT_get_trait_state_v2(const struct GNUNET_TESTING_Command *cmd, struct StartPeerState_v2 **sps)
Function to get the trait with the struct StartPeerState_v2.
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.
int GNUNET_TRANSPORT_get_trait_application_handle_v2(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_connected_peers_map_v2(const struct GNUNET_TESTING_Command *cmd, struct GNUNET_CONTAINER_MultiShortmap **connected_peers_map)
Function to get the trait with the map of connected peers.
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_v2(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_hello_size_v2(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_run(void *cls, const struct GNUNET_TESTING_Command *cmd, 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.