GNUnet  0.11.x
transport_api_cmd_connecting_peers_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"
30 #include "gnunet_hello_lib.h"
32 #include "transport-testing-cmds.h"
33 
37 #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
38 
39 #define CONNECT_ADDRESS_TEMPLATE_TCP "tcp-192.168.15.%u:60002"
40 
41 #define CONNECT_ADDRESS_TEMPLATE_UDP "udp-192.168.15.%u:60002"
42 
43 #define ROUTER_CONNECT_ADDRESS_TEMPLATE_TCP "tcp-92.68.150.%u:60002"
44 
45 #define ROUTER_CONNECT_ADDRESS_TEMPLATE_UDP "udp-92.68.150.%u:60002"
46 
47 #define GLOBAL_CONNECT_ADDRESS_TEMPLATE_TCP "tcp-92.68.151.%u:60002"
48 
49 #define GLOBAL_CONNECT_ADDRESS_TEMPLATE_UDP "udp-92.68.151.%u:60002"
50 
51 #define PREFIX_TCP "tcp"
52 
53 #define PREFIX_UDP "udp"
54 
59 struct ConnectPeersState
60 {
65 
70 
71  // Label of the cmd which started the test system.
72  const char *create_label;
73 
78  uint32_t num;
79 
84  const char *start_peer_label;
85 
90  struct GNUNET_PeerIdentity *id;
91 
96 
101 
103 
107  unsigned int con_num;
108 };
109 
110 
111 static struct GNUNET_PeerIdentity *
112 get_pub_key (unsigned int num, struct GNUNET_TESTING_System *tl_system)
113 {
115  struct GNUNET_CRYPTO_EddsaPublicKey *pub_key = GNUNET_new (struct
117  struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key = GNUNET_new (struct
119 
120  priv_key = GNUNET_TESTING_hostkey_get (tl_system,
121  num,
122  peer);
123 
125  pub_key);
126  peer->public_key = *pub_key;
127  return peer;
128 }
129 
130 
131 static int
132 log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
133 {
134  struct GNUNET_TESTING_NetjailNode *node = value;
135  struct GNUNET_TESTING_NodeConnection *pos_connection;
136  struct GNUNET_TESTING_ADDRESS_PREFIX *pos_prefix;
137 
139  "plugin: %s space: %u node: %u global: %u\n",
140  node->plugin,
141  node->namespace_n,
142  node->node_n,
143  node->is_global);
144 
145  for (pos_connection = node->node_connections_head; NULL != pos_connection;
146  pos_connection = pos_connection->next)
147  {
148 
150  "namespace_n: %u node_n: %u node_type: %u\n",
151  pos_connection->namespace_n,
152  pos_connection->node_n,
153  pos_connection->node_type);
154 
155  for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
156  pos_prefix =
157  pos_prefix->next)
158  {
160  "prefix: %s\n",
161  pos_prefix->address_prefix);
162  }
163  }
164  return GNUNET_YES;
165 }
166 
167 
168 static int
169 log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
170 {
171  struct GNUNET_TESTING_NetjailNamespace *namespace = value;
172  struct GNUNET_TESTING_NetjailRouter *router = namespace->router;
173 
175  "router_tcp: %u router_udp: %u spaces: %u\n",
176  router->tcp_port,
177  router->udp_port,
178  namespace->namespace_n);
179  GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL);
180  return GNUNET_YES;
181 }
182 
183 
184 static int
186 {
188  "plugin: %s spaces: %u nodes: %u known: %u\n",
189  topology->plugin,
190  topology->namespaces_n,
191  topology->nodes_m,
192  topology->nodes_x);
193 
195  log_namespaces, NULL);
197  NULL);
198  return GNUNET_YES;
199 }
200 
201 
202 static struct GNUNET_TESTING_NodeConnection *
203 get_connections (unsigned int num, struct
205 {
206  struct GNUNET_TESTING_NetjailNode *node;
207  struct GNUNET_ShortHashCode *hkey;
208  struct GNUNET_HashCode hc;
209  struct GNUNET_TESTING_NetjailNamespace *namespace;
210  unsigned int namespace_n, node_m;
211 
212  log_topo (topology);
213 
214  hkey = GNUNET_new (struct GNUNET_ShortHashCode);
215  if (topology->nodes_x >= num)
216  {
217 
218  GNUNET_CRYPTO_hash (&num, sizeof(num), &hc);
219  memcpy (hkey,
220  &hc,
221  sizeof (*hkey));
222  node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
223  hkey);
224  }
225  else
226  {
227  namespace_n = (unsigned int) floor ((num - topology->nodes_x)
228  / topology->nodes_m);
230  "num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n",
231  num,
232  topology->nodes_x,
233  topology->nodes_m,
234  namespace_n);
235  hkey = GNUNET_new (struct GNUNET_ShortHashCode);
236  GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc);
237  memcpy (hkey,
238  &hc,
239  sizeof (*hkey));
240  namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
241  hkey);
242  node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1);
243  hkey = GNUNET_new (struct GNUNET_ShortHashCode);
244  GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc);
245  memcpy (hkey,
246  &hc,
247  sizeof (*hkey));
248  node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
249  hkey);
250  }
251 
252 
253  return node->node_connections_head;
254 }
255 
256 
257 static unsigned int
260 {
261  unsigned int n, m, num;
262 
263  n = node_connection->namespace_n;
264  m = node_connection->node_n;
265 
266  if (0 == n)
267  num = m;
268  else
269  num = (n - 1) * topology->nodes_m + m + topology->nodes_x;
270 
271  return num;
272 }
273 
274 
275 static char *
277  char *prefix)
278 {
279  struct GNUNET_TESTING_NetjailNode *node;
280  char *addr;
281 
282  node = connection->node;
283  if (connection->namespace_n == node->namespace_n)
284  {
285  if (0 == strcmp (PREFIX_TCP, prefix))
286  {
287 
288  GNUNET_asprintf (&addr,
290  connection->node_n);
291  }
292  else if (0 == strcmp (PREFIX_UDP, prefix))
293  {
294  GNUNET_asprintf (&addr,
296  connection->node_n);
297  }
298  else
299  {
300  GNUNET_break (0);
301  }
302  }
303  else
304  {
305  if (0 == strcmp (PREFIX_TCP, prefix))
306  {
307 
308  GNUNET_asprintf (&addr,
310  connection->namespace_n);
311  }
312  else if (0 == strcmp (PREFIX_UDP, prefix))
313  {
314  GNUNET_asprintf (&addr,
316  connection->namespace_n);
317  }
318  else
319  {
320  GNUNET_break (0);
321  }
322  }
323 
324  return addr;
325 }
326 
327 
332 static void
333 connect_peers_run (void *cls,
335 {
336  struct ConnectPeersState *cps = cls;
337  const struct GNUNET_TESTING_Command *system_cmd;
338  struct GNUNET_TESTING_System *tl_system;
339 
340 
341  const struct GNUNET_TESTING_Command *peer1_cmd;
343  struct GNUNET_PeerIdentity *peer;
344  char *addr;
345  enum GNUNET_NetworkType nt = 0;
346  uint32_t num;
347  struct GNUNET_TESTING_NodeConnection *pos_connection;
348  struct GNUNET_TESTING_ADDRESS_PREFIX *pos_prefix;
349  unsigned int con_num = 0;
350 
351  cps->is = is;
353  cps->start_peer_label);
355  &ah);
356 
358  cps->create_label);
360  &tl_system);
361 
362  cps->tl_system = tl_system;
363 
365 
366  for (pos_connection = cps->node_connections_head; NULL != pos_connection;
367  pos_connection = pos_connection->next)
368  {
369  con_num++;
370  num = calculate_num (pos_connection, cps->topology);
371  for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
372  pos_prefix =
373  pos_prefix->next)
374  {
375 
377  "prefix: %s\n",
378  pos_prefix->address_prefix);
379 
380  addr = get_address (pos_connection, pos_prefix->address_prefix);
381 
382  peer = get_pub_key (num, tl_system);
383 
385  "num: %u pub_key %s addr: %s\n",
386  num,
388  addr);
389 
390  cps->id = peer;
391 
393  peer,
394  nt,
395  addr);
396  }
397  }
398  cps->con_num = con_num;
399 }
400 
401 
407 static int
410  void *cont_cls)
411 {
412  struct ConnectPeersState *cps = cls;
413  const struct GNUNET_TESTING_Command *peer1_cmd;
414  struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map;
415  unsigned int ret;
417  struct GNUNET_HashCode hc;
418  struct GNUNET_PeerIdentity *peer;
419  unsigned int con_num = 0;
420  struct GNUNET_TESTING_NodeConnection *pos_connection;
421  unsigned int num;
422 
424  cps->start_peer_label);
426  &connected_peers_map);
427 
428  for (pos_connection = cps->node_connections_head; NULL != pos_connection;
429  pos_connection = pos_connection->next)
430  {
431  num = calculate_num (pos_connection, cps->topology);
432  peer = get_pub_key (num, cps->tl_system);
433  GNUNET_CRYPTO_hash (&(peer->public_key), sizeof(peer->public_key), &hc);
434  memcpy (key,
435  &hc,
436  sizeof (*key));
438  connected_peers_map,
439  key))
440  con_num++;
441  }
442 
443 
444  if (cps->con_num == con_num)
445  {
446  cont (cont_cls);
447  ret = GNUNET_YES;
448  }
449 
450  GNUNET_free (key);
451  return ret;
452 }
453 
454 
459 static void
461 {
462  struct ConnectPeersState *cps = cls;
463 
464  GNUNET_free (cps->id);
465  GNUNET_free (cps);
466 }
467 
468 
471  const char *start_peer_label,
472  const char *create_label,
473  uint32_t num,
475  topology)
476 {
477  struct ConnectPeersState *cps;
478 
479  cps = GNUNET_new (struct ConnectPeersState);
481  cps->num = num;
482  cps->create_label = create_label;
483  cps->topology = topology;
484 
485  {
486  struct GNUNET_TESTING_Command cmd = {
487  .cls = cps,
488  .label = label,
489  .run = &connect_peers_run,
490  .ac = &cps->ac,
491  .cleanup = &connect_peers_cleanup
492  };
493 
494  return cmd;
495  }
496 }
enum GNUNET_TESTBED_TopologyOption topology
The topology to generate.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static int prefix
If printing the value of PREFIX has been requested.
Definition: gnunet-config.c:53
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
static struct GNUNET_NAT_AUTO_AutoHandle * ah
Handle to ongoing autoconfiguration.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
@ GNUNET_YES
Definition: gnunet_common.h:97
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:251
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.
Bandwidth allocation API for applications to interact with.
void GNUNET_TRANSPORT_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:197
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
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
int GNUNET_CONTAINER_multishortmap_contains(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
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_free(ptr)
Wrapper around free.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:36
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_TESTING_hostkey_get(const struct GNUNET_TESTING_System *system, uint32_t key_number, struct GNUNET_PeerIdentity *id)
Testing includes a number of pre-created hostkeys for faster peer startup.
Definition: testing.c:704
Struct to store information needed in callbacks.
struct GNUNET_TESTING_AsyncContext ac
Context for our asynchronous completion.
struct GNUNET_TESTING_Interpreter * is
unsigned int con_num
Number of connections.
const char * start_peer_label
Label of the cmd to start a peer.
uint32_t num
Number globally identifying the node.
struct GNUNET_PeerIdentity * id
The peer identity of this peer.
struct GNUNET_TESTING_System * tl_system
The testing system of this node.
struct GNUNET_TESTING_NodeConnection * node_connections_head
Connections to other peers.
struct GNUNET_TESTING_NetjailTopology * topology
The topology of the test setup.
Internal representation of the hash map.
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
A 512-bit hashcode.
The identity of the host (wraps the signing key of the peer).
A 256-bit hashcode.
char * address_prefix
The address prefix.
struct GNUNET_TESTING_ADDRESS_PREFIX * next
Pointer to the next prefix in the DLL.
State each asynchronous command must have in its closure.
A command to be run by the interpreter.
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.
unsigned int namespace_n
The number of the namespace.
Node in the netjail topology.
unsigned int namespace_n
The number of the namespace this node is running in.
struct GNUNET_TESTING_NodeConnection * node_connections_head
Head of the DLL with the connections which shall be established to other nodes.
unsigned int is_global
Flag indicating if this node is a global known node.
char * plugin
Plugin for the test case to be run on this node.
unsigned int node_n
The number of this node in the namespace.
Router of a network namespace.
unsigned int tcp_port
Will tcp be forwarded?
unsigned int udp_port
Will udp be forwarded?
Toplogy of our netjail setup.
Connection to another node.
enum GNUNET_TESTING_NODE_TYPE node_type
The type of the node this connection points to.
struct GNUNET_TESTING_NodeConnection * next
Pointer to the next connection in the DLL.
struct GNUNET_TESTING_ADDRESS_PREFIX * address_prefixes_head
Head of the DLL with the address prefixes for the protocolls this node is reachable.
unsigned int node_n
The number of the node this connection points to.
struct GNUNET_TESTING_NetjailNode * node
The node which establish the connection.
unsigned int namespace_n
The number of the subnet of the node this connection points to.
Handle for a system on which GNUnet peers are executed; a system is used for reserving unique paths a...
Definition: testing.c:93
Handle to the TRANSPORT subsystem for application management.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
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.
#define CONNECT_ADDRESS_TEMPLATE_UDP
struct GNUNET_TESTING_Command GNUNET_TRANSPORT_cmd_connect_peers_v3(const char *label, const char *start_peer_label, const char *create_label, uint32_t num, struct GNUNET_TESTING_NetjailTopology *topology)
#define ROUTER_CONNECT_ADDRESS_TEMPLATE_TCP
static void connect_peers_run(void *cls, struct GNUNET_TESTING_Interpreter *is)
The run method of this cmd will connect to peers.
static unsigned int calculate_num(struct GNUNET_TESTING_NodeConnection *node_connection, struct GNUNET_TESTING_NetjailTopology *topology)
static int connect_peers_finish(void *cls, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
The finish function of this cmd will check if the peers we are trying to connect to are in the connec...
#define ROUTER_CONNECT_ADDRESS_TEMPLATE_UDP
static struct GNUNET_TESTING_NodeConnection * get_connections(unsigned int num, struct GNUNET_TESTING_NetjailTopology *topology)
static int log_topo(struct GNUNET_TESTING_NetjailTopology *topology)
#define LOG(kind,...)
Generic logging shortcut.
static char * get_address(struct GNUNET_TESTING_NodeConnection *connection, char *prefix)
static void connect_peers_cleanup(void *cls)
The cleanup function of this cmd frees resources the cmd allocated.
static struct GNUNET_PeerIdentity * get_pub_key(unsigned int num, struct GNUNET_TESTING_System *tl_system)
static int log_nodes(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
static int log_namespaces(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
#define CONNECT_ADDRESS_TEMPLATE_TCP