aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-05-12 15:48:52 +0000
committerNathan S. Evans <evans@in.tum.de>2010-05-12 15:48:52 +0000
commitdfe5fd29a357766ad681d7c95c47e06717367aa4 (patch)
treeef75959224a76f3e27aca614219267f4d14e96b0 /src/testing
parent0bba5c2a473984a776f37ff064e926e4f0742f24 (diff)
downloadgnunet-dfe5fd29a357766ad681d7c95c47e06717367aa4.tar.gz
gnunet-dfe5fd29a357766ad681d7c95c47e06717367aa4.zip
churn fixes and testcase
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/test_testing_data_topology_churn.conf44
-rw-r--r--src/testing/test_testing_topology_churn.c322
-rw-r--r--src/testing/testing.c18
-rw-r--r--src/testing/testing_group.c40
4 files changed, 415 insertions, 9 deletions
diff --git a/src/testing/test_testing_data_topology_churn.conf b/src/testing/test_testing_data_topology_churn.conf
new file mode 100644
index 000000000..a4c2f8c15
--- /dev/null
+++ b/src/testing/test_testing_data_topology_churn.conf
@@ -0,0 +1,44 @@
1[PATHS]
2SERVICEHOME = /tmp/test-gnunet-testing/
3DEFAULTCONFIG = test_testing_data_topology_churn.conf
4
5[resolver]
6PORT = 2564
7
8[transport]
9PORT = 2565
10PLUGINS = tcp
11#PREFIX = xterm -e xterm -T transport -e gdb --args
12#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport
13#PREFIX = valgrind --tool=memcheck --log-file=logs%p
14#DEBUG = YES
15
16[arm]
17PORT = 2566
18DEFAULTSERVICES = peerinfo transport core
19
20[statistics]
21PORT = 2567
22
23[transport-tcp]
24PORT = 2568
25
26[transport-udp]
27PORT = 2568
28
29[peerinfo]
30PORT = 2569
31#DEBUG = YES
32#PREFIX = xterm -e xterm -T peerinfo -e gdb --args
33#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/peerinfo/.libs/gnunet-service-peerinfo
34#PREFIX = valgrind --tool=memcheck --log-file=peerinfo%p
35
36[core]
37PORT = 2570
38#PREFIX = xterm -e xterm -T CORE -e gdb --args
39#PREFIX = valgrind --tool=memcheck --log-file=logs%p
40#DEBUG = YES
41
42[testing]
43NUM_PEERS = 12
44WEAKRANDOM = YES
diff --git a/src/testing/test_testing_topology_churn.c b/src/testing/test_testing_topology_churn.c
new file mode 100644
index 000000000..0d894378f
--- /dev/null
+++ b/src/testing/test_testing_topology_churn.c
@@ -0,0 +1,322 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file testing/test_testing_topology_churn.c
22 * @brief base testcase for testing simple churn functionality
23 */
24#include "platform.h"
25#include "gnunet_testing_lib.h"
26#include "gnunet_core_service.h"
27
28#define VERBOSE GNUNET_YES
29
30/**
31 * How long until we fail the whole testcase?
32 */
33#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600)
34
35/**
36 * How long until we give up on starting the peers? (Must be longer than the connect timeout!)
37 */
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
39
40#define DEFAULT_NUM_PEERS 4
41
42static int ok;
43
44static unsigned long long num_peers;
45
46static unsigned int expected_connections;
47
48static unsigned int expected_failed_connections;
49
50static unsigned long long peers_left;
51
52static struct GNUNET_TESTING_PeerGroup *pg;
53
54static struct GNUNET_SCHEDULER_Handle *sched;
55
56const struct GNUNET_CONFIGURATION_Handle *main_cfg;
57
58GNUNET_SCHEDULER_TaskIdentifier die_task;
59
60static char *test_directory;
61
62#define MTYPE 12345
63
64struct GNUNET_TestMessage
65{
66 /**
67 * Header of the message
68 */
69 struct GNUNET_MessageHeader header;
70
71 /**
72 * Unique identifier for this message.
73 */
74 uint32_t uid;
75};
76
77static void
78finish_testing ()
79{
80 GNUNET_assert (pg != NULL);
81
82 if (die_task != GNUNET_SCHEDULER_NO_TASK)
83 GNUNET_SCHEDULER_cancel(sched, die_task);
84
85#if VERBOSE
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "Called finish testing, stopping daemons.\n");
88#endif
89
90#if VERBOSE
91 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
92 "Calling daemons_stop\n");
93#endif
94 GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
95#if VERBOSE
96 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
97 "daemons_stop finished\n");
98#endif
99
100 ok = 0;
101}
102
103static void
104end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
105{
106 char *msg = cls;
107 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
108 "End badly was called (%s)... stopping daemons.\n", msg);
109
110 if (pg != NULL)
111 {
112 GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
113 ok = 7331; /* Opposite of leet */
114 }
115 else
116 ok = 401; /* Never got peers started */
117
118}
119
120struct ChurnTestContext
121{
122 GNUNET_SCHEDULER_Task next_task;
123
124};
125
126static struct ChurnTestContext churn_ctx;
127
128/**
129 * Churn callback, report on success or failure of churn operation.
130 *
131 * @param cls closure
132 * @param emsg NULL on success
133 */
134void churn_callback(void *cls,
135 const char *emsg)
136{
137 if (emsg == NULL)
138 {
139 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Successfully churned peers!\n", emsg);
140 GNUNET_SCHEDULER_add_now(sched, churn_ctx.next_task, NULL);
141 }
142 else
143 {
144 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to churn peers with error `%s'\n", emsg);
145 GNUNET_SCHEDULER_cancel(sched, die_task);
146 die_task = GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL);
147 }
148}
149
150
151static void
152churn_peers_both()
153{
154 churn_ctx.next_task = &finish_testing;
155 GNUNET_TESTING_daemons_churn(pg, 1, 1, TIMEOUT, &churn_callback, NULL);
156}
157
158static void
159churn_peers_off_again()
160{
161 churn_ctx.next_task = &churn_peers_both;
162 GNUNET_TESTING_daemons_churn(pg, 2, 0, TIMEOUT, &churn_callback, NULL);
163}
164
165static void
166churn_peers_on()
167{
168 churn_ctx.next_task = &churn_peers_off_again;
169 GNUNET_TESTING_daemons_churn(pg, 0, 2, TIMEOUT, &churn_callback, NULL);
170}
171
172static void
173churn_peers_off()
174{
175 churn_ctx.next_task = &churn_peers_on;
176 GNUNET_TESTING_daemons_churn(pg, 2, 0, TIMEOUT, &churn_callback, NULL);
177}
178
179static void
180peers_started_callback (void *cls,
181 const struct GNUNET_PeerIdentity *id,
182 const struct GNUNET_CONFIGURATION_Handle *cfg,
183 struct GNUNET_TESTING_Daemon *d, const char *emsg)
184{
185 if (emsg != NULL)
186 {
187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start daemon with error: `%s'\n",
188 emsg);
189 return;
190 }
191 GNUNET_assert (id != NULL);
192#if VERBOSE
193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n",
194 (num_peers - peers_left) + 1, num_peers);
195#endif
196 peers_left--;
197 if (peers_left == 0)
198 {
199#if VERBOSE
200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
201 "All %d daemons started, now testing churn!\n",
202 num_peers);
203#endif
204 GNUNET_SCHEDULER_cancel (sched, die_task);
205 /* Set up task in case topology creation doesn't finish
206 * within a reasonable amount of time */
207 die_task = GNUNET_SCHEDULER_add_delayed (sched,
208 GNUNET_TIME_relative_multiply
209 (GNUNET_TIME_UNIT_MINUTES, 5),
210 &end_badly, "from peers_started_callback");
211 churn_peers_off ();
212 ok = 0;
213 }
214}
215
216
217static void
218run (void *cls,
219 struct GNUNET_SCHEDULER_Handle *s,
220 char *const *args,
221 const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
222{
223 sched = s;
224 ok = 1;
225
226#if VERBOSE
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 "Starting daemons based on config file %s\n", cfgfile);
229#endif
230
231 if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", "servicehome", &test_directory))
232 {
233 ok = 404;
234 return;
235 }
236
237 if (GNUNET_SYSERR ==
238 GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
239 &num_peers))
240 num_peers = DEFAULT_NUM_PEERS;
241
242 main_cfg = cfg;
243
244 peers_left = num_peers;
245
246 /* For this specific test we only really want a CLIQUE topology as the
247 * overlay allowed topology, and a RING topology as the underlying connection
248 * allowed topology. So we will expect only num_peers * 2 connections to
249 * work, and (num_peers * (num_peers - 1)) - (num_peers * 2) to fail.
250 */
251 expected_connections = num_peers * (num_peers - 1);
252 expected_failed_connections = expected_connections - (num_peers * 2);
253
254
255 /* Set up a task to end testing if peer start fails */
256 die_task = GNUNET_SCHEDULER_add_delayed (sched,
257 GNUNET_TIME_relative_multiply
258 (GNUNET_TIME_UNIT_MINUTES, 5),
259 &end_badly, "didn't start all daemons in reasonable amount of time!!!");
260
261 pg = GNUNET_TESTING_daemons_start (sched, cfg,
262 peers_left, TIMEOUT, NULL, NULL, &peers_started_callback, NULL,
263 NULL, NULL, NULL);
264
265}
266
267static int
268check ()
269{
270 int ret;
271 char *const argv[] = {"test-testing-topology-churn",
272 "-c",
273 "test_testing_data_topology_churn.conf",
274#if VERBOSE
275 "-L", "DEBUG",
276#endif
277 NULL
278 };
279 struct GNUNET_GETOPT_CommandLineOption options[] = {
280 GNUNET_GETOPT_OPTION_END
281 };
282 ret = GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
283 argv, "test-testing-topology-churn", "nohelp",
284 options, &run, &ok);
285 if (ret != GNUNET_OK)
286 {
287 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`test-testing-topology-churn': Failed with error code %d\n", ret);
288 }
289
290 return ok;
291}
292
293int
294main (int argc, char *argv[])
295{
296 int ret;
297
298 GNUNET_log_setup ("test_testing_topology_churn",
299#if VERBOSE
300 "DEBUG",
301#else
302 "WARNING",
303#endif
304 NULL);
305 ret = check ();
306
307 /**
308 * Need to remove base directory, subdirectories taken care
309 * of by the testing framework.
310 */
311 if (test_directory != NULL)
312 {
313 if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK)
314 {
315 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to remove testing directory %s\n", test_directory);
316 }
317 }
318
319 return ret;
320}
321
322/* end of test_testing_topology_churn.c */
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 1bf3e40cd..6d75be6a5 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -38,7 +38,7 @@
38#include "gnunet_hello_lib.h" 38#include "gnunet_hello_lib.h"
39 39
40#define DEBUG_TESTING GNUNET_NO 40#define DEBUG_TESTING GNUNET_NO
41#define DEBUG_TESTING_RECONNECT GNUNET_YES 41#define DEBUG_TESTING_RECONNECT GNUNET_NO
42 42
43/** 43/**
44 * How long do we wait after starting gnunet-service-arm 44 * How long do we wait after starting gnunet-service-arm
@@ -544,6 +544,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
544 return; 544 return;
545 } 545 }
546 /* wait some more */ 546 /* wait some more */
547 fprintf(stderr, "scheduling in shutdown_start\n");
547 d->task 548 d->task
548 = GNUNET_SCHEDULER_add_delayed (d->sched, 549 = GNUNET_SCHEDULER_add_delayed (d->sched,
549 GNUNET_CONSTANTS_EXEC_WAIT, 550 GNUNET_CONSTANTS_EXEC_WAIT,
@@ -589,11 +590,15 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
589 } 590 }
590 591
591 GNUNET_free_non_null(d->hello); 592 GNUNET_free_non_null(d->hello);
593 d->hello = NULL;
592 GNUNET_free_non_null (d->shortname); 594 GNUNET_free_non_null (d->shortname);
595 d->shortname = NULL;
593 if (NULL != d->dead_cb) 596 if (NULL != d->dead_cb)
594 d->dead_cb (d->dead_cb_cls, NULL); 597 d->dead_cb (d->dead_cb_cls, NULL);
595 598
596 GNUNET_free (d); 599 if (d->churn == GNUNET_NO)
600 GNUNET_free (d);
601
597 break; 602 break;
598 case SP_CONFIG_UPDATE: 603 case SP_CONFIG_UPDATE:
599 /* confirm copying complete */ 604 /* confirm copying complete */
@@ -969,6 +974,7 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d,
969 974
970 if (allow_restart == GNUNET_YES) 975 if (allow_restart == GNUNET_YES)
971 d->churn = GNUNET_YES; 976 d->churn = GNUNET_YES;
977
972 if (d->th != NULL) 978 if (d->th != NULL)
973 { 979 {
974 GNUNET_TRANSPORT_get_hello_cancel(d->th, &process_hello, d); 980 GNUNET_TRANSPORT_get_hello_cancel(d->th, &process_hello, d);
@@ -1014,10 +1020,10 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d,
1014 1020
1015 GNUNET_free_non_null(del_arg); 1021 GNUNET_free_non_null(del_arg);
1016 d->max_timeout = GNUNET_TIME_relative_to_absolute(timeout); 1022 d->max_timeout = GNUNET_TIME_relative_to_absolute(timeout);
1023 fprintf(stderr, "scheduling shutdown fsm phase\n");
1017 d->task 1024 d->task
1018 = GNUNET_SCHEDULER_add_delayed (d->sched, 1025 = GNUNET_SCHEDULER_add_now (d->sched,
1019 GNUNET_CONSTANTS_EXEC_WAIT, 1026 &start_fsm, d);
1020 &start_fsm, d);
1021} 1027}
1022 1028
1023 1029
@@ -1407,7 +1413,7 @@ reattempt_daemons_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext
1407 return; 1413 return;
1408 } 1414 }
1409#if DEBUG_TESTING_RECONNECT 1415#if DEBUG_TESTING_RECONNECT
1410 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "re-attempting connect of peer %s to peer %s\n", 1416 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "re-attempting connect of peer %s to peer %s\n",
1411 ctx->d1->shortname, ctx->d2->shortname); 1417 ctx->d1->shortname, ctx->d2->shortname);
1412#endif 1418#endif
1413 1419
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index cbab2b36c..aa1d5da69 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -29,6 +29,8 @@
29 29
30#define VERBOSE_TESTING GNUNET_NO 30#define VERBOSE_TESTING GNUNET_NO
31 31
32#define DEBUG_CHURN GNUNET_NO
33
32/** 34/**
33 * Lowest port used for GNUnet testing. Should be high enough to not 35 * Lowest port used for GNUnet testing. Should be high enough to not
34 * conflict with other applications running on the hosts but be low 36 * conflict with other applications running on the hosts but be low
@@ -2712,12 +2714,17 @@ churn_stop_callback (void *cls, const char *emsg)
2712 churn_ctx->num_to_stop--; 2714 churn_ctx->num_to_stop--;
2713 } 2715 }
2714 2716
2717#if DEBUG_CHURN
2718 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Stopped peer, %d left.\n", churn_ctx->num_to_stop);
2719#endif
2715 total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + (churn_ctx->num_to_start - churn_ctx->num_failed_start); 2720 total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + (churn_ctx->num_to_start - churn_ctx->num_failed_start);
2716 2721
2717 if (total_left == 0) 2722 if (total_left == 0)
2718 { 2723 {
2719 if ((churn_ctx->num_failed_stop > 0) || (churn_ctx->num_failed_start > 0)) 2724 if ((churn_ctx->num_failed_stop > 0) || (churn_ctx->num_failed_start > 0))
2720 GNUNET_asprintf(&error_message, "Churn didn't complete successfully, %u peers failed to start %u peers failed to be stopped!", churn_ctx->num_failed_start, churn_ctx->num_failed_stop); 2725 {
2726 GNUNET_asprintf(&error_message, "Churn didn't complete successfully, %u peers failed to start %u peers failed to be stopped!", churn_ctx->num_failed_start, churn_ctx->num_failed_stop);
2727 }
2721 churn_ctx->cb(churn_ctx->cb_cls, error_message); 2728 churn_ctx->cb(churn_ctx->cb_cls, error_message);
2722 GNUNET_free_non_null(error_message); 2729 GNUNET_free_non_null(error_message);
2723 GNUNET_free(churn_ctx); 2730 GNUNET_free(churn_ctx);
@@ -2757,6 +2764,10 @@ churn_start_callback (void *cls,
2757 churn_ctx->num_to_start--; 2764 churn_ctx->num_to_start--;
2758 } 2765 }
2759 2766
2767#if DEBUG_CHURN
2768 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Started peer, %d left.\n", churn_ctx->num_to_start);
2769#endif
2770
2760 total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + (churn_ctx->num_to_start - churn_ctx->num_failed_start); 2771 total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + (churn_ctx->num_to_start - churn_ctx->num_failed_start);
2761 2772
2762 if (total_left == 0) 2773 if (total_left == 0)
@@ -2810,6 +2821,12 @@ GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg,
2810 running = 0; 2821 running = 0;
2811 stopped = 0; 2822 stopped = 0;
2812 2823
2824 if ((von == 0) && (voff == 0)) /* No peers at all? */
2825 {
2826 cb(cb_cls, NULL);
2827 return;
2828 }
2829
2813 for (i = 0; i < pg->total; i++) 2830 for (i = 0; i < pg->total; i++)
2814 { 2831 {
2815 if (pg->peers[i].daemon->running == GNUNET_YES) 2832 if (pg->peers[i].daemon->running == GNUNET_YES)
@@ -2839,8 +2856,14 @@ GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg,
2839 churn_ctx = GNUNET_malloc(sizeof(struct ChurnContext)); 2856 churn_ctx = GNUNET_malloc(sizeof(struct ChurnContext));
2840 running_arr = GNUNET_malloc(running * sizeof(unsigned int)); 2857 running_arr = GNUNET_malloc(running * sizeof(unsigned int));
2841 stopped_arr = GNUNET_malloc(stopped * sizeof(unsigned int)); 2858 stopped_arr = GNUNET_malloc(stopped * sizeof(unsigned int));
2842 running_permute = GNUNET_CRYPTO_random_permute(GNUNET_CRYPTO_QUALITY_WEAK, running); 2859
2843 stopped_permute = GNUNET_CRYPTO_random_permute(GNUNET_CRYPTO_QUALITY_WEAK, stopped); 2860 running_permute = NULL;
2861 stopped_permute = NULL;
2862
2863 if (running > 0)
2864 running_permute = GNUNET_CRYPTO_random_permute(GNUNET_CRYPTO_QUALITY_WEAK, running);
2865 if (stopped > 0)
2866 stopped_permute = GNUNET_CRYPTO_random_permute(GNUNET_CRYPTO_QUALITY_WEAK, stopped);
2844 2867
2845 running = 0; 2868 running = 0;
2846 stopped = 0; 2869 stopped = 0;
@@ -2866,13 +2889,24 @@ GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg,
2866 2889
2867 for (i = 0; i < voff; i++) 2890 for (i = 0; i < voff; i++)
2868 { 2891 {
2892#if DEBUG_CHURN
2893 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Stopping peer %d!\n", running_permute[i]);
2894#endif
2869 GNUNET_TESTING_daemon_stop(pg->peers[running_arr[running_permute[i]]].daemon, timeout, &churn_stop_callback, churn_ctx, GNUNET_NO, GNUNET_YES); 2895 GNUNET_TESTING_daemon_stop(pg->peers[running_arr[running_permute[i]]].daemon, timeout, &churn_stop_callback, churn_ctx, GNUNET_NO, GNUNET_YES);
2870 } 2896 }
2871 2897
2872 for (i = 0; i < von; i++) 2898 for (i = 0; i < von; i++)
2873 { 2899 {
2900#if DEBUG_CHURN
2901 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Starting up peer %d!\n", stopped_permute[i]);
2902#endif
2874 GNUNET_TESTING_daemon_start_stopped(pg->peers[stopped_arr[stopped_permute[i]]].daemon, timeout, &churn_start_callback, churn_ctx); 2903 GNUNET_TESTING_daemon_start_stopped(pg->peers[stopped_arr[stopped_permute[i]]].daemon, timeout, &churn_start_callback, churn_ctx);
2875 } 2904 }
2905
2906 GNUNET_free(running_arr);
2907 GNUNET_free(stopped_arr);
2908 GNUNET_free_non_null(running_permute);
2909 GNUNET_free_non_null(stopped_permute);
2876} 2910}
2877 2911
2878 2912