aboutsummaryrefslogtreecommitdiff
path: root/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c')
-rw-r--r--src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c914
1 files changed, 914 insertions, 0 deletions
diff --git a/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c b/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c
new file mode 100644
index 000000000..df6a81cb4
--- /dev/null
+++ b/src/service/testing/testing_api_cmd_netjail_start_cmds_helper.c
@@ -0,0 +1,914 @@
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/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail peers.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testing_plugin.h"
29#include "gnunet_testing_barrier.h"
30#include "gnunet_testing_netjail_lib.h"
31#include "testing.h"
32#include "testing_cmds.h"
33
34#define NETJAIL_EXEC_SCRIPT "netjail_exec.sh"
35
36#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
37
38/**
39 * Generic logging shortcut
40 */
41#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
42
43/**
44 * Struct to store messages send/received by the helper into a DLL
45 *
46 */
47struct HelperMessage
48{
49
50 /**
51 * Kept in a DLL.
52 */
53 struct HelperMessage *next;
54
55 /**
56 * Kept in a DLL.
57 */
58 struct HelperMessage *prev;
59
60 /**
61 * Size of the original message.
62 */
63 uint16_t bytes_msg;
64
65 /* Followed by @e bytes_msg of msg.*/
66};
67
68
69/**
70 * Struct to store information handed over to callbacks.
71 *
72 */
73struct NetJailState
74{
75 /**
76 * Global state of the interpreter, used by a command
77 * to access information about other commands.
78 */
79 struct GNUNET_TESTING_Interpreter *is;
80
81 /**
82 * Context for our asynchronous completion.
83 */
84 struct GNUNET_TESTING_AsyncContext ac;
85
86 /**
87 * The complete topology information.
88 */
89 struct GNUNET_TESTING_NetjailTopology *topology;
90
91 /**
92 * Array with handles of helper processes.
93 */
94 const struct GNUNET_HELPER_Handle **helper;
95
96 /**
97 * Size of the array NetJailState#helper.
98 *
99 */
100 unsigned int n_helper;
101
102 /**
103 * Number of nodes in a natted subnet.
104 *
105 */
106 unsigned int local_m;
107
108 /**
109 * Number of natted subnets.
110 *
111 */
112 unsigned int global_n;
113
114 /**
115 * Number of global known nodes.
116 *
117 */
118 unsigned int known;
119
120
121 /**
122 * Number of test environments started.
123 *
124 */
125 unsigned int number_of_testsystems_started;
126
127 /**
128 * Number of peers started.
129 *
130 */
131 unsigned int number_of_peers_started;
132
133 /**
134 * Number of local tests finished.
135 *
136 */
137 unsigned int number_of_local_tests_finished;
138
139 /**
140 * Number of local tests prepared to finish.
141 *
142 */
143 unsigned int number_of_local_tests_prepared;
144
145 /**
146 * Name of the test case plugin the helper will load.
147 *
148 */
149 char *plugin_name;
150
151 /**
152 * Shall we read the topology from file, or from a string.
153 */
154 unsigned int *read_file;
155
156 /**
157 * String with topology data or name of topology file.
158 */
159 char *topology_data;
160
161 /**
162 * Time after this cmd has to finish.
163 */
164 struct GNUNET_TIME_Relative timeout;
165
166 /**
167 * Timeout task.
168 */
169 struct GNUNET_SCHEDULER_Task *timeout_task;
170};
171
172/**
173 * Struct containing the number of the netjail node and the NetJailState which
174 * will be handed to callbacks specific to a test environment.
175 */
176struct TestingSystemCount
177{
178 /**
179 * The plugin correlated to this netjail node.
180 */
181 struct TestcasePlugin *plugin;
182
183 /**
184 * Kept in a DLL.
185 */
186 struct TestingSystemCount *next;
187
188 /**
189 * Kept in a DLL.
190 */
191 struct TestingSystemCount *prev;
192
193 /**
194 * The send handle for the helper
195 */
196 struct GNUNET_HELPER_SendHandle *shandle;
197
198 /**
199 * Struct to store information handed over to callbacks.
200 *
201 */
202 struct NetJailState *ns;
203
204 /**
205 * The messages send to the helper.
206 */
207 struct GNUNET_MessageHeader *msg;
208};
209
210
211/**
212* Code to clean up resource this cmd used.
213*
214* @param cls closure
215*/
216static void
217netjail_exec_cleanup (void *cls)
218{
219 struct NetJailState *ns = cls;
220 GNUNET_free (ns);
221}
222
223
224/**
225 * This function prepares an array with traits.
226 *
227 */
228static enum GNUNET_GenericReturnValue
229netjail_exec_traits (void *cls,
230 const void **ret,
231 const char *trait,
232 unsigned int index)
233{
234 struct NetJailState *ns = cls;
235 const struct GNUNET_HELPER_Handle **helper = ns->helper;
236
237
238 struct GNUNET_TESTING_Trait traits[] = {
239 GNUNET_TESTING_make_trait_helper_handles (helper),
240 GNUNET_TESTING_trait_end ()
241 };
242
243 return GNUNET_TESTING_get_trait (traits,
244 ret,
245 trait,
246 index);
247}
248
249
250/**
251 * Continuation function from GNUNET_HELPER_send()
252 *
253 * @param cls closure
254 * @param result GNUNET_OK on success,
255 * GNUNET_NO if helper process died
256 * GNUNET_SYSERR during GNUNET_HELPER_stop
257 */
258static void
259clear_msg (void *cls, int result)
260{
261 struct TestingSystemCount *tbc = cls;
262
263 GNUNET_assert (NULL != tbc->shandle);
264 // GNUNET_free (tbc->shandle);
265 GNUNET_free (tbc->plugin);
266 tbc->shandle = NULL;
267 GNUNET_free (tbc);
268}
269
270
271static void
272send_message_to_locals (
273 unsigned int i,
274 unsigned int j,
275 struct NetJailState *ns,
276 struct GNUNET_MessageHeader *header
277 )
278{
279 const struct GNUNET_HELPER_Handle *helper;
280 struct TestingSystemCount *tbc;
281 unsigned int count;
282
283 LOG (GNUNET_ERROR_TYPE_DEBUG,
284 "send message of type %u to locals\n",
285 header->type);
286 tbc = GNUNET_new (struct TestingSystemCount);
287 tbc->ns = ns;
288 if (0 == i)
289 count = j;
290 else
291 count = (i - 1) * ns->local_m + j + ns->known;
292
293 helper = ns->helper[count - 1];
294
295
296 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
297 (struct GNUNET_HELPER_Handle *) helper,
298 header,
299 GNUNET_NO,
300 &clear_msg,
301 tbc);
302
303 tbc->shandle = sh;
304}
305
306
307static void
308send_all_local_tests_prepared (unsigned int i, unsigned int j, struct
309 NetJailState *ns)
310{
311 struct GNUNET_TESTING_CommandAllLocalTestsPrepared *reply;
312 size_t msg_length;
313
314
315 msg_length = sizeof(struct GNUNET_TESTING_CommandAllLocalTestsPrepared);
316 reply = GNUNET_new (struct GNUNET_TESTING_CommandAllLocalTestsPrepared);
317 reply->header.type = htons (
318 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED);
319 reply->header.size = htons ((uint16_t) msg_length);
320
321 send_message_to_locals (i, j, ns, &reply->header);
322 GNUNET_free (reply);
323}
324
325
326static void
327send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
328{
329 struct GNUNET_TESTING_CommandAllPeersStarted *reply;
330 size_t msg_length;
331
332 msg_length = sizeof(struct GNUNET_TESTING_CommandAllPeersStarted);
333 reply = GNUNET_new (struct GNUNET_TESTING_CommandAllPeersStarted);
334 reply->header.type = htons (
335 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
336 reply->header.size = htons ((uint16_t) msg_length);
337
338 send_message_to_locals (i, j, ns, &reply->header);
339 GNUNET_free (reply);
340}
341
342
343void
344barrier_attached (struct NetJailState *ns, const struct
345 GNUNET_MessageHeader *message)
346{
347 struct CommandBarrierAttached *am;
348 struct GNUNET_TESTING_NetjailNode *node;
349 struct GNUNET_TESTING_Barrier *barrier;
350 struct GNUNET_ShortHashCode key;
351 struct GNUNET_HashCode hc;
352 const char *barrier_name;
353
354 am = (struct CommandBarrierAttached *) message;
355 barrier_name = (const char *) &am[1];
356 barrier = TST_interpreter_get_barrier (ns->is, barrier_name);
357 GNUNET_assert (NULL != barrier);
358 node = GNUNET_TESTING_barrier_get_node (barrier, am->node_number);
359 if (NULL == node)
360 {
361 node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
362 node->node_number = am->node_number;
363
364 GNUNET_CRYPTO_hash (&(node->node_number), sizeof(node->node_number), &hc);
365 memcpy (&key, &hc, sizeof (key));
366 GNUNET_CONTAINER_multishortmap_put (barrier->nodes,
367 &key,
368 node,
369 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
370 }
371 node->expected_reaches = node->expected_reaches + am->expected_reaches;
372 barrier->expected_reaches = barrier->expected_reaches + am->expected_reaches;
373}
374
375
376void
377barrier_reached (struct NetJailState *ns, const struct
378 GNUNET_MessageHeader *message)
379{
380 struct GNUNET_TESTING_Barrier *barrier;
381 const char *barrier_name;
382 struct GNUNET_TESTING_CommandBarrierReached *rm = (struct
383 GNUNET_TESTING_CommandBarrierReached
384 *) message;
385
386 barrier_name = (const char *) &rm[1];
387
388 barrier = TST_interpreter_get_barrier (ns->is, barrier_name);
389 GNUNET_assert (NULL != barrier);
390 LOG (GNUNET_ERROR_TYPE_DEBUG,
391 "barrier %s reached %p %u\n",
392 barrier_name,
393 barrier,
394 barrier->reached);
395 barrier->reached++;
396 LOG (GNUNET_ERROR_TYPE_DEBUG,
397 "%u %p\n",
398 barrier->reached,
399 barrier);
400 if (GNUNET_TESTING_barrier_crossable (barrier))
401 {
402 LOG (GNUNET_ERROR_TYPE_DEBUG,
403 "%s can be crossed\n",
404 barrier_name);
405 TST_interpreter_finish_attached_cmds (ns->is, barrier->name);
406 }
407 LOG (GNUNET_ERROR_TYPE_DEBUG,
408 "barrier %s reached finished\n",
409 barrier_name);
410}
411
412
413/**
414 * Functions with this signature are called whenever a
415 * complete message is received by the tokenizer.
416 *
417 * Do not call GNUNET_SERVER_mst_destroy in callback
418 *
419 * @param cls closure
420 * @param client identification of the client
421 * @param message the actual message
422 *
423 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
424 */
425static int
426helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
427{
428 struct NetJailState *ns = cls;
429 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
430 uint16_t message_type = ntohs (message->type);
431 struct GNUNET_TESTING_CommandLocalFinished *lf;
432
433 switch (message_type)
434 {
435 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED:
436 barrier_attached (ns, message);
437 break;
438 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED:
439 barrier_reached (ns, message);
440 break;
441 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY:
442 ns->number_of_testsystems_started++;
443 break;
444 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED:
445 ns->number_of_peers_started++;
446 if (ns->number_of_peers_started == total_number)
447 {
448 for (int i = 1; i <= ns->known; i++)
449 {
450 send_all_peers_started (0,i, ns);
451 }
452 for (int i = 1; i <= ns->global_n; i++)
453 {
454 for (int j = 1; j <= ns->local_m; j++)
455 {
456 send_all_peers_started (i,j, ns);
457 }
458 }
459 ns->number_of_peers_started = 0;
460 }
461 break;
462 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED:
463 ns->number_of_local_tests_prepared++;
464 if (ns->number_of_local_tests_prepared == total_number)
465 {
466 for (int i = 1; i <= ns->known; i++)
467 {
468 send_all_local_tests_prepared (0,i, ns);
469 }
470
471 for (int i = 1; i <= ns->global_n; i++)
472 {
473 for (int j = 1; j <= ns->local_m; j++)
474 {
475 send_all_local_tests_prepared (i,j, ns);
476 }
477 }
478 }
479 break;
480 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED:
481 lf = (struct GNUNET_TESTING_CommandLocalFinished *) message;
482
483 ns->number_of_local_tests_finished++;
484 if (GNUNET_OK != lf->rv)
485 {
486 GNUNET_TESTING_async_fail (&(ns->ac));
487 }
488 else if (ns->number_of_local_tests_finished == total_number)
489 {
490 GNUNET_SCHEDULER_cancel (ns->timeout_task);
491 ns->timeout_task = NULL;
492 GNUNET_TESTING_async_finish (&ns->ac);
493 }
494 break;
495 default:
496 // We received a message we can not handle.
497 GNUNET_assert (0);
498 }
499
500 LOG (GNUNET_ERROR_TYPE_DEBUG,
501 "total %u sysstarted %u peersstarted %u prep %u finished %u %u %u %u\n",
502 total_number,
503 ns->number_of_testsystems_started,
504 ns->number_of_peers_started,
505 ns->number_of_local_tests_prepared,
506 ns->number_of_local_tests_finished,
507 ns->local_m,
508 ns->global_n,
509 ns->known);
510
511
512 return GNUNET_OK;
513}
514
515
516/**
517 * Callback called if there was an exception during execution of the helper.
518 *
519 */
520static void
521exp_cb (void *cls)
522{
523 struct NetJailState *ns = cls;
524
525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
526 if (NULL != ns->timeout_task)
527 GNUNET_SCHEDULER_cancel (ns->timeout_task);
528 GNUNET_TESTING_async_fail (&(ns->ac));
529}
530
531
532/**
533 * Function to initialize a init message for the helper.
534 *
535 * @param plugin_name Name of the test case plugin the helper will load.
536 *
537 */
538static struct GNUNET_TESTING_CommandHelperInit *
539create_helper_init_msg_ (const char *plugin_name)
540{
541 struct GNUNET_TESTING_CommandHelperInit *msg;
542 uint16_t plugin_name_len;
543 uint16_t msg_size;
544
545 GNUNET_assert (NULL != plugin_name);
546 plugin_name_len = strlen (plugin_name);
547 msg_size = sizeof(struct GNUNET_TESTING_CommandHelperInit) + plugin_name_len;
548 msg = GNUNET_malloc (msg_size);
549 msg->header.size = htons (msg_size);
550 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
551 msg->plugin_name_size = htons (plugin_name_len);
552 GNUNET_memcpy ((char *) &msg[1],
553 plugin_name,
554 plugin_name_len);
555 return msg;
556}
557
558
559/**
560 * Function which start a single helper process.
561 *
562 */
563static void
564start_helper (struct NetJailState *ns,
565 unsigned int m,
566 unsigned int n)
567{
568 struct TestcasePlugin *plugin;
569 struct GNUNET_HELPER_Handle *helper;
570 struct GNUNET_TESTING_CommandHelperInit *msg;
571 struct TestingSystemCount *tbc;
572 char *m_char;
573 char *n_char;
574 char *global_n_char;
575 char *local_m_char;
576 char *known_char;
577 char *node_id;
578 char *plugin_name;
579 char *read_file;
580 pid_t pid;
581 unsigned int script_num;
582 struct GNUNET_ShortHashCode *hkey;
583 struct GNUNET_ShortHashCode key;
584 struct GNUNET_HashCode hc;
585 struct GNUNET_TESTING_NetjailTopology *topology = ns->topology;
586 struct GNUNET_TESTING_NetjailNode *node;
587 struct GNUNET_TESTING_NetjailNode *barrier_node;
588 struct GNUNET_TESTING_NetjailNamespace *namespace;
589 char *data_dir;
590 char *script_name;
591 struct GNUNET_TESTING_BarrierListEntry *pos;
592 struct GNUNET_TESTING_Barrier *barrier;
593 struct GNUNET_TESTING_BarrierList *barriers;
594 unsigned int node_num;
595 char *binary_path;
596
597 if (0 == n)
598 {
599 node_num = m;
600 script_num = m - 1;
601 }
602 else
603 {
604 node_num = (n - 1) * ns->local_m + m + ns->known;
605 script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known;
606 }
607 pid = getpid ();
608
609 GNUNET_asprintf (&m_char, "%u", m);
610 GNUNET_asprintf (&n_char, "%u", n);
611 GNUNET_asprintf (&local_m_char, "%u", ns->local_m);
612 GNUNET_asprintf (&global_n_char, "%u",ns->global_n);
613 GNUNET_asprintf (&known_char, "%u",ns->known);
614 GNUNET_asprintf (&node_id, "%s%06x-%06x\n",
615 "if",
616 pid,
617 script_num);
618 // GNUNET_asprintf (&topology_data, "'%s'", ns->topology_data);
619 GNUNET_asprintf (&read_file, "%u", *(ns->read_file));
620
621 data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
622 GNUNET_asprintf (&script_name, "%s%s", data_dir, NETJAIL_EXEC_SCRIPT);
623 unsigned int helper_check = GNUNET_OS_check_helper_binary (
624 script_name,
625 GNUNET_YES,
626 NULL);
627
628 tbc = GNUNET_new (struct TestingSystemCount);
629 tbc->ns = ns;
630
631 if (GNUNET_NO == helper_check)
632 {
633 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
634 "No SUID for %s!\n",
635 script_name);
636 GNUNET_TESTING_interpreter_fail (ns->is);
637 }
638 else if (GNUNET_NO == helper_check)
639 {
640 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
641 "%s not found!\n",
642 script_name);
643 GNUNET_TESTING_interpreter_fail (ns->is);
644 }
645
646 binary_path = GNUNET_OS_get_libexec_binary_path (HELPER_CMDS_BINARY);
647
648 LOG (GNUNET_ERROR_TYPE_DEBUG,
649 "sysstarted %u peersstarted %u prep %u finished %u %u %u %u\n",
650 ns->number_of_testsystems_started,
651 ns->number_of_peers_started,
652 ns->number_of_local_tests_prepared,
653 ns->number_of_local_tests_finished,
654 ns->local_m,
655 ns->global_n,
656 ns->known);
657 {
658 char *const script_argv[] = {script_name,
659 m_char,
660 n_char,
661 binary_path,
662 global_n_char,
663 local_m_char,
664 node_id,
665 read_file,
666 ns->topology_data,
667 NULL};
668 helper = GNUNET_HELPER_start (
669 GNUNET_YES,
670 script_name,
671 script_argv,
672 &helper_mst,
673 &exp_cb,
674 ns);
675 GNUNET_array_append (ns->helper, ns->n_helper, helper);
676 }
677 GNUNET_TESTING_add_netjail_helper (ns->is,
678 helper);
679 plugin_name = topology->plugin;
680
681 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
682 node = NULL;
683 if (0 == n)
684 {
685 GNUNET_CRYPTO_hash (&m, sizeof(m), &hc);
686 memcpy (hkey,
687 &hc,
688 sizeof (*hkey));
689 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals,
690 hkey))
691 {
692 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
693 hkey);
694 if (NULL != node->plugin)
695 plugin_name = node->plugin;
696 }
697 }
698 else
699 {
700 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
701 memcpy (hkey,
702 &hc,
703 sizeof (*hkey));
704 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces,
705 hkey))
706 {
707 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
708 hkey);
709 GNUNET_CRYPTO_hash (&m, sizeof(m), &hc);
710 memcpy (hkey,
711 &hc,
712 sizeof (*hkey));
713 if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes,
714 hkey))
715 {
716 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
717 hkey);
718 if (NULL != node->plugin)
719 plugin_name = node->plugin;
720 }
721 }
722
723
724 }
725 GNUNET_assert (NULL != node);
726 node->node_number = node_num;
727 plugin = GNUNET_new (struct TestcasePlugin);
728 plugin->api = GNUNET_PLUGIN_load (plugin_name,
729 NULL);
730 barriers = plugin->api->get_waiting_for_barriers ();
731
732
733 for (pos = barriers->head; NULL != pos; pos = pos->next)
734 {
735 barrier = TST_interpreter_get_barrier (ns->is, pos->barrier_name);
736 if (NULL == barrier)
737 {
738 LOG (GNUNET_ERROR_TYPE_DEBUG,
739 "barrier %s added\n",
740 pos->barrier_name);
741 barrier = GNUNET_new (struct GNUNET_TESTING_Barrier);
742 barrier->name = pos->barrier_name;
743 barrier->shadow = GNUNET_YES;
744 TST_interpreter_add_barrier (ns->is, barrier);
745
746 LOG (GNUNET_ERROR_TYPE_DEBUG,
747 "%u %p\n",
748 barrier->reached,
749 barrier);
750
751 barrier->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
752 }
753 LOG (GNUNET_ERROR_TYPE_DEBUG,
754 "barrier %p %s node %u added \n",
755 barrier,
756 pos->barrier_name,
757 node->node_number);
758 barrier_node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
759 barrier_node->node_number = node->node_number;
760 barrier_node->expected_reaches = pos->expected_reaches;
761 barrier->expected_reaches = barrier->expected_reaches
762 + pos->expected_reaches;
763 LOG (GNUNET_ERROR_TYPE_DEBUG,
764 "number_to_be_reached %u\n",
765 barrier->number_to_be_reached);
766 if (GNUNET_YES == barrier->shadow)
767 barrier->number_to_be_reached++;
768 LOG (GNUNET_ERROR_TYPE_DEBUG,
769 "number_to_be_reached %u\n",
770 barrier->number_to_be_reached);
771 GNUNET_CRYPTO_hash (&(node->node_number), sizeof(node->node_number), &hc);
772 memcpy (&key, &hc, sizeof (key));
773 GNUNET_CONTAINER_multishortmap_put (barrier->nodes,
774 &key,
775 barrier_node,
776 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
777 }
778
779 tbc->plugin = plugin;
780
781 msg = create_helper_init_msg_ (plugin_name);
782
783 tbc->shandle = GNUNET_HELPER_send (
784 helper,
785 &msg->header,
786 GNUNET_NO,
787 &clear_msg,
788 tbc);
789
790 if (NULL == tbc->shandle)
791 {
792 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
793 "Send handle is NULL!\n");
794 GNUNET_TESTING_interpreter_fail (ns->is);
795 }
796 GNUNET_free (pos);
797 GNUNET_free (binary_path);
798 GNUNET_free (hkey);
799 GNUNET_free (msg);
800 GNUNET_free (m_char);
801 GNUNET_free (n_char);
802 GNUNET_free (local_m_char);
803 GNUNET_free (global_n_char);
804 GNUNET_free (known_char);
805 GNUNET_free (node_id);
806 GNUNET_free (read_file);
807 GNUNET_free (data_dir);
808 GNUNET_free (script_name);
809 GNUNET_free (barriers);
810}
811
812
813/**
814 * Function run when the cmd terminates (good or bad) with timeout.
815 *
816 * @param cls the interpreter state
817 */
818static void
819do_timeout (void *cls)
820{
821 struct NetJailState *ns = cls;
822 struct GNUNET_TESTING_Command *cmd;
823
824 ns->timeout_task = NULL;
825 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
826 "Terminating cmd due to global timeout\n");
827 cmd = GNUNET_TESTING_interpreter_get_current_command (ns->is);
828 GNUNET_TESTING_async_finish (cmd->ac);
829}
830
831
832/**
833* This function starts a helper process for each node.
834*
835* @param cls closure.
836* @param cmd CMD being run.
837* @param is interpreter state.
838*/
839static void
840netjail_exec_run (void *cls,
841 struct GNUNET_TESTING_Interpreter *is)
842{
843 struct NetJailState *ns = cls;
844
845 ns->is = is;
846 for (int i = 1; i <= ns->known; i++)
847 {
848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
849 "i %u\n",
850 i);
851 start_helper (ns,
852 i,
853 0);
854 }
855
856 for (int i = 1; i <= ns->global_n; i++)
857 {
858 for (int j = 1; j <= ns->local_m; j++)
859 {
860 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
861 "i %u j %u\n",
862 i,
863 j);
864 start_helper (ns,
865 j,
866 i);
867 }
868 }
869 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
870 "Adding timeout %s\n",
871 GNUNET_STRINGS_relative_time_to_string (ns->timeout, GNUNET_NO));
872 ns->timeout_task
873 = GNUNET_SCHEDULER_add_delayed (ns->timeout,
874 &do_timeout,
875 ns);
876}
877
878
879/**
880 * Create command.
881 *
882 * @param label Name for the command.
883 * @param topology The complete topology information.
884 * @param read_file Flag indicating if the the name of the topology file is send to the helper, or a string with the topology data.
885 * @param topology_data If read_file is GNUNET_NO, topology_data holds the string with the topology.
886 * @param timeout Before this timeout is reached this cmd MUST finish.
887 * @return command.
888 */
889struct GNUNET_TESTING_Command
890GNUNET_TESTING_cmd_netjail_start_cmds_helper (
891 const char *label,
892 struct GNUNET_TESTING_NetjailTopology *topology,
893 unsigned int *read_file,
894 char *topology_data,
895 struct GNUNET_TIME_Relative timeout)
896{
897 struct NetJailState *ns;
898
899 ns = GNUNET_new (struct NetJailState);
900 ns->local_m = topology->nodes_m;
901 ns->global_n = topology->namespaces_n;
902 ns->known = topology->nodes_x;
903 ns->plugin_name = topology->plugin;
904 ns->topology = topology;
905 ns->read_file = read_file;
906 ns->topology_data = topology_data;
907 ns->timeout = GNUNET_TIME_relative_subtract (timeout, TIMEOUT);
908
909 return GNUNET_TESTING_command_new (ns, label,
910 &netjail_exec_run,
911 &netjail_exec_cleanup,
912 &netjail_exec_traits,
913 &ns->ac);
914}