aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api_cmd_connecting_peers_v3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport_api_cmd_connecting_peers_v3.c')
-rw-r--r--src/transport/transport_api_cmd_connecting_peers_v3.c508
1 files changed, 508 insertions, 0 deletions
diff --git a/src/transport/transport_api_cmd_connecting_peers_v3.c b/src/transport/transport_api_cmd_connecting_peers_v3.c
new file mode 100644
index 000000000..e90781637
--- /dev/null
+++ b/src/transport/transport_api_cmd_connecting_peers_v3.c
@@ -0,0 +1,508 @@
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
21/**
22 * @file testing_api_cmd_start_peer.c
23 * @brief cmd to start a peer.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_transport_application_service.h"
30#include "gnunet_hello_lib.h"
31#include "gnunet_transport_service.h"
32#include "transport-testing-cmds.h"
33
34/**
35 * Generic logging shortcut
36 */
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
55/**
56 * Struct to store information needed in callbacks.
57 *
58 */
59struct ConnectPeersState
60{
61 /**
62 * The testing system of this node.
63 */
64 struct GNUNET_TESTING_System *tl_system;
65
66 // Label of the cmd which started the test system.
67 const char *create_label;
68
69 /**
70 * Number globally identifying the node.
71 *
72 */
73 uint32_t num;
74
75 /**
76 * Label of the cmd to start a peer.
77 *
78 */
79 const char *start_peer_label;
80
81 /**
82 * The peer identity of this peer.
83 *
84 */
85 struct GNUNET_PeerIdentity *id;
86
87 /**
88 * The topology of the test setup.
89 */
90 struct GNUNET_TESTING_NetjailTopology *topology;
91
92 /**
93 * Connections to other peers.
94 */
95 struct GNUNET_TESTING_NodeConnection *node_connections_head;
96
97 /**
98 * Number of connections.
99 */
100 unsigned int con_num;
101};
102
103
104static struct GNUNET_PeerIdentity *
105get_pub_key (unsigned int num, struct GNUNET_TESTING_System *tl_system)
106{
107 struct GNUNET_PeerIdentity *peer = GNUNET_new (struct GNUNET_PeerIdentity);
108 struct GNUNET_CRYPTO_EddsaPublicKey *pub_key = GNUNET_new (struct
109 GNUNET_CRYPTO_EddsaPublicKey);
110 struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key = GNUNET_new (struct
111 GNUNET_CRYPTO_EddsaPrivateKey);
112
113 priv_key = GNUNET_TESTING_hostkey_get (tl_system,
114 num,
115 peer);
116
117 GNUNET_CRYPTO_eddsa_key_get_public (priv_key,
118 pub_key);
119 peer->public_key = *pub_key;
120 return peer;
121}
122
123
124static int
125log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
126{
127 struct GNUNET_TESTING_NetjailNode *node = value;
128 struct GNUNET_TESTING_NodeConnection *pos_connection;
129 struct GNUNET_TESTING_ADDRESS_PREFIX *pos_prefix;
130
131 LOG (GNUNET_ERROR_TYPE_ERROR,
132 "plugin: %s space: %u node: %u global: %u\n",
133 node->plugin,
134 node->namespace_n,
135 node->node_n,
136 node->is_global);
137
138 for (pos_connection = node->node_connections_head; NULL != pos_connection;
139 pos_connection = pos_connection->next)
140 {
141
142 LOG (GNUNET_ERROR_TYPE_ERROR,
143 "namespace_n: %u node_n: %u node_type: %u\n",
144 pos_connection->namespace_n,
145 pos_connection->node_n,
146 pos_connection->node_type);
147
148 for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
149 pos_prefix =
150 pos_prefix->next)
151 {
152 LOG (GNUNET_ERROR_TYPE_ERROR,
153 "prefix: %s\n",
154 pos_prefix->address_prefix);
155 }
156 }
157 return GNUNET_YES;
158}
159
160
161static int
162log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
163{
164 struct GNUNET_TESTING_NetjailNamespace *namespace = value;
165 struct GNUNET_TESTING_NetjailRouter *router = namespace->router;
166
167 LOG (GNUNET_ERROR_TYPE_ERROR,
168 "router_tcp: %u router_udp: %u spaces: %u\n",
169 router->tcp_port,
170 router->udp_port,
171 namespace->namespace_n);
172 GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL);
173 return GNUNET_YES;
174}
175
176
177static int
178log_topo (struct GNUNET_TESTING_NetjailTopology *topology)
179{
180 LOG (GNUNET_ERROR_TYPE_ERROR,
181 "plugin: %s spaces: %u nodes: %u known: %u\n",
182 topology->plugin,
183 topology->namespaces_n,
184 topology->nodes_m,
185 topology->nodes_x);
186
187 GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces,
188 log_namespaces, NULL);
189 GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, &log_nodes,
190 NULL);
191 return GNUNET_YES;
192}
193
194
195static struct GNUNET_TESTING_NodeConnection *
196get_connections (unsigned int num, struct
197 GNUNET_TESTING_NetjailTopology *topology)
198{
199 struct GNUNET_TESTING_NetjailNode *node;
200 struct GNUNET_ShortHashCode *hkey;
201 struct GNUNET_HashCode hc;
202 struct GNUNET_TESTING_NetjailNamespace *namespace;
203 unsigned int namespace_n, node_m;
204
205 log_topo (topology);
206
207 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
208 if (topology->nodes_x >= num)
209 {
210
211 GNUNET_CRYPTO_hash (&num, sizeof(num), &hc);
212 memcpy (hkey,
213 &hc,
214 sizeof (*hkey));
215 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
216 hkey);
217 }
218 else
219 {
220 namespace_n = (unsigned int) floor ((num - topology->nodes_x)
221 / topology->nodes_m);
222 LOG (GNUNET_ERROR_TYPE_ERROR,
223 "num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n",
224 num,
225 topology->nodes_x,
226 topology->nodes_m,
227 namespace_n);
228 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
229 GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc);
230 memcpy (hkey,
231 &hc,
232 sizeof (*hkey));
233 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
234 hkey);
235 node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1);
236 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
237 GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc);
238 memcpy (hkey,
239 &hc,
240 sizeof (*hkey));
241 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
242 hkey);
243 }
244
245
246 return node->node_connections_head;
247}
248
249
250static unsigned int
251calculate_num (struct GNUNET_TESTING_NodeConnection *node_connection,
252 struct GNUNET_TESTING_NetjailTopology *topology)
253{
254 unsigned int n, m, num;
255
256 n = node_connection->namespace_n;
257 m = node_connection->node_n;
258
259 if (0 == n)
260 num = m;
261 else
262 num = (n - 1) * topology->nodes_m + m + topology->nodes_x;
263
264 return num;
265}
266
267static char *
268get_address (struct GNUNET_TESTING_NodeConnection *connection,
269 char *prefix)
270{
271 struct GNUNET_TESTING_NetjailNode *node;
272 char *addr;
273
274 node = connection->node;
275 if (connection->namespace_n == node->namespace_n)
276 {
277 if (0 == strcmp (PREFIX_TCP, prefix))
278 {
279
280 GNUNET_asprintf (&addr,
281 CONNECT_ADDRESS_TEMPLATE_TCP,
282 connection->node_n);
283 }
284 else if (0 == strcmp (PREFIX_UDP, prefix))
285 {
286 GNUNET_asprintf (&addr,
287 CONNECT_ADDRESS_TEMPLATE_UDP,
288 connection->node_n);
289 }
290 else
291 {
292 GNUNET_break (0);
293 }
294 }
295 else
296 {
297 if (0 == strcmp (PREFIX_TCP, prefix))
298 {
299
300 GNUNET_asprintf (&addr,
301 ROUTER_CONNECT_ADDRESS_TEMPLATE_TCP,
302 connection->namespace_n);
303 }
304 else if (0 == strcmp (PREFIX_UDP, prefix))
305 {
306 GNUNET_asprintf (&addr,
307 ROUTER_CONNECT_ADDRESS_TEMPLATE_UDP,
308 connection->namespace_n);
309 }
310 else
311 {
312 GNUNET_break (0);
313 }
314 }
315
316 return addr;
317}
318
319
320/**
321 * The run method of this cmd will connect to peers.
322 *
323 */
324static void
325connect_peers_run (void *cls,
326 const struct GNUNET_TESTING_Command *cmd,
327 struct GNUNET_TESTING_Interpreter *is)
328{
329 struct ConnectPeersState *cps = cls;
330 const struct GNUNET_TESTING_Command *system_cmd;
331 struct GNUNET_TESTING_System *tl_system;
332
333
334 const struct GNUNET_TESTING_Command *peer1_cmd;
335 struct GNUNET_TRANSPORT_ApplicationHandle *ah;
336 struct GNUNET_PeerIdentity *peer;
337 char *addr;
338 enum GNUNET_NetworkType nt = 0;
339 uint32_t num;
340 struct GNUNET_TESTING_NodeConnection *pos_connection;
341 struct GNUNET_TESTING_ADDRESS_PREFIX *pos_prefix;
342 unsigned int con_num = 0;
343
344 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->start_peer_label);
345 GNUNET_TRANSPORT_get_trait_application_handle_v2 (peer1_cmd,
346 &ah);
347
348 system_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->create_label);
349 GNUNET_TESTING_get_trait_test_system (system_cmd,
350 &tl_system);
351
352 cps->tl_system = tl_system;
353
354 cps->node_connections_head = get_connections (cps->num, cps->topology);
355
356 for (pos_connection = cps->node_connections_head; NULL != pos_connection;
357 pos_connection = pos_connection->next)
358 {
359 con_num++;
360 num = calculate_num (pos_connection, cps->topology);
361 for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
362 pos_prefix =
363 pos_prefix->next)
364 {
365
366 LOG (GNUNET_ERROR_TYPE_ERROR,
367 "prefix: %s\n",
368 pos_prefix->address_prefix);
369
370 addr = get_address (pos_connection, pos_prefix->address_prefix);
371
372 peer = get_pub_key (num, tl_system);
373
374 LOG (GNUNET_ERROR_TYPE_ERROR,
375 "num: %u pub_key %s addr: %s\n",
376 num,
377 GNUNET_CRYPTO_eddsa_public_key_to_string (&(peer->public_key)),
378 addr);
379
380 cps->id = peer;
381
382 GNUNET_TRANSPORT_application_validate (ah,
383 peer,
384 nt,
385 addr);
386 }
387 }
388 cps->con_num = con_num;
389}
390
391
392/**
393 * The finish function of this cmd will check if the peers we are trying to
394 * connect to are in the connected peers map of the start peer cmd for this peer.
395 *
396 */
397static int
398connect_peers_finish (void *cls,
399 GNUNET_SCHEDULER_TaskCallback cont,
400 void *cont_cls)
401{
402 struct ConnectPeersState *cps = cls;
403 const struct GNUNET_TESTING_Command *peer1_cmd;
404 struct GNUNET_CONTAINER_MultiShortmap *connected_peers_map;
405 unsigned int ret;
406 struct GNUNET_ShortHashCode *key = GNUNET_new (struct GNUNET_ShortHashCode);
407 struct GNUNET_HashCode hc;
408 struct GNUNET_PeerIdentity *peer;
409 unsigned int con_num = 0;
410 struct GNUNET_TESTING_NodeConnection *pos_connection;
411 unsigned int num;
412
413 peer1_cmd = GNUNET_TESTING_interpreter_lookup_command (cps->start_peer_label);
414 GNUNET_TRANSPORT_get_trait_connected_peers_map_v2 (peer1_cmd,
415 &connected_peers_map);
416
417 for (pos_connection = cps->node_connections_head; NULL != pos_connection;
418 pos_connection = pos_connection->next)
419 {
420 num = calculate_num (pos_connection, cps->topology);
421 peer = get_pub_key (num, cps->tl_system);
422 GNUNET_CRYPTO_hash (&(peer->public_key), sizeof(peer->public_key), &hc);
423 memcpy (key,
424 &hc,
425 sizeof (*key));
426 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
427 connected_peers_map,
428 key))
429 con_num++;
430 }
431
432
433
434 if (cps->con_num == con_num)
435 {
436 cont (cont_cls);
437 ret = GNUNET_YES;
438 }
439
440 GNUNET_free (key);
441 return ret;
442}
443
444
445/**
446 * Trait function of this cmd does nothing.
447 *
448 */
449static int
450connect_peers_traits (void *cls,
451 const void **ret,
452 const char *trait,
453 unsigned int index)
454{
455 return GNUNET_OK;
456}
457
458
459/**
460 * The cleanup function of this cmd frees resources the cmd allocated.
461 *
462 */
463static void
464connect_peers_cleanup (void *cls,
465 const struct GNUNET_TESTING_Command *cmd)
466{
467 struct ConnectPeersState *cps = cls;
468
469 GNUNET_free (cps->id);
470 GNUNET_free (cps);
471}
472
473
474/**
475 * Create command.
476 *
477 * @param label name for command.
478 * @param start_peer_label Label of the cmd to start a peer.
479 * @return command.
480 */
481struct GNUNET_TESTING_Command
482GNUNET_TRANSPORT_cmd_connect_peers_v3 (const char *label,
483 const char *start_peer_label,
484 const char *create_label,
485 uint32_t num,
486 struct GNUNET_TESTING_NetjailTopology *
487 topology)
488{
489 struct ConnectPeersState *cps;
490
491 cps = GNUNET_new (struct ConnectPeersState);
492 cps->start_peer_label = start_peer_label;
493 cps->num = num;
494 cps->create_label = create_label;
495 cps->topology = topology;
496
497
498 struct GNUNET_TESTING_Command cmd = {
499 .cls = cps,
500 .label = label,
501 .run = &connect_peers_run,
502 .finish = &connect_peers_finish,
503 .cleanup = &connect_peers_cleanup,
504 .traits = &connect_peers_traits
505 };
506
507 return cmd;
508}