aboutsummaryrefslogtreecommitdiff
path: root/src/lib/testing/testing_api_topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/testing/testing_api_topology.c')
-rw-r--r--src/lib/testing/testing_api_topology.c1355
1 files changed, 1355 insertions, 0 deletions
diff --git a/src/lib/testing/testing_api_topology.c b/src/lib/testing/testing_api_topology.c
new file mode 100644
index 000000000..22cfd85fe
--- /dev/null
+++ b/src/lib/testing/testing_api_topology.c
@@ -0,0 +1,1355 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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/testing.c
23 * @brief convenience API for writing testcases for GNUnet
24 * Many testcases need to start and stop a peer/service
25 * and this library is supposed to make that easier
26 * for TESTCASES. Normal programs should always
27 * use functions from gnunet_{util,arm}_lib.h. This API is
28 * ONLY for writing testcases (or internal use of the testbed).
29 * @author Christian Grothoff
30 *
31 */
32#include "platform.h"
33#include "gnunet_util_lib.h"
34#include "gnunet_testing_lib.h"
35#include "testing_api_topology.h"
36#include "testing_cmds.h"
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__)
39
40#define CONNECT_ADDRESS_TEMPLATE "%s-192.168.15.%u"
41
42#define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-92.68.150.%u"
43
44#define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-92.68.151.%u"
45
46#define PREFIX_TCP "tcp"
47
48#define PREFIX_UDP "udp"
49
50#define PREFIX_TCP_NATTED "tcp_natted"
51
52#define PREFIX_UDP_NATTED "udp_natted"
53
54
55/**
56 * Every line in the topology configuration starts with a string indicating which
57 * kind of information will be configured with this line. Configuration values following
58 * this string are seperated by special sequences of characters. An integer value seperated
59 * by ':' is returned by this function.
60 *
61 * @param line The line of configuration. Example: "a:42[:43]"
62 * @return An integer value (42)
63 */
64static unsigned int
65get_first_value (const char *line)
66{
67 const char *colon = strchr (line, ':');
68 char dummy;
69 int ret;
70
71 GNUNET_assert (NULL != colon);
72 ret = sscanf (colon + 1,
73 "%u%c",
74 &ret,
75 &dummy);
76 if (2 == ret)
77 GNUNET_assert (':' == dummy);
78 else
79 GNUNET_assert (1 == ret);
80 return ret;
81}
82
83
84/**
85 * Every line in the topology configuration starts with a string indicating
86 * which kind of information will be configured with this line. This string is
87 * returned by this function.
88 *
89 * @param line The line of configuration, e.g. "D:452"
90 * @return The leading string of this configuration line ("D")
91 */
92static char *
93get_key (const char *line)
94{
95 const char *colon = strchr (line, ':');
96
97 GNUNET_assert (NULL != colon);
98 return GNUNET_strndup (line,
99 colon - line);
100}
101
102
103/**
104 * Every line in the topology configuration starts with a string indicating which
105 * kind of information will be configured with this line. Configuration values following
106 * this string are seperated by special sequences of characters. A string value seperated
107 * by ':' is returned by this function.
108 *
109 * @param line The line of configuration ("FOO:BAR")
110 * @return A string value ("BAR").
111 */
112// FIXME: avoid strdup, return const?
113static char *
114get_first_string_value (const char *line)
115{
116 const char *colon = strchr (line, ':');
117
118 GNUNET_assert (NULL != colon);
119 return GNUNET_strdup (colon + 1);
120}
121
122
123/**
124 * Every line in the topology configuration starts with a string indicating
125 * which kind of information will be configured with this line. Configuration
126 * values following this string are seperated by special sequences of
127 * characters. A second integer value seperated by ':' from a first value is
128 * returned by this function.
129 *
130 * @param line The line of configuration (example: "P:1:3")
131 * @return An integer value (3)
132 */
133static unsigned int
134get_second_value (const char *line)
135{
136 const char *colon;
137 char dummy;
138 int ret;
139
140 colon = strchr (line, ':');
141 GNUNET_assert (NULL != colon);
142 colon = strchr (colon + 1, ':');
143 GNUNET_assert (NULL != colon);
144 GNUNET_assert (1 ==
145 sscanf (colon + 1,
146 "%u%c",
147 &ret,
148 &dummy));
149 return ret;
150}
151
152
153/**
154 * Every line in the topology configuration starts with a string indicating which
155 * kind of information will be configured with this line. Configuration values following
156 * this string are seperated by special sequences of characters. A value might be
157 * a key value pair.
158 * This function returns the value for a specific key in a configuration line.
159 *
160 * @param key The key of the key value pair.
161 * @return The value of the key value pair.
162 */
163static char *
164get_value (const char *key, const char *line)
165{
166 char copy[strlen (line) + 1];
167 size_t slen;
168 char *token;
169 char *token2;
170 char *temp;
171 char *rest = NULL;
172
173 slen = strlen (line) + 1;
174 memcpy (copy, line, slen);
175 temp = strstr (copy, key);
176 if (NULL == temp)
177 return NULL;
178 token = strtok_r (temp, ":", &rest);
179 if (NULL == token)
180 return NULL;
181 token = strtok_r (NULL, ":", &rest);
182 if (NULL == token)
183 return NULL;
184 token2 = strtok_r (token, "}", &rest);
185 if (NULL == token2)
186 return NULL;
187 return GNUNET_strdup (token2);
188}
189
190
191/**
192 * Every line in the topology configuration starts with a string indicating which
193 * kind of information will be configured with this line. Configuration values following
194 * this string are seperated by special sequences of characters. A value might be
195 * a key value pair. A special key is the 'connect' key which can appear more than once.
196 * The value is the information about a connection via some protocol to some other node.
197 * This function returns the struct GNUNET_TESTING_NodeConnection which holds the information
198 * of the connect value.
199 *
200 * @param value The value of the connect key value pair.
201 * @return The struct GNUNET_TESTING_NodeConnection.
202 */
203static struct GNUNET_TESTING_NodeConnection *
204get_connect_value (const char *line,
205 struct GNUNET_TESTING_NetjailNode *node)
206{
207 struct GNUNET_TESTING_NodeConnection *node_connection;
208 char *copy;
209 char *token;
210 char *token2;
211 unsigned int node_n;
212 unsigned int namespace_n;
213 char *rest = NULL;
214 char *rest2 = NULL;
215 struct GNUNET_TESTING_AddressPrefix *prefix;
216 unsigned int sscanf_ret;
217
218 node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection);
219 node_connection->node = node;
220
221 copy = GNUNET_strdup (line);
222 token = strtok_r (copy, ":", &rest);
223 if (0 == strcmp ("{K", token))
224 {
225 node_connection->node_type = GNUNET_TESTING_GLOBAL_NODE;
226 token = strtok_r (NULL, ":", &rest);
227 GNUNET_assert (1 == sscanf (token, "%u", &node_n));
228 LOG (GNUNET_ERROR_TYPE_DEBUG,
229 "node_n %u\n",
230 node_n);
231 node_connection->node_n = node_n;
232 node_connection->namespace_n = 0;
233 }
234 else if (0 == strcmp ("{P", token))
235 {
236 node_connection->node_type = GNUNET_TESTING_SUBNET_NODE;
237 token = strtok_r (NULL, ":", &rest);
238 errno = 0;
239 sscanf_ret = sscanf (token, "%u", &namespace_n);
240 if (errno != 0)
241 {
242 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf");
243 }
244 GNUNET_assert (0 < sscanf_ret);
245 node_connection->namespace_n = namespace_n;
246 token = strtok_r (NULL, ":", &rest);
247 errno = 0;
248 sscanf_ret = sscanf (token, "%u", &node_n);
249 if (errno != 0)
250 {
251 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf");
252 }
253 GNUNET_assert (0 < sscanf_ret);
254 node_connection->node_n = node_n;
255 LOG (GNUNET_ERROR_TYPE_DEBUG,
256 "node_n %u namespace_n %u node->node_n %u node->namespace_n %u\n",
257 node_n,
258 namespace_n,
259 node->node_n,
260 node->namespace_n);
261 }
262 else
263 {
264 GNUNET_break (0);
265 GNUNET_free (node_connection);
266 GNUNET_free (copy);
267 return NULL;
268 }
269
270 while (NULL != (token = strtok_r (NULL, ":", &rest)))
271 {
272 prefix = GNUNET_new (struct GNUNET_TESTING_AddressPrefix);
273 token2 = strtok_r (token, "}", &rest2);
274 if (NULL != token2)
275 prefix->address_prefix = GNUNET_strdup (token2);
276 else
277 prefix->address_prefix = GNUNET_strdup (token);
278
279 LOG (GNUNET_ERROR_TYPE_DEBUG,
280 "address_prefix %s\n",
281 prefix->address_prefix);
282
283 GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head,
284 node_connection->address_prefixes_tail,
285 prefix);
286 LOG (GNUNET_ERROR_TYPE_DEBUG,
287 "address_prefix %s\n",
288 prefix->address_prefix);
289 }
290
291 GNUNET_free (copy);
292 return node_connection;
293}
294
295
296/**
297 * Every line in the topology configuration starts with a string indicating which
298 * kind of information will be configured with this line. Configuration values following
299 * this string are seperated by special sequences of characters. A value might be
300 * a key value pair. A special key is the 'connect' key.
301 * The value is the information about a connections via some protocol to other nodes.
302 * Each connection itself is a key value pair separated by the character '|' and
303 * surrounded by the characters '{' and '}'.
304 * The struct GNUNET_TESTING_NodeConnection holds the information of each connection value.
305 * This function extracts the values of each connection into a DLL of
306 * struct GNUNET_TESTING_NodeConnection which will be added to a node.
307 *
308 * @param line The line of configuration.
309 * @param node The struct GNUNET_TESTING_NetjailNode to which the DLL of
310 * struct GNUNET_TESTING_NodeConnection will be added.
311 */
312static void
313node_connections (const char *line,
314 struct GNUNET_TESTING_NetjailNode *node)
315{
316 char *value, *value2;
317 char *temp;
318 char *copy;
319 char *rest = NULL;
320 char *rest2 = NULL;
321 struct GNUNET_TESTING_NodeConnection *node_connection;
322
323 temp = strstr (line, "connect");
324 if (NULL != temp)
325 {
326 copy = GNUNET_strdup (temp);
327 strtok_r (copy, ":", &rest);
328 value = strtok_r (rest, "|", &rest2);
329
330 while (NULL != value)
331 {
332 LOG (GNUNET_ERROR_TYPE_DEBUG,
333 "node_connections value %s\n",
334 value);
335 node_connection = get_connect_value (value, node);
336 if (NULL == node_connection)
337 {
338 LOG (GNUNET_ERROR_TYPE_WARNING,
339 "connect key was not expected in this configuration line: %s\n",
340 line);
341 break;
342 }
343 GNUNET_CONTAINER_DLL_insert (node->node_connections_head,
344 node->node_connections_tail,
345 node_connection);
346 value2 = strstr (value, "}}");
347 if (NULL != value2)
348 break;
349 value = strtok_r (NULL, "|", &rest2);
350
351 }
352 GNUNET_free (copy);
353 }
354}
355
356
357/**
358 * A helper function to log information about individual nodes.
359 *
360 * @param cls This is not used actually.
361 * @param id The key of this value in the map.
362 * @param value A struct GNUNET_TESTING_NetjailNode which holds information about a node.
363 * return GNUNET_YES to continue with iterating, GNUNET_NO otherwise.
364 */
365static int
366log_nodes (void *cls,
367 const struct GNUNET_ShortHashCode *id,
368 void *value)
369{
370 struct GNUNET_TESTING_NetjailNode *node = value;
371 struct GNUNET_TESTING_NodeConnection *pos_connection;
372 struct GNUNET_TESTING_AddressPrefix *pos_prefix;
373
374 LOG (GNUNET_ERROR_TYPE_DEBUG,
375 "plugin: %s space: %u node: %u global: %u\n",
376 node->plugin,
377 node->namespace_n,
378 node->node_n,
379 node->is_global);
380
381 for (pos_connection = node->node_connections_head; NULL != pos_connection;
382 pos_connection = pos_connection->next)
383 {
384
385 LOG (GNUNET_ERROR_TYPE_DEBUG,
386 "namespace_n: %u node_n: %u node_type: %u\n",
387 pos_connection->namespace_n,
388 pos_connection->node_n,
389 pos_connection->node_type);
390
391 for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
392 pos_prefix =
393 pos_prefix->next)
394 {
395 LOG (GNUNET_ERROR_TYPE_DEBUG,
396 "prefix: %s\n",
397 pos_prefix->address_prefix);
398 }
399 }
400 return GNUNET_YES;
401}
402
403
404/**
405 * Helper function to log information about namespaces.
406 *
407 * @param cls This is not used actually.
408 * @param id The key of this value in the map.
409 * @param value A struct GNUNET_TESTING_NetjailNamespace which holds information about a subnet.
410 * return GNUNET_YES to continue with iterating, GNUNET_NO otherwise.
411 */
412static int
413log_namespaces (void *cls,
414 const struct GNUNET_ShortHashCode *id,
415 void *value)
416{
417 struct GNUNET_TESTING_NetjailNamespace *namespace = value;
418
419 GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes,
420 &log_nodes,
421 NULL);
422 return GNUNET_YES;
423}
424
425
426/**
427 * Helper function to log the configuration in case of a problem with configuration.
428 *
429 * @param topology The struct GNUNET_TESTING_NetjailTopology holding the configuration information.
430 */
431static int
432log_topo (const struct GNUNET_TESTING_NetjailTopology *topology)
433{
434 LOG (GNUNET_ERROR_TYPE_DEBUG,
435 "plugin: %s spaces: %u nodes: %u known: %u\n",
436 topology->plugin,
437 topology->namespaces_n,
438 topology->nodes_m,
439 topology->nodes_x);
440
441 GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces,
442 log_namespaces, NULL);
443 GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, &log_nodes,
444 NULL);
445 return GNUNET_YES;
446}
447
448
449/**
450 * This function extracts information about a specific node from the topology.
451 *
452 * @param num The global index number of the node.
453 * @param[out] node_ex A struct GNUNET_TESTING_NetjailNode with information about the node.
454 * @param[out] namespace_ex A struct GNUNET_TESTING_NetjailNamespace with information about the namespace
455 the node is in or NULL, if the node is a global node.
456 * @param[out] node_connections_ex A struct GNUNET_TESTING_NodeConnection with information about the connection
457 of this node to other nodes.
458*/
459static void
460get_node_info (unsigned int num,
461 const struct GNUNET_TESTING_NetjailTopology *topology,
462 struct GNUNET_TESTING_NetjailNode **node_ex,
463 struct GNUNET_TESTING_NetjailNamespace **namespace_ex,
464 struct GNUNET_TESTING_NodeConnection **node_connections_ex)
465{
466 struct GNUNET_ShortHashCode hkey;
467 struct GNUNET_HashCode hc;
468 unsigned int namespace_n;
469 unsigned int node_m;
470 struct GNUNET_TESTING_NetjailNode *node;
471 struct GNUNET_TESTING_NetjailNamespace *namespace;
472 struct GNUNET_TESTING_NodeConnection *node_connections = NULL;
473
474 log_topo (topology);
475 LOG (GNUNET_ERROR_TYPE_DEBUG,
476 "num: %u \n",
477 num);
478 if (topology->nodes_x >= num)
479 {
480
481 GNUNET_CRYPTO_hash (&num, sizeof(num), &hc);
482 memcpy (&hkey,
483 &hc,
484 sizeof (hkey));
485 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
486 &hkey);
487 if (NULL != node)
488 {
489 *node_ex = node;
490 *node_connections_ex = node->node_connections_head;
491 }
492 }
493 else
494 {
495 namespace_n = (unsigned int) ceil ((double) (num - topology->nodes_x)
496 / topology->nodes_m);
497 LOG (GNUNET_ERROR_TYPE_DEBUG,
498 "ceil num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n",
499 num,
500 topology->nodes_x,
501 topology->nodes_m,
502 namespace_n);
503 GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc);
504 memcpy (&hkey,
505 &hc,
506 sizeof (hkey));
507 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
508 &hkey);
509 if (NULL != namespace)
510 {
511 node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1);
512 GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc);
513 memcpy (&hkey,
514 &hc,
515 sizeof (hkey));
516 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
517 &hkey);
518 if (NULL != node)
519 {
520 LOG (GNUNET_ERROR_TYPE_DEBUG,
521 "node additional_connects: %u %p\n",
522 node->additional_connects,
523 node);
524 node_connections = node->node_connections_head;
525 }
526 *node_ex = node;
527 *namespace_ex = namespace;
528 *node_connections_ex = node_connections;
529 }
530 }
531}
532
533
534/**
535 * Get a node from the topology.
536 *
537 * @param num The specific node we want the connections for.
538 * @param topology The topology we get the connections from.
539 * @return The connections of the node.
540 */
541struct GNUNET_TESTING_NetjailNode *
542GNUNET_TESTING_get_node (unsigned int num,
543 struct GNUNET_TESTING_NetjailTopology *topology)
544{
545 struct GNUNET_TESTING_NetjailNode *node;
546 struct GNUNET_TESTING_NetjailNamespace *namespace;
547 struct GNUNET_TESTING_NodeConnection *node_connections;
548
549 get_node_info (num, topology, &node, &namespace, &node_connections);
550
551 return node;
552
553}
554
555
556/**
557 * Get the connections to other nodes for a specific node.
558 *
559 * @param num The specific node we want the connections for.
560 * @param topology The topology we get the connections from.
561 * @return The connections of the node.
562 */
563struct GNUNET_TESTING_NodeConnection *
564GNUNET_TESTING_get_connections (unsigned int num,
565 const struct
566 GNUNET_TESTING_NetjailTopology *topology)
567{
568 struct GNUNET_TESTING_NetjailNode *node;
569 struct GNUNET_TESTING_NetjailNamespace *namespace;
570 struct GNUNET_TESTING_NodeConnection *node_connections;
571
572 LOG (GNUNET_ERROR_TYPE_DEBUG,
573 "get_connections\n");
574
575 get_node_info (num, topology, &node, &namespace, &node_connections);
576
577 return node_connections;
578}
579
580
581int
582free_nodes_cb (void *cls,
583 const struct GNUNET_ShortHashCode *key,
584 void *value)
585{
586 (void) cls;
587 struct GNUNET_TESTING_NetjailNode *node = value;
588 struct GNUNET_TESTING_NodeConnection *pos_connection;
589 struct GNUNET_TESTING_AddressPrefix *pos_prefix;
590
591 while (NULL != (pos_connection = node->node_connections_head))
592 {
593 while (NULL != (pos_prefix = pos_connection->address_prefixes_head))
594 {
595 GNUNET_CONTAINER_DLL_remove (pos_connection->address_prefixes_head,
596 pos_connection->address_prefixes_tail,
597 pos_prefix);
598 GNUNET_free (pos_prefix->address_prefix);
599 GNUNET_free (pos_prefix);
600 }
601 GNUNET_CONTAINER_DLL_remove (node->node_connections_head,
602 node->node_connections_tail,
603 pos_connection);
604 GNUNET_free (pos_connection);
605 }
606
607 GNUNET_free (node->plugin);
608 GNUNET_free (node);
609 return GNUNET_OK;
610}
611
612
613int
614free_namespaces_cb (void *cls,
615 const struct GNUNET_ShortHashCode *key,
616 void *value)
617{
618 (void) cls;
619 struct GNUNET_TESTING_NetjailNamespace *namespace = value;
620
621 GNUNET_free (namespace->router);
622 GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, free_nodes_cb,
623 namespace->nodes);
624 return GNUNET_OK;
625
626}
627
628
629static int
630free_value_cb (void *cls,
631 const struct GNUNET_ShortHashCode *key,
632 void *value)
633{
634 (void) cls;
635
636 GNUNET_free (value);
637
638 return GNUNET_OK;
639}
640
641
642static int
643free_subnets_cb (void *cls,
644 const struct GNUNET_ShortHashCode *key,
645 void *value)
646{
647 (void) cls;
648 struct GNUNET_TESTING_NetjailSubnet *subnet = value;
649
650 GNUNET_CONTAINER_multishortmap_iterate (subnet->peers,
651 &free_value_cb,
652 NULL);
653
654 GNUNET_free (subnet);
655
656 return GNUNET_OK;
657}
658
659
660static int
661free_carriers_cb (void *cls,
662 const struct GNUNET_ShortHashCode *key,
663 void *value)
664{
665 (void) cls;
666 struct GNUNET_TESTING_NetjailCarrier *carrier = value;
667
668 GNUNET_CONTAINER_multishortmap_iterate (carrier->peers,
669 &free_value_cb,
670 NULL);
671 GNUNET_CONTAINER_multishortmap_iterate (carrier->subnets,
672 &free_subnets_cb,
673 NULL);
674
675 GNUNET_free (carrier);
676
677 return GNUNET_OK;
678}
679
680
681/**
682 * Deallocate memory of the struct GNUNET_TESTING_NetjailTopology.
683 *
684 * @param topology The GNUNET_TESTING_NetjailTopology to be deallocated.
685 */
686void
687GNUNET_TESTING_free_topology (struct GNUNET_TESTING_NetjailTopology *topology)
688{
689 GNUNET_CONTAINER_multishortmap_iterate (topology->backbone_peers,
690 &free_value_cb,
691 NULL);
692 GNUNET_CONTAINER_multishortmap_iterate (topology->carriers,
693 &free_carriers_cb,
694 NULL);
695 GNUNET_free (topology->plugin);
696 GNUNET_free (topology);
697}
698
699
700/**
701 * Deallocate memory of the struct GNUNET_TESTING_NetjailTopology.
702 *
703 * @param topology The GNUNET_TESTING_NetjailTopology to be deallocated.
704 *
705void
706GNUNET_TESTING_free_topology (struct GNUNET_TESTING_NetjailTopology *topology)
707{
708 GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces,
709 &free_namespaces_cb,
710 NULL);
711 GNUNET_CONTAINER_multishortmap_destroy (topology->map_namespaces);
712 GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals,
713 &free_nodes_cb,
714 NULL);
715 GNUNET_CONTAINER_multishortmap_destroy (topology->map_globals);
716 GNUNET_free (topology->plugin);
717 GNUNET_free (topology);
718 }*/
719
720
721unsigned int
722GNUNET_TESTING_calculate_num (
723 struct GNUNET_TESTING_NodeConnection *node_connection,
724 struct GNUNET_TESTING_NetjailTopology *topology)
725{
726 unsigned int n, m, num;
727
728 n = node_connection->namespace_n;
729 m = node_connection->node_n;
730
731 if (0 == n)
732 num = m;
733 else
734 num = (n - 1) * topology->nodes_m + m + topology->nodes_x;
735
736 return num;
737}
738
739
740/**
741 * Get the address for a specific communicator from a connection.
742 *
743 * @param connection The connection we like to have the address from.
744 * @param prefix The communicator protocol prefix.
745 * @return The address of the communicator.
746 */
747char *
748GNUNET_TESTING_get_address (struct GNUNET_TESTING_NodeConnection *connection,
749 const char *prefix)
750{
751 struct GNUNET_TESTING_NetjailNode *node;
752 char *addr;
753 char *template;
754 unsigned int node_n;
755
756 LOG (GNUNET_ERROR_TYPE_DEBUG,
757 "get address prefix: %s node_n: %u\n",
758 prefix,
759 connection->node_n);
760
761 node = connection->node;
762 if (connection->namespace_n == node->namespace_n)
763 {
764 template = CONNECT_ADDRESS_TEMPLATE;
765 node_n = connection->node_n;
766 }
767 else if (0 == connection->namespace_n)
768 {
769 template = KNOWN_CONNECT_ADDRESS_TEMPLATE;
770 node_n = connection->node_n;
771 }
772 else if (1 == connection->node_n)
773 {
774 template = ROUTER_CONNECT_ADDRESS_TEMPLATE;
775 node_n = connection->namespace_n;
776 }
777 else
778 {
779 return NULL;
780 }
781
782 if (0 == strcmp (PREFIX_TCP, prefix) ||
783 0 == strcmp (PREFIX_UDP, prefix) ||
784 0 == strcmp (PREFIX_UDP_NATTED, prefix) ||
785 0 == strcmp (PREFIX_TCP_NATTED, prefix))
786 {
787 GNUNET_asprintf (&addr,
788 template,
789 prefix,
790 node_n);
791 }
792 else
793 {
794 GNUNET_assert (0);
795 }
796
797 return addr;
798}
799
800
801/**
802 * Get the number of unintentional additional connections the node waits for.
803 *
804 * @param num The specific node we want the additional connects for.
805 * @return The number of additional connects
806 */
807unsigned int
808GNUNET_TESTING_get_additional_connects (unsigned int num,
809 struct GNUNET_TESTING_NetjailTopology *
810 topology)
811{
812 struct GNUNET_TESTING_NetjailNode *node;
813 struct GNUNET_TESTING_NetjailNamespace *namespace;
814 struct GNUNET_TESTING_NodeConnection *node_connections;
815
816 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "get_additional_connects\n");
818
819 get_node_info (num, topology, &node, &namespace, &node_connections);
820
821 if (NULL == node)
822 {
823 LOG (GNUNET_ERROR_TYPE_WARNING,
824 "No info found for node %d\n", num);
825 return 0;
826 }
827 LOG (GNUNET_ERROR_TYPE_DEBUG,
828 "node additional_connects for node %p\n",
829 node);
830 LOG (GNUNET_ERROR_TYPE_DEBUG,
831 "node additional_connects: %u\n",
832 node->additional_connects);
833
834 return node->additional_connects;
835}
836
837char *
838GNUNET_TESTING_get_plugin_from_topo (
839 struct GNUNET_TESTING_NetjailTopology *njt,
840 const char *my_node_id)
841{
842 return njt->plugin;
843}
844
845
846static void
847create_subnet_peers (struct GNUNET_CONFIGURATION_Handle *cfg,
848 struct GNUNET_TESTING_NetjailTopology *topology,
849 struct GNUNET_TESTING_NetjailSubnet *subnet)
850{
851 struct GNUNET_HashCode hc;
852 subnet->peers = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
853
854 for (int i = 1; i < subnet->number_peers; i++)
855 {
856 struct GNUNET_ShortHashCode hkey;
857 struct GNUNET_TESTING_NetjailSubnetPeer *subnet_peer = GNUNET_new (struct GNUNET_TESTING_NetjailSubnetPeer);
858
859 topology->total++;
860 GNUNET_CRYPTO_hash (&topology->total, sizeof(topology->total), &hc);
861 memcpy (&hkey,
862 &hc,
863 sizeof (hkey));
864 GNUNET_CONTAINER_multishortmap_put (subnet->peers,
865 &hkey,
866 subnet_peer,
867 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
868 }
869}
870
871
872static void
873create_subnets (struct GNUNET_CONFIGURATION_Handle *cfg,
874 struct GNUNET_TESTING_NetjailTopology *topology,
875 struct GNUNET_TESTING_NetjailCarrier *carrier)
876{
877 struct GNUNET_HashCode hc;
878 carrier->subnets = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
879
880 for (int i = 1; i < carrier->number_subnets; i++)
881 {
882 struct GNUNET_ShortHashCode hkey;
883 struct GNUNET_TESTING_NetjailSubnet *subnet = GNUNET_new (struct GNUNET_TESTING_NetjailSubnet);
884 char *section;
885
886 topology->total++;
887 subnet->number = topology->total;
888 subnet->index = i;
889 GNUNET_CRYPTO_hash (&topology->total, sizeof(topology->total), &hc);
890 memcpy (&hkey,
891 &hc,
892 sizeof (hkey));
893 GNUNET_CONTAINER_multishortmap_put (carrier->subnets,
894 &hkey,
895 subnet,
896 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
897 GNUNET_asprintf (&section, "CARRIER-%u-SUBNET-%u", carrier->index, i);
898 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
899 section,
900 "SUBNET_PEERS",
901 (unsigned long long *) &subnet->number_peers))
902 {
903 subnet->number_peers = topology->default_subnet_peers;
904 }
905
906 create_subnet_peers (cfg, topology, subnet);
907
908 GNUNET_free (section);
909 }
910}
911
912
913static void
914create_peers (struct GNUNET_CONFIGURATION_Handle *cfg,
915 struct GNUNET_TESTING_NetjailTopology *topology,
916 struct GNUNET_TESTING_NetjailCarrier *carrier)
917{
918 struct GNUNET_HashCode hc;
919 carrier->peers = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
920
921 for (int i = 1; i < carrier->number_peers; i++)
922 {
923 struct GNUNET_ShortHashCode hkey;
924 struct GNUNET_TESTING_NetjailCarrierPeer *peer = GNUNET_new (struct GNUNET_TESTING_NetjailCarrierPeer);
925
926 topology->total++;
927 peer->number = topology->total;
928 GNUNET_CRYPTO_hash (&topology->total, sizeof(topology->total), &hc);
929 memcpy (&hkey,
930 &hc,
931 sizeof (hkey));
932 GNUNET_CONTAINER_multishortmap_put (carrier->peers,
933 &hkey,
934 peer,
935 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
936 //GNUNET_asprintf (&section, "CARRIER-%u-PEER-%u", carrier->index, i);
937 }
938}
939
940
941struct GNUNET_TESTING_NetjailTopology *
942GNUNET_TESTING_get_topo_from_string_ (const char *input)
943{
944 struct GNUNET_CONFIGURATION_Handle *cfg;
945 struct GNUNET_TESTING_NetjailTopology *topology = GNUNET_new (struct GNUNET_TESTING_NetjailTopology);
946 topology->backbone_peers = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
947 topology->carriers = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
948 struct GNUNET_HashCode hc;
949
950 cfg = GNUNET_CONFIGURATION_create ();
951 GNUNET_assert (NULL != topology->carriers);
952
953 if (GNUNET_OK !=
954 GNUNET_CONFIGURATION_deserialize (cfg,
955 input,
956 strlen (input),
957 NULL))
958 {
959 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
960 _ ("Failed to parse configuration.\n"));
961 GNUNET_CONFIGURATION_destroy (cfg);
962 return NULL;
963 }
964 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
965 "DEFAULTS",
966 "SUBNETS",
967 &(topology->default_subnets)))
968 {
969 LOG (GNUNET_ERROR_TYPE_ERROR,
970 "Missing default SUBNETS!\n");
971 return NULL;
972 }
973 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
974 "DEFAULTS",
975 "TESTBED_PLUGIN",
976 &topology->plugin))
977 {
978 LOG (GNUNET_ERROR_TYPE_ERROR,
979 "Missing default TESTBED_PLUGIN!\n");
980 return NULL;
981 }
982 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
983 "DEFAULTS",
984 "CARRIER_PEERS",
985 &(topology->default_carrier_peers)))
986 {
987 LOG (GNUNET_ERROR_TYPE_ERROR,
988 "Missing default CARRIER_PEERS!\n");
989 return NULL;
990 }
991 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
992 "DEFAULTS",
993 "SUBNET_PEERS",
994 &(topology->default_subnet_peers)))
995 {
996 LOG (GNUNET_ERROR_TYPE_ERROR,
997 "Missing default SUBNET_PEERS!\n");
998 return NULL;
999 }
1000 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1001 "BACKBONE",
1002 "CARRIERS",
1003 &(topology->num_carriers)))
1004 {
1005 LOG (GNUNET_ERROR_TYPE_INFO,
1006 "No carrier configured!\n");
1007 return NULL;
1008 }
1009 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1010 "BACKBONE",
1011 "BACKBONE_PEERS",
1012 &(topology->num_backbone_peers)))
1013 {
1014 LOG (GNUNET_ERROR_TYPE_INFO,
1015 "No backbone peers configured!\n");
1016 return NULL;
1017 }
1018 for (int i = 0;i < topology->num_backbone_peers; i++)
1019 {
1020 struct GNUNET_TESTING_NetjailBackbonePeer *peer = GNUNET_new (struct GNUNET_TESTING_NetjailBackbonePeer);
1021 struct GNUNET_ShortHashCode hkey;
1022
1023 topology->total++;
1024 peer->number = topology->total;
1025 GNUNET_CRYPTO_hash (&topology->total, sizeof(topology->total), &hc);
1026 memcpy (&hkey,
1027 &hc,
1028 sizeof (hkey));
1029 GNUNET_CONTAINER_multishortmap_put (topology->backbone_peers,
1030 &hkey,
1031 peer,
1032 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1033 }
1034 GNUNET_assert (NULL != topology->carriers);
1035 for (int i = 0;i < topology->num_carriers; i++)
1036 {
1037 struct GNUNET_TESTING_NetjailCarrier *carrier = GNUNET_new (struct GNUNET_TESTING_NetjailCarrier);
1038 struct GNUNET_ShortHashCode hkey;
1039 char *section;
1040
1041 topology->total++;
1042 carrier->number = topology->total;
1043 GNUNET_CRYPTO_hash (&topology->total, sizeof(topology->total), &hc);
1044 memcpy (&hkey,
1045 &hc,
1046 sizeof (hkey));
1047 GNUNET_assert (NULL != topology->carriers);
1048 GNUNET_CONTAINER_multishortmap_put (topology->carriers,
1049 &hkey,
1050 carrier,
1051 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1052 GNUNET_asprintf (&section, "CARRIER-%u", i);
1053 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1054 section,
1055 "SUBNETS",
1056 (unsigned long long *) &carrier->number_subnets))
1057 {
1058 carrier->number_subnets = topology->default_subnets;
1059 }
1060 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
1061 section,
1062 "CARRIER_PEERS",
1063 (unsigned long long *) &carrier->number_peers))
1064 {
1065 carrier->number_peers = topology->default_carrier_peers;
1066 }
1067 create_peers (cfg, topology, carrier);
1068 create_subnets (cfg, topology, carrier);
1069
1070 GNUNET_free (section);
1071 }
1072
1073 GNUNET_free (cfg);
1074
1075 return topology;
1076}
1077
1078
1079/**
1080 * Parse the topology data.
1081 *
1082 * @param data The topology data.
1083 * @return The GNUNET_TESTING_NetjailTopology
1084 *
1085struct GNUNET_TESTING_NetjailTopology *
1086GNUNET_TESTING_get_topo_from_string_ (const char *input)
1087{
1088 char *token;
1089 char *key = NULL;
1090 unsigned int out;
1091 char *rest = NULL;
1092 char *value = NULL;
1093 char *value2;
1094 char *data;
1095 int ret;
1096 struct GNUNET_TESTING_NetjailTopology *topo;
1097 struct GNUNET_TESTING_NetjailRouter *router;
1098 struct GNUNET_TESTING_NetjailNamespace *namespace;
1099 struct GNUNET_HashCode hc;
1100
1101 data = GNUNET_strdup (input);
1102 token = strtok_r (data, "\n", &rest);
1103 topo = GNUNET_new (struct GNUNET_TESTING_NetjailTopology);
1104 topo->map_namespaces =
1105 GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
1106 topo->map_globals =
1107 GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
1108
1109 while (NULL != token)
1110 {
1111 if (NULL != key)
1112 GNUNET_free (key);
1113 key = get_key (token);
1114 LOG (GNUNET_ERROR_TYPE_DEBUG,
1115 "In the loop with token: %s beginning with %s\n",
1116 token,
1117 key);
1118 if (0 == strcmp (key, "M"))
1119 {
1120 LOG (GNUNET_ERROR_TYPE_DEBUG,
1121 "Get first Value for M.\n");
1122 out = get_first_value (token);
1123 LOG (GNUNET_ERROR_TYPE_DEBUG,
1124 "M: %u\n",
1125 out);
1126 topo->nodes_m = out;
1127 }
1128 else if (0 == strcmp (key, "N"))
1129 {
1130 LOG (GNUNET_ERROR_TYPE_DEBUG,
1131 "Get first Value for N.\n");
1132 out = get_first_value (token);
1133 LOG (GNUNET_ERROR_TYPE_DEBUG,
1134 "N: %u\n",
1135 out);
1136 topo->namespaces_n = out;
1137 }
1138 else if (0 == strcmp (key, "X"))
1139 {
1140 LOG (GNUNET_ERROR_TYPE_DEBUG,
1141 "Get first Value for X.\n");
1142 out = get_first_value (token);
1143 LOG (GNUNET_ERROR_TYPE_DEBUG,
1144 "X: %u\n",
1145 out);
1146 topo->nodes_x = out;
1147 }
1148 else if (0 == strcmp (key, "AC"))
1149 {
1150 LOG (GNUNET_ERROR_TYPE_DEBUG,
1151 "Get first Value for AC.\n");
1152 out = get_first_value (token);
1153 LOG (GNUNET_ERROR_TYPE_DEBUG,
1154 "AC: %u\n",
1155 out);
1156 topo->additional_connects = out;
1157 }
1158 else if (0 == strcmp (key, "T"))
1159 {
1160 LOG (GNUNET_ERROR_TYPE_DEBUG,
1161 "Get first string value for T.\n");
1162 value = get_first_string_value (token);
1163 LOG (GNUNET_ERROR_TYPE_DEBUG,
1164 "value: %s\n",
1165 value);
1166 topo->plugin = value;
1167 }
1168 else if (0 == strcmp (key, "K"))
1169 {
1170 struct GNUNET_ShortHashCode hkey_k;
1171 struct GNUNET_TESTING_NetjailNode *k_node = GNUNET_new (struct
1172 GNUNET_TESTING_NetjailNode);
1173
1174 LOG (GNUNET_ERROR_TYPE_DEBUG,
1175 "Get first Value for K.\n");
1176 out = get_first_value (token);
1177 LOG (GNUNET_ERROR_TYPE_DEBUG,
1178 "K: %u\n",
1179 out);
1180 k_node->node_n = out;
1181 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
1182 memcpy (&hkey_k,
1183 &hc,
1184 sizeof (hkey_k));
1185 k_node->is_global = GNUNET_YES;
1186
1187 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
1188 topo->map_globals,
1189 &hkey_k))
1190 GNUNET_break (0);
1191 else
1192 GNUNET_CONTAINER_multishortmap_put (topo->map_globals,
1193 &hkey_k,
1194 k_node,
1195 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1196 LOG (GNUNET_ERROR_TYPE_DEBUG,
1197 "Get value for key value on K.\n");
1198 value = get_value ("plugin", token);
1199 LOG (GNUNET_ERROR_TYPE_DEBUG,
1200 "value: %s\n",
1201 value);
1202 k_node->plugin = value;
1203 parse_ac (k_node, token);
1204 node_connections (token, k_node);
1205 GNUNET_free (value);
1206 }
1207 else if (0 == strcmp (key, "R"))
1208 {
1209 struct GNUNET_ShortHashCode hkey_r;
1210 router = GNUNET_new (struct GNUNET_TESTING_NetjailRouter);
1211
1212 LOG (GNUNET_ERROR_TYPE_DEBUG,
1213 "Get first Value for R.\n");
1214 out = get_first_value (token);
1215 LOG (GNUNET_ERROR_TYPE_DEBUG,
1216 "R: %u\n",
1217 out);
1218 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
1219 memcpy (&hkey_r,
1220 &hc,
1221 sizeof (hkey_r));
1222 LOG (GNUNET_ERROR_TYPE_DEBUG,
1223 "Get value for key tcp_port on R.\n");
1224 value = get_value ("tcp_port", token);
1225 LOG (GNUNET_ERROR_TYPE_DEBUG,
1226 "tcp_port: %s\n",
1227 value);
1228 ret = sscanf (value, "%u", &(router->tcp_port));
1229 GNUNET_free (value);
1230 GNUNET_break (0 != ret && 1 >= router->tcp_port);
1231
1232 LOG (GNUNET_ERROR_TYPE_DEBUG,
1233 "Get value for key udp_port on R.\n");
1234 value2 = get_value ("udp_port", token);
1235 ret = sscanf (value2, "%u", &(router->udp_port));
1236 GNUNET_free (value2);
1237 GNUNET_break (0 != ret && 1 >= router->udp_port);
1238 LOG (GNUNET_ERROR_TYPE_DEBUG,
1239 "udp_port: %s\n",
1240 value2);
1241 GNUNET_free (value2);
1242 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
1243 topo->map_namespaces,
1244 &hkey_r))
1245 {
1246 namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces,
1247 &hkey_r);
1248 }
1249 else
1250 {
1251 namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
1252 namespace->namespace_n = out;
1253 namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
1254 GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces,
1255 &hkey_r,
1256 namespace,
1257 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1258 }
1259 namespace->router = router;
1260
1261 }
1262 else if (0 == strcmp (key, "P"))
1263 {
1264 struct GNUNET_TESTING_NetjailNode *p_node = GNUNET_new (struct
1265 GNUNET_TESTING_NetjailNode);
1266 struct GNUNET_ShortHashCode hkey_p;
1267
1268 LOG (GNUNET_ERROR_TYPE_DEBUG,
1269 "Get first Value for P.\n");
1270 out = get_first_value (token);
1271 LOG (GNUNET_ERROR_TYPE_DEBUG,
1272 "P: %u\n",
1273 out);
1274 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
1275 memcpy (&hkey_p,
1276 &hc,
1277 sizeof (hkey_p));
1278
1279 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
1280 topo->map_namespaces,
1281 &hkey_p))
1282 {
1283 namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces,
1284 &hkey_p);
1285 }
1286 else
1287 {
1288 namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
1289 namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
1290 namespace->namespace_n = out;
1291 GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces,
1292 &hkey_p,
1293 namespace,
1294 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1295 }
1296 LOG (GNUNET_ERROR_TYPE_DEBUG,
1297 "Get second Value for P.\n");
1298 out = get_second_value (token);
1299 LOG (GNUNET_ERROR_TYPE_DEBUG,
1300 "P: %u\n",
1301 out);
1302 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
1303 memcpy (&hkey_p,
1304 &hc,
1305 sizeof (hkey_p));
1306 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
1307 namespace->nodes,
1308 &hkey_p))
1309 {
1310 GNUNET_break (0);
1311 }
1312 else
1313 {
1314
1315 GNUNET_CONTAINER_multishortmap_put (namespace->nodes,
1316 &hkey_p,
1317 p_node,
1318 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1319 LOG (GNUNET_ERROR_TYPE_DEBUG,
1320 "Get value for key plugin on P.\n");
1321 value = get_value ("plugin", token);
1322 if (NULL != value)
1323 {
1324 LOG (GNUNET_ERROR_TYPE_DEBUG,
1325 "plugin: %s\n",
1326 value);
1327 p_node->plugin = value;
1328 }
1329 p_node->node_n = out;
1330 p_node->namespace_n = namespace->namespace_n;
1331 }
1332 LOG (GNUNET_ERROR_TYPE_DEBUG,
1333 "Get AC Value for P.\n");
1334 parse_ac (p_node, token);
1335 node_connections (token, p_node);
1336 }
1337 token = strtok_r (NULL, "\n", &rest);
1338 if (NULL != token)
1339 LOG (GNUNET_ERROR_TYPE_DEBUG,
1340 "Next token %s\n",
1341 token);
1342 }
1343 if (NULL != key)
1344 GNUNET_free (key);
1345 GNUNET_free (data);
1346 return topo;
1347 }*/
1348
1349
1350GNUNET_TESTING_SIMPLE_NETJAIL_TRAITS (
1351 GNUNET_TESTING_MAKE_IMPL_SIMPLE_TRAIT,
1352 GNUNET_TESTING)
1353
1354
1355/* end of netjail.c */