GNUnet  0.19.5
transport_api_cmd_start_peer.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"
33 #include "transport-testing-cmds.h"
34 
38 #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
39 
40 
41 static void
42 retrieve_hello (void *cls);
43 
44 
49 static void
50 hello_iter_cb (void *cb_cls,
51  const struct GNUNET_PEERSTORE_Record *record,
52  const char *emsg)
53 {
54  struct StartPeerState *sps = cb_cls;
55  if (NULL == record)
56  {
57  sps->pic = NULL;
59  return;
60  }
61  // Check record type et al?
62  sps->hello_size = record->value_size;
63  sps->hello = GNUNET_malloc (sps->hello_size);
64  memcpy (sps->hello, record->value, sps->hello_size);
65  sps->hello[sps->hello_size - 1] = '\0';
66 
68  "Our hello %s\n",
69  sps->hello);
71  sps->pic = NULL;
73 }
74 
75 
81 static void
82 retrieve_hello (void *cls)
83 {
84  struct StartPeerState *sps = cls;
85  sps->rh_task = NULL;
86  sps->pic = GNUNET_PEERSTORE_iterate (sps->ph,
87  "transport",
88  &sps->id,
91  sps);
92 
93 }
94 
95 
100 static void
101 notify_disconnect (void *cls,
102  const struct GNUNET_PeerIdentity *peer,
103  void *handler_cls)
104 {
105  struct StartPeerState *sps = cls;
106 
108  "Peer %s disconnected from peer %u (`%s')\n",
109  GNUNET_i2s (peer),
110  sps->no,
111  GNUNET_i2s (&sps->id));
112 
113 }
114 
115 
120 static void *
121 notify_connect (void *cls,
122  const struct GNUNET_PeerIdentity *peer,
123  struct GNUNET_MQ_Handle *mq)
124 {
125  struct StartPeerState *sps = cls;
127  struct GNUNET_HashCode hc;
128  struct GNUNET_CRYPTO_EddsaPublicKey public_key = peer->public_key;
129 
130  void *ret = (struct GNUNET_PeerIdentity *) peer;
131 
133  "This Peer %s \n",
134  GNUNET_i2s (&sps->id));
135 
136 
137  GNUNET_CRYPTO_hash (&public_key, sizeof(public_key), &hc);
138 
140  "Peer %s connected to peer number %u with mq %p\n",
141  GNUNET_i2s (peer),
142  sps->no,
143  mq);
144 
145 
146  memcpy (key,
147  &hc,
148  sizeof (*key));
150  key,
151  mq,
153 
154  GNUNET_free (key);
155 
156  sps->notify_connect (sps->ac.is,
157  peer);
158 
159  return ret;
160 }
161 
162 
167 static void
168 start_peer_run (void *cls,
170 {
171  struct StartPeerState *sps = cls;
172  char *emsg = NULL;
173  struct GNUNET_PeerIdentity dummy;
174  const struct GNUNET_TESTING_Command *system_cmd;
175  const struct GNUNET_TESTING_System *tl_system;
176  char *home;
177  char *transport_unix_path;
178  char *tcp_communicator_unix_path;
179  char *udp_communicator_unix_path;
180  char *bindto;
181  char *bindto_udp;
182 
184  {
186  "File not found: `%s'\n",
187  sps->cfgname);
189  return;
190  }
191 
192 
195  GNUNET_CONFIGURATION_load (sps->cfg, sps->cfgname));
196 
197  GNUNET_asprintf (&home,
198  "$GNUNET_TMP/test-transport/api-tcp-p%u",
199  sps->no);
200 
201  GNUNET_asprintf (&transport_unix_path,
202  "$GNUNET_RUNTIME_DIR/tng-p%u.sock",
203  sps->no);
204 
205  GNUNET_asprintf (&tcp_communicator_unix_path,
206  "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock",
207  sps->no);
208 
209  GNUNET_asprintf (&udp_communicator_unix_path,
210  "$GNUNET_RUNTIME_DIR/tcp-comm-p%u.sock",
211  sps->no);
212 
213  GNUNET_asprintf (&bindto,
214  "%s:60002",
215  sps->node_ip);
216 
217  GNUNET_asprintf (&bindto_udp,
218  "2086");
219 
221  "node_ip %s\n",
222  bindto);
223 
225  "bind_udp %s\n",
226  GNUNET_YES == sps->broadcast ?
227  bindto_udp : 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  GNUNET_YES == sps->broadcast ?
239  bindto_udp : bindto);
240  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-tcp",
241  "UNIXPATH",
242  tcp_communicator_unix_path);
243  GNUNET_CONFIGURATION_set_value_string (sps->cfg, "communicator-udp",
244  "UNIXPATH",
245  udp_communicator_unix_path);
246 
247 
249  sps->system_label);
251  &tl_system);
252 
253  sps->tl_system = tl_system;
254 
256  "Creating testing library with key number %u\n",
257  sps->no);
258 
259  if (GNUNET_SYSERR ==
261  GNUNET_TESTING_System *) tl_system,
262  sps->cfg))
263  {
265  "Testing library failed to create unique configuration based on `%s'\n",
266  sps->cfgname);
269  return;
270  }
271 
272  sps->peer = GNUNET_TESTING_peer_configure ((struct
273  GNUNET_TESTING_System *) sps->
274  tl_system,
275  sps->cfg,
276  sps->no,
277  NULL,
278  &emsg);
279  if (NULL == sps->peer)
280  {
282  "Testing library failed to create unique configuration based on `%s': `%s' with key number %u\n",
283  sps->cfgname,
284  emsg,
285  sps->no);
286  GNUNET_free (emsg);
288  return;
289  }
290 
292  {
294  "Testing library failed to create unique configuration based on `%s'\n",
295  sps->cfgname);
296  GNUNET_free (emsg);
298  return;
299  }
300 
301  memset (&dummy,
302  '\0',
303  sizeof(dummy));
304 
306  &sps->id);
307 
308  if (0 == memcmp (&dummy,
309  &sps->id,
310  sizeof(struct GNUNET_PeerIdentity)))
311  {
313  "Testing library failed to obtain peer identity for peer %u\n",
314  sps->no);
315  GNUNET_free (emsg);
317  return;
318  }
320  "Peer %u configured with identity `%s'\n",
321  sps->no,
322  GNUNET_i2s_full (&sps->id));
323 
324  sps->th = GNUNET_TRANSPORT_core_connect (sps->cfg,
325  NULL,
326  sps->handlers,
327  sps,
330  if (NULL == sps->th)
331  {
333  "Failed to connect to transport service for peer `%s': `%s'\n",
334  sps->cfgname,
335  emsg);
336  GNUNET_free (emsg);
338  return;
339  }
340 
341  sps->ph = GNUNET_PEERSTORE_connect (sps->cfg);
342  if (NULL == sps->th)
343  {
345  "Failed to connect to peerstore service for peer `%s': `%s'\n",
346  sps->cfgname,
347  emsg);
348  GNUNET_free (emsg);
350  return;
351  }
352 
354  if (NULL == sps->ah)
355  {
357  "Failed to initialize the TRANSPORT application suggestion client handle for peer `%s': `%s'\n",
358  sps->cfgname,
359  emsg);
360  GNUNET_free (emsg);
362  return;
363  }
365  GNUNET_free (home);
366  GNUNET_free (transport_unix_path);
367  GNUNET_free (tcp_communicator_unix_path);
368  GNUNET_free (udp_communicator_unix_path);
369  GNUNET_free (bindto);
370  GNUNET_free (bindto_udp);
371 }
372 
373 
378 static void
380 {
381  struct StartPeerState *sps = cls;
382 
383  if (NULL != sps->handlers)
384  {
385  GNUNET_free (sps->handlers);
386  sps->handlers = NULL;
387  }
388  //TODO Investigate why this caused problems during shutdown.
389  /*if (NULL != sps->cfg)
390  {
391  GNUNET_CONFIGURATION_destroy (sps->cfg);
392  sps->cfg = NULL;
393  }*/
394  GNUNET_free (sps->cfgname);
395  GNUNET_free (sps->node_ip);
396  GNUNET_free (sps->system_label);
397  GNUNET_free (sps->hello);
399  GNUNET_free (sps);
400 }
401 
402 
407 static int
408 start_peer_traits (void *cls,
409  const void **ret,
410  const char *trait,
411  unsigned int index)
412 {
413  struct StartPeerState *sps = cls;
415  struct GNUNET_PeerIdentity *id = &sps->id;
416  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
417  sps->connected_peers_map;
418  char *hello = sps->hello;
419  size_t hello_size = sps->hello_size;
420 
421 
422  struct GNUNET_TESTING_Trait traits[] = {
424  GNUNET_TRANSPORT_make_trait_peer_id ((const void *) id),
426  void *)
427  connected_peers_map),
428  GNUNET_TRANSPORT_make_trait_hello ((const void *) hello),
429  GNUNET_TRANSPORT_make_trait_hello_size ((const void *) hello_size),
430  GNUNET_TRANSPORT_make_trait_state ((const void *) sps),
431  GNUNET_TRANSPORT_make_trait_broadcast ((const void *) &sps->broadcast),
433  };
434 
435  return GNUNET_TESTING_get_trait (traits,
436  ret,
437  trait,
438  index);
439 }
440 
441 
444  const char *system_label,
445  uint32_t no,
446  const char *node_ip,
448  const char *cfgname,
451  unsigned int broadcast)
452 {
453  struct StartPeerState *sps;
454  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map =
456  unsigned int i;
457 
458  sps = GNUNET_new (struct StartPeerState);
459  sps->no = no;
460  sps->system_label = GNUNET_strdup (system_label);
461  sps->connected_peers_map = connected_peers_map;
462  sps->cfgname = GNUNET_strdup (cfgname);
463  sps->node_ip = GNUNET_strdup (node_ip);
465  sps->broadcast = broadcast;
466 
467  if (NULL != handlers)
468  {
469  for (i = 0; NULL != handlers[i].cb; i++)
470  ;
471  sps->handlers = GNUNET_new_array (i + 1,
472  struct GNUNET_MQ_MessageHandler);
473  GNUNET_memcpy (sps->handlers,
474  handlers,
475  i * sizeof(struct GNUNET_MQ_MessageHandler));
476  }
477  return GNUNET_TESTING_command_new (sps,
478  label,
482  &sps->ac);
483 }
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.
struct GNUNET_TESTING_Interpreter * is
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.
API to the peerstore service.
enum GNUNET_GenericReturnValue GNUNET_TESTING_get_trait_test_system(const struct GNUNET_TESTING_Command *cmd, const struct GNUNET_TESTING_System **ret)
void GNUNET_TESTING_async_finish(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has finished.
struct GNUNET_TESTING_Command GNUNET_TESTING_command_new(void *cls, const char *label, GNUNET_TESTING_CommandRunRoutine run, GNUNET_TESTING_CommandCleanupRoutine cleanup, GNUNET_TESTING_CommandGetTraits traits, struct GNUNET_TESTING_AsyncContext *ac)
Create a new command.
struct GNUNET_TESTING_Trait GNUNET_TESTING_trait_end(void)
"end" trait.
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.
API of the transport service towards the CORE service (TNG version)
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
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.
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
enum GNUNET_GenericReturnValue 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.
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).
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
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_strdup(a)
Wrapper around GNUNET_xstrdup_.
#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:1299
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:1188
int GNUNET_TESTING_peer_start(struct GNUNET_TESTING_Peer *peer)
Start the peer.
Definition: testing.c:1381
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:1167
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:1359
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:87
Message handler for a specific message type.
Single PEERSTORE record.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
A 256-bit hashcode.
struct GNUNET_TESTING_Interpreter * is
Interpreter we are part of.
A command to be run by the interpreter.
char label[127+1]
Label for the command.
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:122
A struct GNUNET_TESTING_Trait can be used to exchange data between cmds.
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.
char * node_ip
The ip of a node.
enum GNUNET_GenericReturnValue broadcast
Flag indicating, if udp broadcast should be switched on.
struct GNUNET_MQ_MessageHandler * handlers
Receive callback.
struct GNUNET_CONFIGURATION_Handle * cfg
Peer's configuration.
struct GNUNET_PEERSTORE_Handle * ph
Peer's PEERSTORE Handle.
struct GNUNET_SCHEDULER_Task * rh_task
Hello get task.
struct GNUNET_PEERSTORE_IterateContext * pic
Peer's transport get hello handle to retrieve peer's HELLO message.
struct GNUNET_CONTAINER_MultiShortmap * connected_peers_map
A map with struct GNUNET_MQ_Handle values for each peer this peer is connected to.
struct GNUNET_TESTING_Peer * peer
struct GNUNET_TESTING_Peer returned by GNUNET_TESTING_peer_configure.
GNUNET_TRANSPORT_notify_connect_cb notify_connect
Callback which is called on neighbour connect events.
char * system_label
The label of the command which was started by calling GNUNET_TESTING_cmd_system_create.
size_t hello_size
Hello size.
struct GNUNET_TRANSPORT_CoreHandle * th
Peer's transport service handle.
char * cfgname
GNUnet configuration file used to start a peer.
struct GNUNET_TRANSPORT_ApplicationHandle * ah
Application handle.
const struct GNUNET_TESTING_System * tl_system
Test setup for this peer.
struct GNUNET_TESTING_AsyncContext ac
Context for our asynchronous completion.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_application_handle(const struct GNUNET_TRANSPORT_ApplicationHandle *value)
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_hello(const char *value)
void *(* GNUNET_TRANSPORT_notify_connect_cb)(struct GNUNET_TESTING_Interpreter *is, const struct GNUNET_PeerIdentity *peer)
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_peer_id(const struct GNUNET_PeerIdentity *value)
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_hello_size(const size_t *value)
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_broadcast(const enum GNUNET_GenericReturnValue *value)
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_state(const struct StartPeerState *value)
struct GNUNET_TESTING_Trait GNUNET_TRANSPORT_make_trait_connected_peers_map(const struct GNUNET_CONTAINER_MultiShortmap *value)
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.
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(const char *label, const char *system_label, uint32_t no, const char *node_ip, struct GNUNET_MQ_MessageHandler *handlers, const char *cfgname, GNUNET_TRANSPORT_notify_connect_cb notify_connect, unsigned int broadcast)
Create command.
#define LOG(kind,...)
Generic logging shortcut.
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.