aboutsummaryrefslogtreecommitdiff
path: root/src/testing/testing_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_group.c')
-rw-r--r--src/testing/testing_group.c1195
1 files changed, 1110 insertions, 85 deletions
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index e617bc113..e9bc05a74 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -50,6 +50,57 @@
50 50
51#define CONNECT_ATTEMPTS 8 51#define CONNECT_ATTEMPTS 8
52 52
53/**
54 * Prototype of a function called whenever two peers would be connected
55 * in a certain topology.
56 */
57typedef int (*GNUNET_TESTING_ConnectionProcessor)
58(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second);
59
60struct RestartContext
61{
62 /**
63 * The group of peers being restarted
64 */
65 struct GNUNET_TESTING_PeerGroup *peer_group;
66
67 /**
68 * How many peers have been restarted thus far
69 */
70 unsigned int peers_restarted;
71
72 /**
73 * How many peers got an error when restarting
74 */
75 unsigned int peers_restart_failed;
76
77 /**
78 * The function to call once all peers have been restarted
79 */
80 GNUNET_TESTING_NotifyCompletion callback;
81
82 /**
83 * Closure for callback function
84 */
85 void *callback_cls;
86
87};
88
89struct CreateTopologyContext
90{
91
92 /**
93 * Function to call with number of connections
94 */
95 GNUNET_TESTING_NotifyConnections cont;
96
97 /**
98 * Closure for connection notification
99 */
100 void *cls;
101};
102
103#if OLD
53struct PeerConnection 104struct PeerConnection
54{ 105{
55 /* 106 /*
@@ -63,6 +114,7 @@ struct PeerConnection
63 struct GNUNET_TESTING_Daemon *daemon; 114 struct GNUNET_TESTING_Daemon *daemon;
64 115
65}; 116};
117#endif
66 118
67/** 119/**
68 * Data we keep per peer. 120 * Data we keep per peer.
@@ -83,9 +135,33 @@ struct PeerData
83 struct GNUNET_TESTING_Daemon *daemon; 135 struct GNUNET_TESTING_Daemon *daemon;
84 136
85 /** 137 /**
86 * Linked list of peer connections (simply indexes of PeerGroup) 138 * The peergroup this peer belongs to.
139 */
140 struct GNUNET_TESTING_PeerGroup *pg;
141
142 /**
143 * Linked list of peer connections (pointers)
144 */
145 //struct PeerConnection *connected_peers;
146 /**
147 * Hash map of allowed peer connections (F2F created topology)
148 */
149 struct GNUNET_CONTAINER_MultiHashMap *allowed_peers;
150
151 /**
152 * Hash map of blacklisted peers
153 */
154 struct GNUNET_CONTAINER_MultiHashMap *blacklisted_peers;
155
156 /**
157 * Hash map of peer connections
158 */
159 struct GNUNET_CONTAINER_MultiHashMap *connect_peers;
160
161 /**
162 * Temporary hash map of peer connections
87 */ 163 */
88 struct PeerConnection *connected_peers; 164 struct GNUNET_CONTAINER_MultiHashMap *connect_peers_working_set;
89 165
90 /** 166 /**
91 * Total number of connections this peer has 167 * Total number of connections this peer has
@@ -165,6 +241,31 @@ struct GNUNET_TESTING_PeerGroup
165 241
166}; 242};
167 243
244/**
245 * Convert unique ID to hash code.
246 *
247 * @param uid unique ID to convert
248 * @param hash set to uid (extended with zeros)
249 */
250static void
251hash_from_uid (uint32_t uid,
252 GNUNET_HashCode *hash)
253{
254 memset (hash, 0, sizeof(GNUNET_HashCode));
255 *((uint32_t*)hash) = uid;
256}
257
258/**
259 * Convert hash code to unique ID.
260 *
261 * @param uid unique ID to convert
262 * @param hash set to uid (extended with zeros)
263 */
264static void
265uid_from_hash (const GNUNET_HashCode *hash, uint32_t *uid)
266{
267 memcpy (uid, hash, sizeof(uint32_t));
268}
168 269
169struct UpdateContext 270struct UpdateContext
170{ 271{
@@ -279,41 +380,107 @@ make_config (const struct GNUNET_CONFIGURATION_Handle *cfg, uint16_t * port, con
279 return uc.ret; 380 return uc.ret;
280} 381}
281 382
383
282/* 384/*
283 * Add entries to the peers connected list 385 * Add entries to the peers connect list
284 * 386 *
285 * @param pg the peer group we are working with 387 * @param pg the peer group we are working with
286 * @param first index of the first peer 388 * @param first index of the first peer
287 * @param second index of the second peer 389 * @param second index of the second peer
288 * 390 *
289 * @return the number of connections added (can be 0, 1 or 2) 391 * @return the number of connections added (can be 0, 1 or 2)
392 * technically should only be 0 or 2, but the small price
393 * of iterating over the lists (hashmaps in the future)
394 * for being sure doesn't bother me!
395 *
396 */
397static int
398add_actual_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second)
399{
400 int added;
401 int add_first;
402 int add_second;
403
404 GNUNET_HashCode hash_first;
405 GNUNET_HashCode hash_second;
406
407 hash_from_uid(first, &hash_first);
408 hash_from_uid(second, &hash_second);
409
410 add_first = GNUNET_NO;
411 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(pg->peers[first].connect_peers, &hash_second))
412 {
413 add_first = GNUNET_YES;
414 }
415
416 add_second = GNUNET_NO;
417 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(pg->peers[second].connect_peers, &hash_first))
418 {
419 add_second = GNUNET_YES;
420 }
421
422 added = 0;
423 if (add_first)
424 {
425 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(pg->peers[first].connect_peers, &hash_second, pg->peers[second].daemon, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
426 added++;
427 }
428
429 if (add_second)
430 {
431 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(pg->peers[second].connect_peers, &hash_first, pg->peers[first].daemon, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
432 added++;
433 }
434
435 return added;
436}
437
438
439/*
440 * Add entries to the peers allowed connections list
290 * 441 *
291 * FIXME: add both, or only add one? 442 * @param pg the peer group we are working with
292 * - if both are added, then we have to keep track 443 * @param first index of the first peer
293 * when connecting so we don't double connect 444 * @param second index of the second peer
294 * - if only one is added, we need to iterate over
295 * both lists to find out if connection already exists
296 * - having both allows the whitelisting/friend file
297 * creation to be easier
298 * 445 *
299 * -- For now, add both, we have to iterate over each to 446 * @return the number of connections added (can be 0, 1 or 2)
300 * check for duplicates anyways, so we'll take the performance 447 * technically should only be 0 or 2, but the small price
301 * hit assuming we don't have __too__ many connections 448 * of iterating over the lists (hashmaps in the future)
449 * for being sure doesn't bother me!
302 * 450 *
303 */ 451 */
304static int 452static int
305add_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second) 453add_allowed_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second)
306{ 454{
307 int added; 455 int added;
456#if OLD
308 struct PeerConnection *first_iter; 457 struct PeerConnection *first_iter;
309 struct PeerConnection *second_iter; 458 struct PeerConnection *second_iter;
310 int add_first;
311 int add_second;
312 struct PeerConnection *new_first; 459 struct PeerConnection *new_first;
313 struct PeerConnection *new_second; 460 struct PeerConnection *new_second;
461#endif
462 int add_first;
463 int add_second;
464
465 GNUNET_HashCode hash_first;
466 GNUNET_HashCode hash_second;
314 467
468 hash_from_uid(first, &hash_first);
469 hash_from_uid(second, &hash_second);
470
471 add_first = GNUNET_NO;
472 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(pg->peers[first].allowed_peers, &hash_second))
473 {
474 add_first = GNUNET_YES;
475 }
476
477 add_second = GNUNET_NO;
478 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(pg->peers[second].allowed_peers, &hash_first))
479 {
480 add_second = GNUNET_YES;
481 }
482#if OLD
315 first_iter = pg->peers[first].connected_peers; 483 first_iter = pg->peers[first].connected_peers;
316 add_first = GNUNET_YES;
317 while (first_iter != NULL) 484 while (first_iter != NULL)
318 { 485 {
319 if (first_iter->daemon == pg->peers[second].daemon) 486 if (first_iter->daemon == pg->peers[second].daemon)
@@ -329,31 +496,129 @@ add_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigne
329 add_second = GNUNET_NO; 496 add_second = GNUNET_NO;
330 second_iter = second_iter->next; 497 second_iter = second_iter->next;
331 } 498 }
499#endif
332 500
333 added = 0; 501 added = 0;
334 if (add_first) 502 if (add_first)
335 { 503 {
504 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(pg->peers[first].allowed_peers, &hash_second, pg->peers[second].daemon, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
505#if OLD
336 new_first = GNUNET_malloc(sizeof(struct PeerConnection)); 506 new_first = GNUNET_malloc(sizeof(struct PeerConnection));
337 new_first->daemon = pg->peers[second].daemon; 507 new_first->daemon = pg->peers[second].daemon;
338 new_first->next = pg->peers[first].connected_peers; 508 new_first->next = pg->peers[first].connected_peers;
339 pg->peers[first].connected_peers = new_first; 509 pg->peers[first].connected_peers = new_first;
340 pg->peers[first].num_connections++; 510 pg->peers[first].num_connections++;
511#endif
341 added++; 512 added++;
342 } 513 }
343 514
344 if (add_second) 515 if (add_second)
345 { 516 {
517 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(pg->peers[second].allowed_peers, &hash_first, pg->peers[first].daemon, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
518#if OLD
346 new_second = GNUNET_malloc(sizeof(struct PeerConnection)); 519 new_second = GNUNET_malloc(sizeof(struct PeerConnection));
347 new_second->daemon = pg->peers[first].daemon; 520 new_second->daemon = pg->peers[first].daemon;
348 new_second->next = pg->peers[second].connected_peers; 521 new_second->next = pg->peers[second].connected_peers;
349 pg->peers[second].connected_peers = new_second; 522 pg->peers[second].connected_peers = new_second;
350 pg->peers[first].num_connections++; 523 pg->peers[first].num_connections++;
524#endif
351 added++; 525 added++;
352 } 526 }
353 527
354 return added; 528 return added;
355} 529}
356 530
531/*
532 * Add entries to the peers blacklisted list
533 *
534 * @param pg the peer group we are working with
535 * @param first index of the first peer
536 * @param second index of the second peer
537 *
538 * @return the number of connections added (can be 0, 1 or 2)
539 *
540 */
541static int
542blacklist_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second)
543{
544 int added;
545 int add_first;
546 int add_second;
547 GNUNET_HashCode hash_first;
548 GNUNET_HashCode hash_second;
549
550 hash_from_uid(first, &hash_first);
551 hash_from_uid(second, &hash_second);
552
553 add_first = GNUNET_NO;
554 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(pg->peers[first].blacklisted_peers, &hash_second))
555 {
556 add_first = GNUNET_YES;
557 }
558
559 add_second = GNUNET_NO;
560 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(pg->peers[second].blacklisted_peers, &hash_first))
561 {
562 add_second = GNUNET_YES;
563 }
564
565 added = 0;
566 if (add_first)
567 {
568 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(pg->peers[first].blacklisted_peers, &hash_second, pg->peers[second].daemon, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
569 added++;
570 }
571
572 if (add_second)
573 {
574 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(pg->peers[second].blacklisted_peers, &hash_first, pg->peers[first].daemon, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
575 added++;
576 }
577
578 return added;
579}
580
581/*
582 * Remove entries from the peers blacklisted list
583 *
584 * @param pg the peer group we are working with
585 * @param first index of the first peer
586 * @param second index of the second peer
587 *
588 * @return the number of connections removed (can be 0, 1 or 2)
589 *
590 */
591static int
592unblacklist_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second)
593{
594 int removed;
595 int remove_first;
596 int remove_second;
597 GNUNET_HashCode hash_first;
598 GNUNET_HashCode hash_second;
599
600 hash_from_uid(first, &hash_first);
601 hash_from_uid(second, &hash_second);
602
603 remove_first = GNUNET_CONTAINER_multihashmap_contains(pg->peers[first].blacklisted_peers, &hash_second);
604 remove_second = GNUNET_CONTAINER_multihashmap_contains(pg->peers[second].blacklisted_peers, &hash_first);
605
606 removed = 0;
607 if (remove_first)
608 {
609 GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(pg->peers[first].blacklisted_peers, &hash_second, pg->peers[second].daemon));
610 removed++;
611 }
612
613 if (remove_second)
614 {
615 GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(pg->peers[second].blacklisted_peers, &hash_first, pg->peers[first].daemon));
616 removed++;
617 }
618
619 return removed;
620}
621
357/** 622/**
358 * Scale free network construction as described in: 623 * Scale free network construction as described in:
359 * 624 *
@@ -369,7 +634,7 @@ add_connections(struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigne
369 * @return the number of connections created 634 * @return the number of connections created
370 */ 635 */
371static int 636static int
372create_scale_free (struct GNUNET_TESTING_PeerGroup *pg) 637create_scale_free (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
373{ 638{
374 639
375 unsigned int total_connections; 640 unsigned int total_connections;
@@ -382,7 +647,7 @@ create_scale_free (struct GNUNET_TESTING_PeerGroup *pg)
382 GNUNET_assert(pg->total > 1); 647 GNUNET_assert(pg->total > 1);
383 648
384 /* Add a connection between the first two nodes */ 649 /* Add a connection between the first two nodes */
385 total_connections = add_connections(pg, 0, 1); 650 total_connections = proc(pg, 0, 1);
386 651
387 for (outer_count = 1; outer_count < pg->total; outer_count++) 652 for (outer_count = 1; outer_count < pg->total; outer_count++)
388 { 653 {
@@ -404,7 +669,7 @@ create_scale_free (struct GNUNET_TESTING_PeerGroup *pg)
404 "Connecting peer %d to peer %d\n", 669 "Connecting peer %d to peer %d\n",
405 outer_count, i); 670 outer_count, i);
406#endif 671#endif
407 total_connections += add_connections(pg, outer_count, i); 672 total_connections += proc(pg, outer_count, i);
408 } 673 }
409 } 674 }
410 } 675 }
@@ -413,7 +678,7 @@ create_scale_free (struct GNUNET_TESTING_PeerGroup *pg)
413} 678}
414 679
415int 680int
416create_small_world_ring(struct GNUNET_TESTING_PeerGroup *pg) 681create_small_world_ring(struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
417{ 682{
418 unsigned int i, j; 683 unsigned int i, j;
419 int nodeToConnect; 684 int nodeToConnect;
@@ -502,7 +767,7 @@ create_small_world_ring(struct GNUNET_TESTING_PeerGroup *pg)
502 pg->total); 767 pg->total);
503 } 768 }
504 smallWorldConnections += 769 smallWorldConnections +=
505 add_connections (pg, i, randomPeer); 770 proc (pg, i, randomPeer);
506 } 771 }
507 else 772 else
508 { 773 {
@@ -512,7 +777,7 @@ create_small_world_ring(struct GNUNET_TESTING_PeerGroup *pg)
512 nodeToConnect = nodeToConnect - pg->total; 777 nodeToConnect = nodeToConnect - pg->total;
513 } 778 }
514 connect_attempts += 779 connect_attempts +=
515 add_connections (pg, i, nodeToConnect); 780 proc (pg, i, nodeToConnect);
516 } 781 }
517 } 782 }
518 783
@@ -525,7 +790,7 @@ create_small_world_ring(struct GNUNET_TESTING_PeerGroup *pg)
525 790
526 791
527static int 792static int
528create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg) 793create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
529{ 794{
530 unsigned int outer_count, inner_count; 795 unsigned int outer_count, inner_count;
531 unsigned int cutoff; 796 unsigned int cutoff;
@@ -566,7 +831,7 @@ create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg)
566 "Connecting peer %d to peer %d\n", 831 "Connecting peer %d to peer %d\n",
567 outer_count, inner_count); 832 outer_count, inner_count);
568#endif 833#endif
569 connect_attempts += add_connections(pg, outer_count, inner_count); 834 connect_attempts += proc(pg, outer_count, inner_count);
570 } 835 }
571 } 836 }
572 } 837 }
@@ -578,7 +843,7 @@ create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg)
578 843
579 844
580static int 845static int
581create_small_world (struct GNUNET_TESTING_PeerGroup *pg) 846create_small_world (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
582{ 847{
583 unsigned int i, j, k; 848 unsigned int i, j, k;
584 unsigned int square; 849 unsigned int square;
@@ -662,7 +927,7 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg)
662 else 927 else
663 nodeToConnect = i - cols + 1; 928 nodeToConnect = i - cols + 1;
664 929
665 connect_attempts += add_connections (pg, i, nodeToConnect); 930 connect_attempts += proc (pg, i, nodeToConnect);
666 931
667 if (i < cols) 932 if (i < cols)
668 nodeToConnect = (rows * cols) - cols + i; 933 nodeToConnect = (rows * cols) - cols + i;
@@ -670,7 +935,7 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg)
670 nodeToConnect = i - cols; 935 nodeToConnect = i - cols;
671 936
672 if (nodeToConnect < pg->total) 937 if (nodeToConnect < pg->total)
673 connect_attempts += add_connections (pg, i, nodeToConnect); 938 connect_attempts += proc (pg, i, nodeToConnect);
674 } 939 }
675 natLog = log (pg->total); 940 natLog = log (pg->total);
676#if VERBOSE_TESTING > 2 941#if VERBOSE_TESTING > 2
@@ -703,7 +968,7 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg)
703 (uint64_t)-1LL)) / ( (double) (uint64_t) -1LL); 968 (uint64_t)-1LL)) / ( (double) (uint64_t) -1LL);
704 /* If random < probability, then connect the two nodes */ 969 /* If random < probability, then connect the two nodes */
705 if (random < probability) 970 if (random < probability)
706 smallWorldConnections += add_connections (pg, j, k); 971 smallWorldConnections += proc (pg, j, k);
707 972
708 } 973 }
709 } 974 }
@@ -721,7 +986,7 @@ create_small_world (struct GNUNET_TESTING_PeerGroup *pg)
721 986
722 987
723static int 988static int
724create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg) 989create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
725{ 990{
726 double temp_rand; 991 double temp_rand;
727 unsigned int outer_count; 992 unsigned int outer_count;
@@ -759,7 +1024,7 @@ create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg)
759#endif 1024#endif
760 if (temp_rand < probability) 1025 if (temp_rand < probability)
761 { 1026 {
762 connect_attempts += add_connections (pg, outer_count, inner_count); 1027 connect_attempts += proc (pg, outer_count, inner_count);
763 } 1028 }
764 } 1029 }
765 } 1030 }
@@ -768,7 +1033,7 @@ create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg)
768} 1033}
769 1034
770static int 1035static int
771create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg) 1036create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
772{ 1037{
773 unsigned int i; 1038 unsigned int i;
774 unsigned int square; 1039 unsigned int square;
@@ -820,7 +1085,7 @@ create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg)
820 "Connecting peer %d to peer %d\n", 1085 "Connecting peer %d to peer %d\n",
821 i, nodeToConnect); 1086 i, nodeToConnect);
822#endif 1087#endif
823 connect_attempts += add_connections(pg, i, nodeToConnect); 1088 connect_attempts += proc(pg, i, nodeToConnect);
824 1089
825 /* Second connect to the node immediately above */ 1090 /* Second connect to the node immediately above */
826 if (i < cols) 1091 if (i < cols)
@@ -835,7 +1100,7 @@ create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg)
835 "Connecting peer %d to peer %d\n", 1100 "Connecting peer %d to peer %d\n",
836 i, nodeToConnect); 1101 i, nodeToConnect);
837#endif 1102#endif
838 connect_attempts += add_connections(pg, i, nodeToConnect); 1103 connect_attempts += proc(pg, i, nodeToConnect);
839 } 1104 }
840 1105
841 } 1106 }
@@ -846,7 +1111,7 @@ create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg)
846 1111
847 1112
848static int 1113static int
849create_clique (struct GNUNET_TESTING_PeerGroup *pg) 1114create_clique (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
850{ 1115{
851 unsigned int outer_count; 1116 unsigned int outer_count;
852 unsigned int inner_count; 1117 unsigned int inner_count;
@@ -864,7 +1129,7 @@ create_clique (struct GNUNET_TESTING_PeerGroup *pg)
864 "Connecting peer %d to peer %d\n", 1129 "Connecting peer %d to peer %d\n",
865 outer_count, inner_count); 1130 outer_count, inner_count);
866#endif 1131#endif
867 connect_attempts += add_connections(pg, outer_count, inner_count); 1132 connect_attempts += proc(pg, outer_count, inner_count);
868 } 1133 }
869 } 1134 }
870 1135
@@ -873,7 +1138,7 @@ create_clique (struct GNUNET_TESTING_PeerGroup *pg)
873 1138
874 1139
875static int 1140static int
876create_ring (struct GNUNET_TESTING_PeerGroup *pg) 1141create_ring (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_ConnectionProcessor proc)
877{ 1142{
878 unsigned int count; 1143 unsigned int count;
879 int connect_attempts; 1144 int connect_attempts;
@@ -888,16 +1153,77 @@ create_ring (struct GNUNET_TESTING_PeerGroup *pg)
888 "Connecting peer %d to peer %d\n", 1153 "Connecting peer %d to peer %d\n",
889 count, count + 1); 1154 count, count + 1);
890#endif 1155#endif
891 connect_attempts += add_connections(pg, count, count + 1); 1156 connect_attempts += proc(pg, count, count + 1);
892 } 1157 }
893 1158
894 /* Connect the last peer to the first peer */ 1159 /* Connect the last peer to the first peer */
895 connect_attempts += add_connections(pg, pg->total - 1, 0); 1160 connect_attempts += proc(pg, pg->total - 1, 0);
896 1161
897 return connect_attempts; 1162 return connect_attempts;
898} 1163}
899 1164
900 1165
1166/**
1167 * Iterator for writing friends of a peer to a file.
1168 *
1169 * @param cls closure, an open writable file handle
1170 * @param key the key the daemon was stored under
1171 * @param value the GNUNET_TESTING_Daemon that needs to be written.
1172 *
1173 * @return GNUNET_YES to continue iteration
1174 *
1175 * TODO: Could replace friend_file_iterator and blacklist_file_iterator
1176 * with a single file_iterator that takes a closure which contains
1177 * the prefix to write before the peer. Then this could be used
1178 * for blacklisting multiple transports and writing the friend
1179 * file. I'm sure *someone* will complain loudly about other
1180 * things that negate these functions even existing so no point in
1181 * "fixing" now.
1182 */
1183static int
1184friend_file_iterator (void *cls,
1185 const GNUNET_HashCode * key,
1186 void *value)
1187{
1188 FILE *temp_friend_handle = cls;
1189 struct GNUNET_TESTING_Daemon *peer = value;
1190 struct GNUNET_PeerIdentity *temppeer;
1191 struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc;
1192
1193 temppeer = &peer->id;
1194 GNUNET_CRYPTO_hash_to_enc(&temppeer->hashPubKey, &peer_enc);
1195 fprintf(temp_friend_handle, "%s\n", (char *)&peer_enc);
1196
1197 return GNUNET_YES;
1198}
1199
1200
1201/**
1202 * Iterator for writing blacklist data to appropriate files.
1203 *
1204 * @param cls closure, an open writable file handle
1205 * @param key the key the daemon was stored under
1206 * @param value the GNUNET_TESTING_Daemon that needs to be written.
1207 *
1208 * @return GNUNET_YES to continue iteration
1209 */
1210static int
1211blacklist_file_iterator (void *cls,
1212 const GNUNET_HashCode * key,
1213 void *value)
1214{
1215 FILE *temp_blacklist_handle = cls;
1216 struct GNUNET_TESTING_Daemon *peer = value;
1217 struct GNUNET_PeerIdentity *temppeer;
1218 struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc;
1219
1220 temppeer = &peer->id;
1221 GNUNET_CRYPTO_hash_to_enc(&temppeer->hashPubKey, &peer_enc);
1222 fprintf(temp_blacklist_handle, "tcp:%s\n", (char *)&peer_enc);
1223
1224 return GNUNET_YES;
1225}
1226
901/* 1227/*
902 * Create the friend files based on the PeerConnection's 1228 * Create the friend files based on the PeerConnection's
903 * of each peer in the peer group, and copy the files 1229 * of each peer in the peer group, and copy the files
@@ -910,12 +1236,9 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg)
910{ 1236{
911 FILE *temp_friend_handle; 1237 FILE *temp_friend_handle;
912 unsigned int pg_iter; 1238 unsigned int pg_iter;
913 struct PeerConnection *connection_iter;
914 struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc;
915 char *temp_service_path; 1239 char *temp_service_path;
916 pid_t *pidarr; 1240 pid_t *pidarr;
917 char *arg; 1241 char *arg;
918 struct GNUNET_PeerIdentity *temppeer;
919 char * mytemp; 1242 char * mytemp;
920 enum GNUNET_OS_ProcessStatusType type; 1243 enum GNUNET_OS_ProcessStatusType type;
921 unsigned long return_code; 1244 unsigned long return_code;
@@ -927,16 +1250,10 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg)
927 for (pg_iter = 0; pg_iter < pg->total; pg_iter++) 1250 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
928 { 1251 {
929 mytemp = GNUNET_DISK_mktemp("friends"); 1252 mytemp = GNUNET_DISK_mktemp("friends");
1253 GNUNET_assert(mytemp != NULL);
930 temp_friend_handle = fopen (mytemp, "wt"); 1254 temp_friend_handle = fopen (mytemp, "wt");
931 connection_iter = pg->peers[pg_iter].connected_peers; 1255 GNUNET_assert(temp_friend_handle != NULL);
932 while (connection_iter != NULL) 1256 GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].allowed_peers, &friend_file_iterator, temp_friend_handle);
933 {
934 temppeer = &connection_iter->daemon->id;
935 GNUNET_CRYPTO_hash_to_enc(&temppeer->hashPubKey, &peer_enc);
936 fprintf(temp_friend_handle, "%s\n", (char *)&peer_enc);
937 connection_iter = connection_iter->next;
938 }
939
940 fclose(temp_friend_handle); 1257 fclose(temp_friend_handle);
941 1258
942 if (GNUNET_OK != 1259 if (GNUNET_OK !=
@@ -1029,6 +1346,130 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg)
1029 return ret; 1346 return ret;
1030} 1347}
1031 1348
1349
1350/*
1351 * Create the blacklist files based on the PeerConnection's
1352 * of each peer in the peer group, and copy the files
1353 * to the appropriate place.
1354 *
1355 * @param pg the peer group we are dealing with
1356 */
1357static int
1358create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg)
1359{
1360 FILE *temp_friend_handle;
1361 unsigned int pg_iter;
1362 char *temp_service_path;
1363 pid_t *pidarr;
1364 char *arg;
1365 char *mytemp;
1366 enum GNUNET_OS_ProcessStatusType type;
1367 unsigned long return_code;
1368 int count;
1369 int ret;
1370 int max_wait = 10;
1371
1372 pidarr = GNUNET_malloc(sizeof(pid_t) * pg->total);
1373 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
1374 {
1375 mytemp = GNUNET_DISK_mktemp("blacklist");
1376 GNUNET_assert(mytemp != NULL);
1377 temp_friend_handle = fopen (mytemp, "wt");
1378 GNUNET_assert(temp_friend_handle != NULL);
1379 GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].blacklisted_peers, &blacklist_file_iterator, temp_friend_handle);
1380 fclose(temp_friend_handle);
1381
1382 if (GNUNET_OK !=
1383 GNUNET_CONFIGURATION_get_value_string(pg->peers[pg_iter].daemon->cfg, "PATHS", "SERVICEHOME", &temp_service_path))
1384 {
1385 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1386 _("No `%s' specified in peer configuration in section `%s', cannot copy friends file!\n"),
1387 "SERVICEHOME",
1388 "PATHS");
1389 if (UNLINK (mytemp) != 0)
1390 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", mytemp);
1391 GNUNET_free (mytemp);
1392 break;
1393 }
1394
1395 if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */
1396 {
1397 GNUNET_asprintf (&arg, "%s/blacklist", temp_service_path);
1398 pidarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "mv",
1399 "mv", mytemp, arg, NULL);
1400#if VERBOSE_TESTING
1401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1402 _("Copying file with command cp %s %s\n"), mytemp, arg);
1403#endif
1404
1405 GNUNET_free(arg);
1406 }
1407 else /* Remote, scp the file to the correct place */
1408 {
1409 if (NULL != pg->peers[pg_iter].daemon->username)
1410 GNUNET_asprintf (&arg, "%s@%s:%s/blacklist", pg->peers[pg_iter].daemon->username, pg->peers[pg_iter].daemon->hostname, temp_service_path);
1411 else
1412 GNUNET_asprintf (&arg, "%s:%s/blacklist", pg->peers[pg_iter].daemon->hostname, temp_service_path);
1413 pidarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "scp",
1414 "scp", mytemp, arg, NULL);
1415
1416#if VERBOSE_TESTING
1417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1418 _("Copying file with command scp %s %s\n"), mytemp, arg);
1419#endif
1420 GNUNET_free(arg);
1421 }
1422 GNUNET_free (temp_service_path);
1423 GNUNET_free (mytemp);
1424 }
1425
1426 count = 0;
1427 ret = GNUNET_SYSERR;
1428 while ((count < max_wait) && (ret != GNUNET_OK))
1429 {
1430 ret = GNUNET_OK;
1431 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
1432 {
1433#if VERBOSE_TESTING
1434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1435 _("Checking copy status of file %d\n"), pg_iter);
1436#endif
1437 if (pidarr[pg_iter] != 0) /* Check for already completed! */
1438 {
1439 if (GNUNET_OS_process_status(pidarr[pg_iter], &type, &return_code) != GNUNET_OK)
1440 {
1441 ret = GNUNET_SYSERR;
1442 }
1443 else if ((type != GNUNET_OS_PROCESS_EXITED) || (return_code != 0))
1444 {
1445 ret = GNUNET_SYSERR;
1446 }
1447 else
1448 {
1449 pidarr[pg_iter] = 0;
1450#if VERBOSE_TESTING
1451 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1452 _("File %d copied\n"), pg_iter);
1453#endif
1454 }
1455 }
1456 }
1457 count++;
1458 if (ret == GNUNET_SYSERR)
1459 {
1460 sleep(1);
1461 }
1462 }
1463
1464#if VERBOSE_TESTING
1465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1466 _("Finished copying all blacklist files!\n"));
1467#endif
1468 GNUNET_free(pidarr);
1469 return ret;
1470}
1471
1472
1032/** 1473/**
1033 * Internal notification of a connection, kept so that we can ensure some connections 1474 * Internal notification of a connection, kept so that we can ensure some connections
1034 * happen instead of flooding all testing daemons with requests to connect. 1475 * happen instead of flooding all testing daemons with requests to connect.
@@ -1081,54 +1522,154 @@ static void schedule_connect(void *cls, const struct GNUNET_SCHEDULER_TaskContex
1081 } 1522 }
1082} 1523}
1083 1524
1525/**
1526 * Iterator for actually scheduling connections to be created
1527 * between two peers.
1528 *
1529 * @param cls closure, a GNUNET_TESTING_Daemon
1530 * @param key the key the second Daemon was stored under
1531 * @param value the GNUNET_TESTING_Daemon that the first is to connect to
1532 *
1533 * @return GNUNET_YES to continue iteration
1534 */
1535static int
1536connect_iterator (void *cls,
1537 const GNUNET_HashCode * key,
1538 void *value)
1539{
1540 struct PeerData *first = cls;
1541 struct GNUNET_TESTING_Daemon *second = value;
1542 struct ConnectContext *connect_context;
1543
1544 connect_context = GNUNET_malloc(sizeof(struct ConnectContext));
1545 connect_context->pg = first->pg;
1546 connect_context->first = first->daemon;
1547 connect_context->second = second;
1548 GNUNET_SCHEDULER_add_now(first->pg->sched, &schedule_connect, connect_context);
1549
1550 return GNUNET_YES;
1551}
1552
1553/**
1554 * Iterator for copying all entries in the allowed hashmap to the
1555 * connect hashmap.
1556 *
1557 * @param cls closure, a GNUNET_TESTING_Daemon
1558 * @param key the key the second Daemon was stored under
1559 * @param value the GNUNET_TESTING_Daemon that the first is to connect to
1560 *
1561 * @return GNUNET_YES to continue iteration
1562 */
1563static int
1564copy_topology_iterator (void *cls,
1565 const GNUNET_HashCode * key,
1566 void *value)
1567{
1568 struct PeerData *first = cls;
1569
1570 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(first->connect_peers, key, value, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1571
1572 return GNUNET_YES;
1573}
1574
1575/**
1576 * Make the peers to connect the same as those that are allowed to be
1577 * connected.
1578 *
1579 * @param pg the peer group
1580 */
1581static int
1582copy_allowed_topology (struct GNUNET_TESTING_PeerGroup *pg)
1583{
1584 unsigned int pg_iter;
1585 int ret;
1586 int total;
1587
1588 total = 0;
1589 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
1590 {
1591 ret = GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].allowed_peers, &copy_topology_iterator, &pg->peers[pg_iter]);
1592 if (GNUNET_SYSERR == ret)
1593 return GNUNET_SYSERR;
1594
1595 total = total + ret;
1596 }
1597
1598 return total;
1599}
1600
1601
1084/* 1602/*
1085 * Connect the topology as specified by the PeerConnection's 1603 * Connect the topology as specified by the PeerConnection's
1086 * of each peer in the peer group 1604 * of each peer in the peer group
1087 * 1605 *
1088 * @param pg the peer group we are dealing with 1606 * @param pg the peer group we are dealing with
1607 *
1608 * @return the number of connections that will be attempted
1089 */ 1609 */
1090static void 1610static int
1091connect_topology (struct GNUNET_TESTING_PeerGroup *pg) 1611connect_topology (struct GNUNET_TESTING_PeerGroup *pg)
1092{ 1612{
1093 unsigned int pg_iter; 1613 unsigned int pg_iter;
1614 int ret;
1615 int total;
1616#if OLD
1094 struct PeerConnection *connection_iter; 1617 struct PeerConnection *connection_iter;
1095 struct ConnectContext *connect_context; 1618 struct ConnectContext *connect_context;
1619#endif
1096 1620
1621 total = 0;
1097 for (pg_iter = 0; pg_iter < pg->total; pg_iter++) 1622 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
1098 { 1623 {
1099 connection_iter = pg->peers[pg_iter].connected_peers; 1624 ret = GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].connect_peers, &connect_iterator, &pg->peers[pg_iter]);
1625 if (GNUNET_SYSERR == ret)
1626 return GNUNET_SYSERR;
1627
1628 total = total + ret;
1629
1630#if OLD
1631 connection_iter = ;
1100 while (connection_iter != NULL) 1632 while (connection_iter != NULL)
1101 { 1633 {
1102 connect_context = GNUNET_malloc(sizeof(struct ConnectContext)); 1634 connect_context = GNUNET_malloc(sizeof(struct ConnectContext));
1103 connect_context->pg = pg; 1635 connect_context->pg = pg;
1104 connect_context->first = pg->peers[pg_iter].daemon; 1636 connect_context->first = ;
1105 connect_context->second = connection_iter->daemon; 1637 connect_context->second = connection_iter->daemon;
1106 GNUNET_SCHEDULER_add_now(pg->sched, &schedule_connect, connect_context); 1638 GNUNET_SCHEDULER_add_now(pg->sched, &schedule_connect, connect_context);
1107 connection_iter = connection_iter->next; 1639 connection_iter = connection_iter->next;
1108 } 1640 }
1641#endif
1109 } 1642 }
1643 return total;
1110} 1644}
1111 1645
1112 1646
1113/* 1647/*
1114 * Takes a peer group and attempts to create a topology based on the 1648 * Takes a peer group and creates a topology based on the
1115 * one specified in the configuration file. Returns the number of connections 1649 * one specified. Creates a topology means generates friend
1116 * that will attempt to be created, but this will happen asynchronously(?) so 1650 * files for the peers so they can only connect to those allowed
1117 * the caller will have to keep track (via the callback) of whether or not 1651 * by the topology. This will only have an effect once peers
1118 * the connection actually happened. 1652 * are started if the FRIENDS_ONLY option is set in the base
1653 * config. Also takes an optional restrict topology which
1654 * disallows direct TCP connections UNLESS they are specified in
1655 * the restricted topology.
1119 * 1656 *
1120 * @param pg the peer group struct representing the running peers 1657 * @param pg the peer group struct representing the running peers
1121 * @param topology which topology to connect the peers in 1658 * @param topology which topology to connect the peers in
1659 * @param restrict_topology allow only direct TCP connections in this topology
1660 * use GNUNET_TESTING_TOPOLOGY_NONE for no restrictions
1122 * 1661 *
1123 * @return the number of connections should be created by the topology, so the 1662 * @return the maximum number of connections were all allowed peers
1124 * caller knows how many to wait for (if it so chooses) 1663 * connected to each other
1125 *
1126 */ 1664 */
1127int 1665int
1128GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, enum GNUNET_TESTING_Topology topology) 1666GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg,
1667 enum GNUNET_TESTING_Topology topology,
1668 enum GNUNET_TESTING_Topology restrict_topology)
1129{ 1669{
1130 int ret; 1670 int ret;
1131 int num_connections; 1671 int num_connections;
1672 int unblacklisted_connections;
1132 1673
1133 GNUNET_assert (pg->notify_connection != NULL); 1674 GNUNET_assert (pg->notify_connection != NULL);
1134 ret = GNUNET_OK; 1675 ret = GNUNET_OK;
@@ -1140,56 +1681,56 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, enum GNUNET
1140 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1141 _("Creating clique topology\n")); 1682 _("Creating clique topology\n"));
1142#endif 1683#endif
1143 num_connections = create_clique (pg); 1684 num_connections = create_clique (pg, &add_allowed_connections);
1144 break; 1685 break;
1145 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: 1686 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING:
1146#if VERBOSE_TESTING 1687#if VERBOSE_TESTING
1147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1148 _("Creating small world (ring) topology\n")); 1689 _("Creating small world (ring) topology\n"));
1149#endif 1690#endif
1150 num_connections = create_small_world_ring (pg); 1691 num_connections = create_small_world_ring (pg, &add_allowed_connections);
1151 break; 1692 break;
1152 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: 1693 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD:
1153#if VERBOSE_TESTING 1694#if VERBOSE_TESTING
1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1695 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1155 _("Creating small world (2d-torus) topology\n")); 1696 _("Creating small world (2d-torus) topology\n"));
1156#endif 1697#endif
1157 num_connections = create_small_world (pg); 1698 num_connections = create_small_world (pg, &add_allowed_connections);
1158 break; 1699 break;
1159 case GNUNET_TESTING_TOPOLOGY_RING: 1700 case GNUNET_TESTING_TOPOLOGY_RING:
1160#if VERBOSE_TESTING 1701#if VERBOSE_TESTING
1161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1162 _("Creating ring topology\n")); 1703 _("Creating ring topology\n"));
1163#endif 1704#endif
1164 num_connections = create_ring (pg); 1705 num_connections = create_ring (pg, &add_allowed_connections);
1165 break; 1706 break;
1166 case GNUNET_TESTING_TOPOLOGY_2D_TORUS: 1707 case GNUNET_TESTING_TOPOLOGY_2D_TORUS:
1167#if VERBOSE_TESTING 1708#if VERBOSE_TESTING
1168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1169 _("Creating 2d torus topology\n")); 1710 _("Creating 2d torus topology\n"));
1170#endif 1711#endif
1171 num_connections = create_2d_torus (pg); 1712 num_connections = create_2d_torus (pg, &add_allowed_connections);
1172 break; 1713 break;
1173 case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: 1714 case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI:
1174#if VERBOSE_TESTING 1715#if VERBOSE_TESTING
1175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1176 _("Creating Erdos-Renyi topology\n")); 1717 _("Creating Erdos-Renyi topology\n"));
1177#endif 1718#endif
1178 num_connections = create_erdos_renyi (pg); 1719 num_connections = create_erdos_renyi (pg, &add_allowed_connections);
1179 break; 1720 break;
1180 case GNUNET_TESTING_TOPOLOGY_INTERNAT: 1721 case GNUNET_TESTING_TOPOLOGY_INTERNAT:
1181#if VERBOSE_TESTING 1722#if VERBOSE_TESTING
1182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1183 _("Creating InterNAT topology\n")); 1724 _("Creating InterNAT topology\n"));
1184#endif 1725#endif
1185 num_connections = create_nated_internet (pg); 1726 num_connections = create_nated_internet (pg, &add_allowed_connections);
1186 break; 1727 break;
1187 case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: 1728 case GNUNET_TESTING_TOPOLOGY_SCALE_FREE:
1188#if VERBOSE_TESTING 1729#if VERBOSE_TESTING
1189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1190 _("Creating Scale Free topology\n")); 1731 _("Creating Scale Free topology\n"));
1191#endif 1732#endif
1192 num_connections = create_scale_free (pg); 1733 num_connections = create_scale_free (pg, &add_allowed_connections);
1193 break; 1734 break;
1194 case GNUNET_TESTING_TOPOLOGY_NONE: 1735 case GNUNET_TESTING_TOPOLOGY_NONE:
1195 num_connections = 0; 1736 num_connections = 0;
@@ -1202,10 +1743,11 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, enum GNUNET
1202 return GNUNET_SYSERR; 1743 return GNUNET_SYSERR;
1203 1744
1204 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (pg->cfg, "TESTING", "F2F")) 1745 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (pg->cfg, "TESTING", "F2F"))
1205 ret = create_and_copy_friend_files(pg); 1746 {
1206 if (ret == GNUNET_OK) 1747 ret = create_and_copy_friend_files(pg);
1207 connect_topology(pg); 1748 }
1208 else 1749
1750 if (ret != GNUNET_OK)
1209 { 1751 {
1210#if VERBOSE_TESTING 1752#if VERBOSE_TESTING
1211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1753 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1213,10 +1755,419 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, enum GNUNET
1213#endif 1755#endif
1214 return GNUNET_SYSERR; 1756 return GNUNET_SYSERR;
1215 } 1757 }
1758 else
1759 {
1760#if VERBOSE_TESTING
1761 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1762 _("Friend files created/copied successfully!\n"));
1763#endif
1764 }
1765
1766 /**
1767 * Use the create clique method to initially set all connections
1768 * as blacklisted.
1769 */
1770 create_clique (pg, &blacklist_connections);
1771 unblacklisted_connections = 0;
1772 /**
1773 * Un-blacklist connections as per the topology specified
1774 */
1775 switch (restrict_topology)
1776 {
1777 case GNUNET_TESTING_TOPOLOGY_CLIQUE:
1778#if VERBOSE_TESTING
1779 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1780 _("Blacklisting all but clique topology\n"));
1781#endif
1782 unblacklisted_connections = create_clique (pg, &unblacklist_connections);
1783 break;
1784 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING:
1785#if VERBOSE_TESTING
1786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1787 _("Blacklisting all but small world (ring) topology\n"));
1788#endif
1789 unblacklisted_connections = create_small_world_ring (pg, &unblacklist_connections);
1790 break;
1791 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD:
1792#if VERBOSE_TESTING
1793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1794 _("Blacklisting all but small world (2d-torus) topology\n"));
1795#endif
1796 unblacklisted_connections = create_small_world (pg, &unblacklist_connections);
1797 break;
1798 case GNUNET_TESTING_TOPOLOGY_RING:
1799#if VERBOSE_TESTING
1800 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1801 _("Blacklisting all but ring topology\n"));
1802#endif
1803 unblacklisted_connections = create_ring (pg, &unblacklist_connections);
1804 break;
1805 case GNUNET_TESTING_TOPOLOGY_2D_TORUS:
1806#if VERBOSE_TESTING
1807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1808 _("Blacklisting all but 2d torus topology\n"));
1809#endif
1810 unblacklisted_connections = create_2d_torus (pg, &unblacklist_connections);
1811 break;
1812 case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI:
1813#if VERBOSE_TESTING
1814 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1815 _("Blacklisting all but Erdos-Renyi topology\n"));
1816#endif
1817 unblacklisted_connections = create_erdos_renyi (pg, &unblacklist_connections);
1818 break;
1819 case GNUNET_TESTING_TOPOLOGY_INTERNAT:
1820#if VERBOSE_TESTING
1821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1822 _("Blacklisting all but InterNAT topology\n"));
1823#endif
1824 unblacklisted_connections = create_nated_internet (pg, &unblacklist_connections);
1825 break;
1826 case GNUNET_TESTING_TOPOLOGY_SCALE_FREE:
1827#if VERBOSE_TESTING
1828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1829 _("Blacklisting all but Scale Free topology\n"));
1830#endif
1831 unblacklisted_connections = create_scale_free (pg, &unblacklist_connections);
1832 break;
1833 case GNUNET_TESTING_TOPOLOGY_NONE:
1834 /* Fall through */
1835 default:
1836 break;
1837 }
1838
1839 if (unblacklisted_connections > 0)
1840 {
1841 ret = create_and_copy_blacklist_files(pg);
1842 if (ret != GNUNET_OK)
1843 {
1844#if VERBOSE_TESTING
1845 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1846 _("Failed during blacklist file copying!\n"));
1847#endif
1848 return GNUNET_SYSERR;
1849 }
1850 else
1851 {
1852#if VERBOSE_TESTING
1853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1854 _("Blacklist files created/copied successfully!\n"));
1855#endif
1856 }
1857 }
1858
1216 1859
1217 return num_connections; 1860 return num_connections;
1218} 1861}
1219 1862
1863struct RandomContext
1864{
1865 /**
1866 * The peergroup
1867 */
1868 struct GNUNET_TESTING_PeerGroup *pg;
1869
1870 /**
1871 * uid of the first peer
1872 */
1873 uint32_t first_uid;
1874
1875 /**
1876 * Peer data for first peer.
1877 */
1878 struct PeerData *first;
1879
1880 /**
1881 * Random percentage to use
1882 */
1883 double percentage;
1884};
1885
1886struct MinimumContext
1887{
1888 /**
1889 * The peergroup
1890 */
1891 struct GNUNET_TESTING_PeerGroup *pg;
1892
1893 /**
1894 * uid of the first peer
1895 */
1896 uint32_t first_uid;
1897
1898 /**
1899 * Peer data for first peer.
1900 */
1901 struct PeerData *first;
1902
1903 /**
1904 * Number of conns per peer
1905 */
1906 unsigned int num_to_add;
1907};
1908
1909/**
1910 * Iterator for choosing random peers to connect.
1911 *
1912 * @param cls closure, a RandomContext
1913 * @param key the key the second Daemon was stored under
1914 * @param value the GNUNET_TESTING_Daemon that the first is to connect to
1915 *
1916 * @return GNUNET_YES to continue iteration
1917 */
1918static int
1919random_connect_iterator (void *cls,
1920 const GNUNET_HashCode * key,
1921 void *value)
1922{
1923 struct RandomContext *random_ctx = cls;
1924 double random_number;
1925 uint32_t second_pos;
1926 GNUNET_HashCode first_hash;
1927 random_number = ((double) GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK,
1928 (uint64_t)-1LL)) / ( (double) (uint64_t) -1LL);
1929 if (random_number < random_ctx->percentage)
1930 {
1931 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(random_ctx->first->connect_peers_working_set, key, value, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1932 }
1933 /* Now we have considered this particular connection, remove it from the second peer so it's not double counted */
1934 uid_from_hash(key, &second_pos);
1935 hash_from_uid(random_ctx->first_uid, &first_hash);
1936 GNUNET_assert(random_ctx->pg->total > second_pos);
1937 GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(random_ctx->pg->peers[second_pos].connect_peers, &first_hash, random_ctx->first->daemon));
1938
1939 return GNUNET_YES;
1940}
1941
1942/**
1943 * Iterator for adding at least X peers to a peers connection set.
1944 *
1945 * @param cls closure, MinimumContext
1946 * @param key the key the second Daemon was stored under
1947 * @param value the GNUNET_TESTING_Daemon that the first is to connect to
1948 *
1949 * @return GNUNET_YES to continue iteration
1950 */
1951static int
1952minimum_connect_iterator (void *cls,
1953 const GNUNET_HashCode * key,
1954 void *value)
1955{
1956 struct MinimumContext *min_ctx = cls;
1957 uint32_t second_pos;
1958 GNUNET_HashCode first_hash;
1959
1960 if (GNUNET_CONTAINER_multihashmap_size(min_ctx->first->connect_peers_working_set) < min_ctx->num_to_add)
1961 {
1962 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(min_ctx->first->connect_peers_working_set, key, value, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1963 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(min_ctx->first->connect_peers_working_set, key, value, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1964 /* Now we have added this particular connection, remove it from the second peer's map so it's not double counted */
1965 uid_from_hash(key, &second_pos);
1966 hash_from_uid(min_ctx->first_uid, &first_hash);
1967 GNUNET_assert(min_ctx->pg->total > second_pos);
1968 GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(min_ctx->pg->peers[second_pos].connect_peers, &first_hash, min_ctx->first->daemon));
1969 return GNUNET_YES;
1970 }
1971 else
1972 return GNUNET_NO; /* We can stop iterating, we have enough peers! */
1973
1974
1975}
1976
1977/**
1978 * From the set of connections possible, choose percentage percent of connections
1979 * to actually connect.
1980 *
1981 * @param pg the peergroup we are dealing with
1982 * @param percentage what percent of total connections to make
1983 */
1984void
1985choose_random_connections(struct GNUNET_TESTING_PeerGroup *pg, double percentage)
1986{
1987 struct RandomContext random_ctx;
1988 uint32_t pg_iter;
1989
1990 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
1991 {
1992 random_ctx.first_uid = pg_iter;
1993 random_ctx.first = &pg->peers[pg_iter];
1994 random_ctx.percentage = percentage;
1995 pg->peers[pg_iter].connect_peers_working_set = GNUNET_CONTAINER_multihashmap_create(pg->total);
1996 GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].connect_peers, &random_connect_iterator, &random_ctx);
1997 /* Now remove the old connections */
1998 GNUNET_CONTAINER_multihashmap_destroy(pg->peers[pg_iter].connect_peers);
1999 /* And replace with the random set */
2000 pg->peers[pg_iter].connect_peers = pg->peers[pg_iter].connect_peers_working_set;
2001 }
2002}
2003
2004/**
2005 * From the set of connections possible, choose at least num connections per
2006 * peer.
2007 *
2008 * @param pg the peergroup we are dealing with
2009 * @param num how many connections at least should each peer have (if possible)?
2010 */
2011void
2012choose_minimum(struct GNUNET_TESTING_PeerGroup *pg, unsigned int num)
2013{
2014 struct MinimumContext minimum_ctx;
2015 uint32_t pg_iter;
2016
2017 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
2018 {
2019 pg->peers[pg_iter].connect_peers_working_set = GNUNET_CONTAINER_multihashmap_create(num);
2020 }
2021
2022 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
2023 {
2024 minimum_ctx.first_uid = pg_iter;
2025 minimum_ctx.first = &pg->peers[pg_iter];
2026 minimum_ctx.num_to_add = num;
2027 pg->peers[pg_iter].connect_peers_working_set = GNUNET_CONTAINER_multihashmap_create(pg->total);
2028 GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].connect_peers, &minimum_connect_iterator, &minimum_ctx);
2029 }
2030
2031 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
2032 {
2033 /* Remove the "old" connections */
2034 GNUNET_CONTAINER_multihashmap_destroy(pg->peers[pg_iter].connect_peers);
2035 /* And replace with the working set */
2036 pg->peers[pg_iter].connect_peers = pg->peers[pg_iter].connect_peers_working_set;
2037 }
2038
2039}
2040
2041
2042/*
2043 * @param pg the peer group struct representing the running peers
2044 * @param topology which topology to connect the peers in
2045 * @param options options for connecting the topology
2046 * @param option_modifier modifier for options that take a parameter
2047 *
2048 * There are many ways to connect peers that are supported by this function.
2049 * To connect peers in the same topology that was created via the
2050 * GNUNET_TESTING_create_topology, the topology variable must be set to
2051 * GNUNET_TESTING_TOPOLOGY_NONE. If the topology variable is specified,
2052 * a new instance of that topology will be generated and attempted to be
2053 * connected. This could result in some connections being impossible,
2054 * because some topologies are non-deterministic.
2055 *
2056 */
2057int
2058GNUNET_TESTING_connect_topology (struct GNUNET_TESTING_PeerGroup *pg,
2059 enum GNUNET_TESTING_Topology topology,
2060 enum GNUNET_TESTING_TopologyOption options,
2061 double option_modifier)
2062{
2063 int num_connections;
2064
2065 switch (topology)
2066 {
2067 case GNUNET_TESTING_TOPOLOGY_CLIQUE:
2068 #if VERBOSE_TESTING
2069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2070 _("Creating clique topology\n"));
2071 #endif
2072 num_connections = create_clique (pg, &add_actual_connections);
2073 break;
2074 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING:
2075 #if VERBOSE_TESTING
2076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2077 _("Creating small world (ring) topology\n"));
2078 #endif
2079 num_connections = create_small_world_ring (pg, &add_actual_connections);
2080 break;
2081 case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD:
2082 #if VERBOSE_TESTING
2083 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2084 _("Creating small world (2d-torus) topology\n"));
2085 #endif
2086 num_connections = create_small_world (pg, &add_actual_connections);
2087 break;
2088 case GNUNET_TESTING_TOPOLOGY_RING:
2089 #if VERBOSE_TESTING
2090 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2091 _("Creating ring topology\n"));
2092 #endif
2093 num_connections = create_ring (pg, &add_actual_connections);
2094 break;
2095 case GNUNET_TESTING_TOPOLOGY_2D_TORUS:
2096 #if VERBOSE_TESTING
2097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2098 _("Creating 2d torus topology\n"));
2099 #endif
2100 num_connections = create_2d_torus (pg, &add_actual_connections);
2101 break;
2102 case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI:
2103 #if VERBOSE_TESTING
2104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2105 _("Creating Erdos-Renyi topology\n"));
2106 #endif
2107 num_connections = create_erdos_renyi (pg, &add_actual_connections);
2108 break;
2109 case GNUNET_TESTING_TOPOLOGY_INTERNAT:
2110 #if VERBOSE_TESTING
2111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2112 _("Creating InterNAT topology\n"));
2113 #endif
2114 num_connections = create_nated_internet (pg, &add_actual_connections);
2115 break;
2116 case GNUNET_TESTING_TOPOLOGY_SCALE_FREE:
2117 #if VERBOSE_TESTING
2118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2119 _("Creating Scale Free topology\n"));
2120 #endif
2121 num_connections = create_scale_free (pg, &add_actual_connections);
2122 break;
2123 case GNUNET_TESTING_TOPOLOGY_NONE:
2124 num_connections = copy_allowed_topology(pg);
2125 break;
2126 default:
2127 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Unknown topology specification, can't connect peers!\n");
2128 return GNUNET_SYSERR;
2129 }
2130
2131 switch (options)
2132 {
2133 case GNUNET_TESTING_TOPOLOGY_OPTION_RANDOM: /* Create a random subset of total connections based on parameter */
2134 choose_random_connections(pg, option_modifier);
2135 break;
2136 case GNUNET_TESTING_TOPOLOGY_OPTION_MINIMUM: /* Create at least X connections per peer (if possible!) */
2137 choose_minimum(pg, (unsigned int)option_modifier);
2138 break;
2139 case GNUNET_TESTING_TOPOLOGY_OPTION_DFS: /* Choose a random starting point, randomly walk graph, try to get each peer X connections */
2140 //choose_dfs(pg, (int)option_modifier);
2141 break;
2142 case GNUNET_TESTING_TOPOLOGY_OPTION_NONE:
2143 /* Fall through */
2144 case GNUNET_TESTING_TOPOLOGY_OPTION_ALL:
2145 /* Fall through */
2146 default:
2147 break;
2148 }
2149
2150 return connect_topology(pg);
2151}
2152
2153/**
2154 * Function which continues a peer group starting up
2155 * after successfully generating hostkeys for each peer.
2156 *
2157 * @param pg the peer group to continue starting
2158 *
2159 */
2160void
2161GNUNET_TESTING_daemons_continue_startup(struct GNUNET_TESTING_PeerGroup *pg)
2162{
2163 unsigned int i;
2164
2165 for (i = 0; i < pg->total; i++)
2166 {
2167 GNUNET_TESTING_daemon_continue_startup(pg->peers[i].daemon);
2168 }
2169}
2170
1220/** 2171/**
1221 * Start count gnunetd processes with the same set of transports and 2172 * Start count gnunetd processes with the same set of transports and
1222 * applications. The port numbers (any option called "PORT") will be 2173 * applications. The port numbers (any option called "PORT") will be
@@ -1226,6 +2177,11 @@ GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, enum GNUNET
1226 * @param sched scheduler to use 2177 * @param sched scheduler to use
1227 * @param cfg configuration template to use 2178 * @param cfg configuration template to use
1228 * @param total number of daemons to start 2179 * @param total number of daemons to start
2180 * @param hostkey_callback function to call on each peers hostkey generation
2181 * if NULL, peers will be started by this call, if non-null,
2182 * GNUNET_TESTING_daemons_continue_startup must be called after
2183 * successful hostkey generation
2184 * @param hostkey_cls closure for hostkey callback
1229 * @param cb function to call on each daemon that was started 2185 * @param cb function to call on each daemon that was started
1230 * @param cb_cls closure for cb 2186 * @param cb_cls closure for cb
1231 * @param connect_callback function to call each time two hosts are connected 2187 * @param connect_callback function to call each time two hosts are connected
@@ -1238,6 +2194,8 @@ struct GNUNET_TESTING_PeerGroup *
1238GNUNET_TESTING_daemons_start (struct GNUNET_SCHEDULER_Handle *sched, 2194GNUNET_TESTING_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
1239 const struct GNUNET_CONFIGURATION_Handle *cfg, 2195 const struct GNUNET_CONFIGURATION_Handle *cfg,
1240 unsigned int total, 2196 unsigned int total,
2197 GNUNET_TESTING_NotifyHostkeyCreated hostkey_callback,
2198 void *hostkey_cls,
1241 GNUNET_TESTING_NotifyDaemonRunning cb, 2199 GNUNET_TESTING_NotifyDaemonRunning cb,
1242 void *cb_cls, 2200 void *cb_cls,
1243 GNUNET_TESTING_NotifyConnection 2201 GNUNET_TESTING_NotifyConnection
@@ -1366,13 +2324,20 @@ GNUNET_TESTING_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
1366 "SERVICEHOME", newservicehome); 2324 "SERVICEHOME", newservicehome);
1367 GNUNET_free (newservicehome); 2325 GNUNET_free (newservicehome);
1368 pg->peers[off].cfg = pcfg; 2326 pg->peers[off].cfg = pcfg;
2327 pg->peers[off].allowed_peers = GNUNET_CONTAINER_multihashmap_create(total);
2328 pg->peers[off].connect_peers = GNUNET_CONTAINER_multihashmap_create(total);
2329 pg->peers[off].blacklisted_peers = GNUNET_CONTAINER_multihashmap_create(total);
2330 pg->peers[off].pg = pg;
1369 pg->peers[off].daemon = GNUNET_TESTING_daemon_start (sched, 2331 pg->peers[off].daemon = GNUNET_TESTING_daemon_start (sched,
1370 pcfg, 2332 pcfg,
1371 hostname, 2333 hostname,
2334 hostkey_callback,
2335 hostkey_cls,
1372 cb, cb_cls); 2336 cb, cb_cls);
1373 if (NULL == pg->peers[off].daemon) 2337 if (NULL == pg->peers[off].daemon)
1374 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2338 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1375 _("Could not start peer number %u!\n"), off); 2339 _("Could not start peer number %u!\n"), off);
2340
1376 } 2341 }
1377 return pg; 2342 return pg;
1378} 2343}
@@ -1391,6 +2356,72 @@ GNUNET_TESTING_daemon_get (struct GNUNET_TESTING_PeerGroup *pg, unsigned int pos
1391} 2356}
1392 2357
1393/** 2358/**
2359 * Prototype of a function that will be called when a
2360 * particular operation was completed the testing library.
2361 *
2362 * @param cls closure
2363 * @param emsg NULL on success
2364 */
2365void restart_callback (void *cls,
2366 const struct GNUNET_PeerIdentity *id,
2367 const struct GNUNET_CONFIGURATION_Handle *cfg,
2368 struct GNUNET_TESTING_Daemon *d,
2369 const char *emsg)
2370{
2371 struct RestartContext *restart_context = cls;
2372
2373 if (emsg == NULL)
2374 {
2375 restart_context->peers_restarted++;
2376 }
2377 else
2378 {
2379 restart_context->peers_restart_failed++;
2380 }
2381
2382 if (restart_context->peers_restarted == restart_context->peer_group->total)
2383 {
2384 restart_context->callback(restart_context->callback_cls, NULL);
2385 GNUNET_free(restart_context);
2386 }
2387 else if (restart_context->peers_restart_failed + restart_context->peers_restarted == restart_context->peer_group->total)
2388 {
2389 restart_context->callback(restart_context->callback_cls, "Failed to restart peers!");
2390 GNUNET_free(restart_context);
2391 }
2392
2393}
2394
2395/**
2396 * Restart all peers in the given group.
2397 *
2398 * @param pg the handle to the peer group
2399 * @param timeout how long to wait on failure
2400 * @param callback function to call on completion (or failure)
2401 * @param callback_cls closure for the callback function
2402 */
2403void
2404GNUNET_TESTING_daemons_restart (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_NotifyCompletion callback, void *callback_cls)
2405{
2406 struct RestartContext *restart_context;
2407 unsigned int off;
2408
2409 if (pg->total > 0)
2410 {
2411 restart_context = GNUNET_malloc(sizeof(struct RestartContext));
2412 restart_context->peer_group = pg;
2413 restart_context->peers_restarted = 0;
2414 restart_context->callback = callback;
2415 restart_context->callback_cls = callback_cls;
2416
2417 for (off = 0; off < pg->total; off++)
2418 {
2419 GNUNET_TESTING_daemon_restart (pg->peers[off].daemon, &restart_callback, restart_context);
2420 }
2421 }
2422}
2423
2424/**
1394 * Shutdown all peers started in the given group. 2425 * Shutdown all peers started in the given group.
1395 * 2426 *
1396 * @param pg handle to the peer group 2427 * @param pg handle to the peer group
@@ -1399,8 +2430,6 @@ void
1399GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg) 2430GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg)
1400{ 2431{
1401 unsigned int off; 2432 unsigned int off;
1402 struct PeerConnection *pos;
1403 struct PeerConnection *next;
1404 2433
1405 for (off = 0; off < pg->total; off++) 2434 for (off = 0; off < pg->total; off++)
1406 { 2435 {
@@ -1410,17 +2439,13 @@ GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg)
1410 as well... */ 2439 as well... */
1411 2440
1412 if (NULL != pg->peers[off].daemon) 2441 if (NULL != pg->peers[off].daemon)
1413 GNUNET_TESTING_daemon_stop (pg->peers[off].daemon, NULL, NULL); 2442 GNUNET_TESTING_daemon_stop (pg->peers[off].daemon, NULL, NULL, GNUNET_YES);
1414 if (NULL != pg->peers[off].cfg) 2443 if (NULL != pg->peers[off].cfg)
1415 GNUNET_CONFIGURATION_destroy (pg->peers[off].cfg); 2444 GNUNET_CONFIGURATION_destroy (pg->peers[off].cfg);
1416 2445
1417 pos = pg->peers[off].connected_peers; 2446 GNUNET_CONTAINER_multihashmap_destroy(pg->peers[off].allowed_peers);
1418 while (pos != NULL) 2447 GNUNET_CONTAINER_multihashmap_destroy(pg->peers[off].connect_peers);
1419 { 2448 GNUNET_CONTAINER_multihashmap_destroy(pg->peers[off].blacklisted_peers);
1420 next = pos->next;
1421 GNUNET_free(pos);
1422 pos = next;
1423 }
1424 2449
1425 } 2450 }
1426 GNUNET_free (pg->peers); 2451 GNUNET_free (pg->peers);