summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-09-05 21:18:45 +0000
committerChristian Grothoff <christian@grothoff.org>2011-09-05 21:18:45 +0000
commit563b71afee70ac213a8bb28ce0697fcbae06aac3 (patch)
tree122d6a25630f68a9845651ba2295ef68f7d2af09 /src
parentcf6e2bdb1b9a5aedc4f090df853814b9df817e03 (diff)
downloadgnunet-563b71afee70ac213a8bb28ce0697fcbae06aac3.tar.gz
gnunet-563b71afee70ac213a8bb28ce0697fcbae06aac3.zip
fixing API and clean up issues in testing
Diffstat (limited to 'src')
-rw-r--r--src/dht/gnunet-dht-driver.c168
-rw-r--r--src/fs/fs_test_lib.c32
-rw-r--r--src/fs/fs_test_lib.h14
-rw-r--r--src/fs/test_fs_test_lib.c12
-rw-r--r--src/fs/test_gnunet_service_fs_migration.c14
-rw-r--r--src/fs/test_gnunet_service_fs_p2p.c12
-rw-r--r--src/include/gnunet_testing_lib.h26
-rw-r--r--src/nse/gnunet-nse-profiler.c2
-rw-r--r--src/testing/test_testing_connect.c7
-rw-r--r--src/testing/test_testing_reconnect.c9
-rw-r--r--src/testing/testing.c311
-rw-r--r--src/testing/testing_group.c84
-rw-r--r--src/topology/test_gnunet_daemon_topology.c33
13 files changed, 320 insertions, 404 deletions
diff --git a/src/dht/gnunet-dht-driver.c b/src/dht/gnunet-dht-driver.c
index 4f411f4a9..a7641098e 100644
--- a/src/dht/gnunet-dht-driver.c
+++ b/src/dht/gnunet-dht-driver.c
@@ -36,9 +36,6 @@
36#include "dht.h" 36#include "dht.h"
37#include "gauger.h" 37#include "gauger.h"
38 38
39/* Specific DEBUG hack, do not use normally (may leak memory, segfault, or eat children.) */
40#define ONLY_TESTING GNUNET_NO
41
42/* DEFINES */ 39/* DEFINES */
43#define VERBOSE GNUNET_NO 40#define VERBOSE GNUNET_NO
44 41
@@ -332,6 +329,11 @@ struct FindPeerContext
332 struct GNUNET_CONTAINER_MultiHashMap *peer_hash; 329 struct GNUNET_CONTAINER_MultiHashMap *peer_hash;
333 330
334 /** 331 /**
332 * Handle to an active attempt to connect this peer.
333 */
334 struct GNUNET_TESTING_ConnectContext *cc;
335
336 /**
335 * Min heap which orders values in the peer_hash for 337 * Min heap which orders values in the peer_hash for
336 * easy lookup. 338 * easy lookup.
337 */ 339 */
@@ -446,21 +448,6 @@ static unsigned int do_find_peer;
446 */ 448 */
447static unsigned int insert_gauger_data; 449static unsigned int insert_gauger_data;
448 450
449#if ONLY_TESTING
450/**
451 * Are we currently trying to connect two peers repeatedly?
452 */
453static unsigned int repeat_connect_mode;
454
455/**
456 * Task for repeating connects.
457 */
458GNUNET_SCHEDULER_TaskIdentifier repeat_connect_task;
459
460struct GNUNET_TESTING_Daemon *repeat_connect_peer1;
461struct GNUNET_TESTING_Daemon *repeat_connect_peer2;
462#endif
463
464/** 451/**
465 * Boolean value, should replication be done by the dht 452 * Boolean value, should replication be done by the dht
466 * service (GNUNET_YES) or by the driver (GNUNET_NO) 453 * service (GNUNET_YES) or by the driver (GNUNET_NO)
@@ -724,6 +711,7 @@ static unsigned long long cumulative_successful_gets;
724 */ 711 */
725static unsigned long long gets_failed; 712static unsigned long long gets_failed;
726 713
714#ifndef HAVE_MALICIOUS
727/** 715/**
728 * How many malicious control messages do 716 * How many malicious control messages do
729 * we currently have in flight? 717 * we currently have in flight?
@@ -734,6 +722,7 @@ static unsigned long long outstanding_malicious;
734 * How many set malicious peers are done? 722 * How many set malicious peers are done?
735 */ 723 */
736static unsigned int malicious_completed; 724static unsigned int malicious_completed;
725#endif
737 726
738/** 727/**
739 * For gauger logging, what specific identifier (svn revision) 728 * For gauger logging, what specific identifier (svn revision)
@@ -1417,6 +1406,30 @@ add_new_connection (struct FindPeerContext *find_peer_context,
1417 } 1406 }
1418} 1407}
1419 1408
1409static void
1410did_connect (void *cls,
1411 const struct
1412 GNUNET_PeerIdentity * first,
1413 const struct
1414 GNUNET_PeerIdentity * second,
1415 uint32_t distance,
1416 const struct
1417 GNUNET_CONFIGURATION_Handle *
1418 first_cfg,
1419 const struct
1420 GNUNET_CONFIGURATION_Handle *
1421 second_cfg,
1422 struct GNUNET_TESTING_Daemon *
1423 first_daemon,
1424 struct GNUNET_TESTING_Daemon *
1425 second_daemon,
1426 const char *emsg)
1427{
1428 struct FindPeerContext *find_peer_context = cls;
1429
1430 find_peer_context->cc = NULL;
1431}
1432
1420/** 1433/**
1421 * Iterate over min heap of connections per peer. For any 1434 * Iterate over min heap of connections per peer. For any
1422 * peer that has 0 connections, attempt to connect them to 1435 * peer that has 0 connections, attempt to connect them to
@@ -1444,7 +1457,7 @@ iterate_min_heap_peers (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
1444 d1 = GNUNET_TESTING_daemon_get_by_id (pg, &peer_count->peer_id); 1457 d1 = GNUNET_TESTING_daemon_get_by_id (pg, &peer_count->peer_id);
1445 GNUNET_assert (d1 != NULL); 1458 GNUNET_assert (d1 != NULL);
1446 d2 = d1; 1459 d2 = d1;
1447 while ((d2 == d1) || (GNUNET_YES != GNUNET_TESTING_daemon_running (d2))) 1460 while ((d2 == d1) || (GNUNET_YES != GNUNET_TESTING_test_daemon_running (d2)))
1448 { 1461 {
1449 d2 = GNUNET_TESTING_daemon_get (pg, 1462 d2 = GNUNET_TESTING_daemon_get (pg,
1450 GNUNET_CRYPTO_random_u32 1463 GNUNET_CRYPTO_random_u32
@@ -1464,14 +1477,17 @@ iterate_min_heap_peers (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
1464 { 1477 {
1465 timeout = GNUNET_TIME_absolute_get_remaining (find_peer_context->endtime); 1478 timeout = GNUNET_TIME_absolute_get_remaining (find_peer_context->endtime);
1466 } 1479 }
1467 GNUNET_TESTING_daemons_connect (d1, d2, timeout, DEFAULT_RECONNECT_ATTEMPTS, 1480 if (NULL != find_peer_context->cc)
1468 GNUNET_YES, NULL, NULL); 1481 GNUNET_TESTING_daemons_connect_cancel (find_peer_context->cc);
1482 find_peer_context->cc = GNUNET_TESTING_daemons_connect (d1, d2, timeout, DEFAULT_RECONNECT_ATTEMPTS,
1483 GNUNET_YES,
1484 &did_connect,
1485 find_peer_context);
1469 } 1486 }
1470 if (GNUNET_TIME_absolute_get_remaining (find_peer_context->endtime).rel_value 1487 if (GNUNET_TIME_absolute_get_remaining (find_peer_context->endtime).rel_value
1471 > 0) 1488 > 0)
1472 return GNUNET_YES; 1489 return GNUNET_YES;
1473 else 1490 return GNUNET_NO;
1474 return GNUNET_NO;
1475} 1491}
1476 1492
1477/** 1493/**
@@ -1585,6 +1601,8 @@ count_peers_churn_cb (void *cls, const struct GNUNET_PeerIdentity *first,
1585 find_peer_context); 1601 find_peer_context);
1586 GNUNET_CONTAINER_multihashmap_destroy (find_peer_context->peer_hash); 1602 GNUNET_CONTAINER_multihashmap_destroy (find_peer_context->peer_hash);
1587 GNUNET_CONTAINER_heap_destroy (find_peer_context->peer_min_heap); 1603 GNUNET_CONTAINER_heap_destroy (find_peer_context->peer_min_heap);
1604 if (NULL != find_peer_context->cc)
1605 GNUNET_TESTING_daemons_connect_cancel (find_peer_context->cc);
1588 GNUNET_free (find_peer_context); 1606 GNUNET_free (find_peer_context);
1589 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1607 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1590 "Churn round %u of %llu finished, scheduling next GET round.\n", 1608 "Churn round %u of %llu finished, scheduling next GET round.\n",
@@ -1756,7 +1774,7 @@ churn_complete (void *cls, const char *emsg)
1756 for (i = 0; i < num_peers; i++) 1774 for (i = 0; i < num_peers; i++)
1757 { 1775 {
1758 temp_daemon = GNUNET_TESTING_daemon_get (pg, i); 1776 temp_daemon = GNUNET_TESTING_daemon_get (pg, i);
1759 if (GNUNET_YES == GNUNET_TESTING_daemon_running (temp_daemon)) 1777 if (GNUNET_YES == GNUNET_TESTING_test_daemon_running (temp_daemon))
1760 { 1778 {
1761 peer_count = GNUNET_malloc (sizeof (struct PeerCount)); 1779 peer_count = GNUNET_malloc (sizeof (struct PeerCount));
1762 memcpy (&peer_count->peer_id, &temp_daemon->id, 1780 memcpy (&peer_count->peer_id, &temp_daemon->id,
@@ -2102,7 +2120,7 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2102 /* Set this here in case we are re-running gets */ 2120 /* Set this here in case we are re-running gets */
2103 test_get->succeeded = GNUNET_NO; 2121 test_get->succeeded = GNUNET_NO;
2104 2122
2105 if (GNUNET_YES != GNUNET_TESTING_daemon_running (test_get->daemon)) /* If the peer has been churned off, don't try issuing request from it! */ 2123 if (GNUNET_YES != GNUNET_TESTING_test_daemon_running (test_get->daemon)) /* If the peer has been churned off, don't try issuing request from it! */
2106 { 2124 {
2107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2108 "Peer we should issue get request from is down, skipping.\n"); 2126 "Peer we should issue get request from is down, skipping.\n");
@@ -2219,7 +2237,7 @@ do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2219 if (test_put == NULL) 2237 if (test_put == NULL)
2220 return; /* End of list */ 2238 return; /* End of list */
2221 2239
2222 if (GNUNET_YES != GNUNET_TESTING_daemon_running (test_put->daemon)) /* If the peer has been churned off, don't try issuing request from it! */ 2240 if (GNUNET_YES != GNUNET_TESTING_test_daemon_running (test_put->daemon)) /* If the peer has been churned off, don't try issuing request from it! */
2223 { 2241 {
2224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2225 "Peer we should issue put request at is down, skipping.\n"); 2243 "Peer we should issue put request at is down, skipping.\n");
@@ -2338,6 +2356,8 @@ count_peers_cb (void *cls, const struct GNUNET_PeerIdentity *first,
2338 find_peer_context); 2356 find_peer_context);
2339 GNUNET_CONTAINER_multihashmap_destroy (find_peer_context->peer_hash); 2357 GNUNET_CONTAINER_multihashmap_destroy (find_peer_context->peer_hash);
2340 GNUNET_CONTAINER_heap_destroy (find_peer_context->peer_min_heap); 2358 GNUNET_CONTAINER_heap_destroy (find_peer_context->peer_min_heap);
2359 if (NULL != find_peer_context->cc)
2360 GNUNET_TESTING_daemons_connect_cancel (find_peer_context->cc);
2341 GNUNET_free (find_peer_context); 2361 GNUNET_free (find_peer_context);
2342 fprintf (stderr, "Not sending any more find peer requests.\n"); 2362 fprintf (stderr, "Not sending any more find peer requests.\n");
2343 2363
@@ -2663,6 +2683,7 @@ continue_puts_and_gets (void *cls,
2663 } 2683 }
2664} 2684}
2665 2685
2686#if HAVE_MALICIOUS
2666/** 2687/**
2667 * Task to release DHT handles 2688 * Task to release DHT handles
2668 */ 2689 */
@@ -2686,7 +2707,6 @@ malicious_disconnect_task (void *cls,
2686 } 2707 }
2687} 2708}
2688 2709
2689#if HAVE_MALICIOUS
2690/** 2710/**
2691 * Task to release DHT handles 2711 * Task to release DHT handles
2692 */ 2712 */
@@ -2784,7 +2804,7 @@ choose_next_malicious (struct GNUNET_TESTING_PeerGroup *pg,
2784 temp_daemon = GNUNET_TESTING_daemon_get (pg, i); 2804 temp_daemon = GNUNET_TESTING_daemon_get (pg, i);
2785 hash_from_uid (i, &uid_hash); 2805 hash_from_uid (i, &uid_hash);
2786 /* Check if this peer matches the bloomfilter */ 2806 /* Check if this peer matches the bloomfilter */
2787 if ((GNUNET_NO == GNUNET_TESTING_daemon_running (temp_daemon)) || 2807 if ((GNUNET_NO == GNUNET_TESTING_test_daemon_running (temp_daemon)) ||
2788 (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (bloom, &uid_hash))) 2808 (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (bloom, &uid_hash)))
2789 continue; 2809 continue;
2790 2810
@@ -2877,43 +2897,6 @@ setup_malicious_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2877} 2897}
2878#endif 2898#endif
2879 2899
2880#if ONLY_TESTING
2881/* Forward declaration */
2882static void
2883topology_callback (void *cls, const struct GNUNET_PeerIdentity *first,
2884 const struct GNUNET_PeerIdentity *second, uint32_t distance,
2885 const struct GNUNET_CONFIGURATION_Handle *first_cfg,
2886 const struct GNUNET_CONFIGURATION_Handle *second_cfg,
2887 struct GNUNET_TESTING_Daemon *first_daemon,
2888 struct GNUNET_TESTING_Daemon *second_daemon,
2889 const char *emsg);
2890
2891/**
2892 * Retry connecting two specific peers until they connect,
2893 * at a specific interval. These two peers previously failed
2894 * to connect, and we hope they continue to so that we can
2895 * debug the reason they are having issues.
2896 */
2897static void
2898repeat_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2899{
2900
2901 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2902 "Repeating connect attempt between %s and %s.\n",
2903 repeat_connect_peer1->shortname, repeat_connect_peer2->shortname);
2904 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Peer 1 configuration `%s'\n",
2905 repeat_connect_peer1->cfgfile);
2906 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Peer 2 configuration `%s'\n",
2907 repeat_connect_peer2->cfgfile);
2908
2909 repeat_connect_task = GNUNET_SCHEDULER_NO_TASK;
2910 GNUNET_TESTING_daemons_connect (repeat_connect_peer1, repeat_connect_peer2,
2911 GNUNET_TIME_relative_multiply
2912 (GNUNET_TIME_UNIT_SECONDS, 60), 2,
2913 &topology_callback, NULL);
2914}
2915#endif
2916
2917/** 2900/**
2918 * This function is called whenever a connection attempt is finished between two of 2901 * This function is called whenever a connection attempt is finished between two of
2919 * the started peers (started with GNUNET_TESTING_daemons_start). The total 2902 * the started peers (started with GNUNET_TESTING_daemons_start). The total
@@ -2945,36 +2928,6 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first,
2945 char *temp_conn_failed_string; 2928 char *temp_conn_failed_string;
2946 char *revision_str; 2929 char *revision_str;
2947 2930
2948#if ONLY_TESTING
2949 if (repeat_connect_mode == GNUNET_YES)
2950 {
2951 if ((first_daemon == repeat_connect_peer1) &&
2952 (second_daemon == repeat_connect_peer2))
2953 {
2954 if (emsg != NULL) /* Peers failed to connect again! */
2955 {
2956 GNUNET_assert (repeat_connect_task == GNUNET_SCHEDULER_NO_TASK);
2957 repeat_connect_task =
2958 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
2959 (GNUNET_TIME_UNIT_SECONDS, 60),
2960 &repeat_connect, NULL);
2961 return;
2962 }
2963 else /* Repeat peers actually connected! */
2964 {
2965 if (repeat_connect_task != GNUNET_SCHEDULER_NO_TASK)
2966 GNUNET_SCHEDULER_cancel (repeat_connect_task);
2967 repeat_connect_peer1 = NULL;
2968 repeat_connect_peer2 = NULL;
2969 repeat_connect_mode = GNUNET_NO;
2970 GNUNET_TESTING_resume_connections (pg);
2971 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2972 "Resuming normal connection mode, debug connection was successful!\n");
2973 }
2974 }
2975 }
2976#endif
2977
2978 if (GNUNET_TIME_absolute_get_difference 2931 if (GNUNET_TIME_absolute_get_difference
2979 (connect_last_time, 2932 (connect_last_time,
2980 GNUNET_TIME_absolute_get ()).rel_value > 2933 GNUNET_TIME_absolute_get ()).rel_value >
@@ -3013,26 +2966,6 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first,
3013 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2966 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3014 "have %llu total_connections, %llu failed\n", total_connections, 2967 "have %llu total_connections, %llu failed\n", total_connections,
3015 failed_connections); 2968 failed_connections);
3016#if ONLY_TESTING
3017 /* These conditions likely mean we've entered the death spiral of doom */
3018 if ((total_connections > 20000) && (conns_per_sec_recent < 5.0) &&
3019 (conns_per_sec_total > 10.0) && (emsg != NULL) &&
3020 (repeat_connect_mode == GNUNET_NO))
3021 {
3022 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3023 "Entering repeat connection attempt mode!\n");
3024 repeat_connect_peer1 = first_daemon;
3025 repeat_connect_peer2 = second_daemon;
3026 repeat_connect_mode = GNUNET_YES;
3027 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3028 "Stopping NEW connections from being scheduled!\n");
3029 GNUNET_TESTING_stop_connections (pg);
3030 repeat_connect_task =
3031 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
3032 (GNUNET_TIME_UNIT_SECONDS, 60),
3033 &repeat_connect, NULL);
3034 }
3035#endif
3036 } 2969 }
3037 2970
3038 if (emsg == NULL) 2971 if (emsg == NULL)
@@ -3058,11 +2991,6 @@ topology_callback (void *cls, const struct GNUNET_PeerIdentity *first,
3058#endif 2991#endif
3059 } 2992 }
3060 2993
3061#if ONLY_TESTING
3062 if ((repeat_connect_mode == GNUNET_YES))
3063 return;
3064#endif
3065
3066 GNUNET_assert (peer_connect_meter != NULL); 2994 GNUNET_assert (peer_connect_meter != NULL);
3067 if (GNUNET_YES == update_meter (peer_connect_meter)) 2995 if (GNUNET_YES == update_meter (peer_connect_meter))
3068 { 2996 {
diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c
index 17291d1bd..40a9f6276 100644
--- a/src/fs/fs_test_lib.c
+++ b/src/fs/fs_test_lib.c
@@ -379,10 +379,11 @@ GNUNET_FS_TEST_daemons_start (const char *template_cfg_file,
379} 379}
380 380
381 381
382struct ConnectContext 382struct GNUNET_FS_TEST_ConnectContext
383{ 383{
384 GNUNET_SCHEDULER_Task cont; 384 GNUNET_SCHEDULER_Task cont;
385 void *cont_cls; 385 void *cont_cls;
386 struct GNUNET_TESTING_ConnectContext *cc;
386}; 387};
387 388
388 389
@@ -409,8 +410,9 @@ notify_connection (void *cls, const struct GNUNET_PeerIdentity *first,
409 struct GNUNET_TESTING_Daemon *second_daemon, 410 struct GNUNET_TESTING_Daemon *second_daemon,
410 const char *emsg) 411 const char *emsg)
411{ 412{
412 struct ConnectContext *cc = cls; 413 struct GNUNET_FS_TEST_ConnectContext *cc = cls;
413 414
415 cc->cc = NULL;
414 if (emsg != NULL) 416 if (emsg != NULL)
415 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peers: %s\n", 417 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peers: %s\n",
416 emsg); 418 emsg);
@@ -432,20 +434,34 @@ notify_connection (void *cls, const struct GNUNET_PeerIdentity *first,
432 * @param cont function to call when done 434 * @param cont function to call when done
433 * @param cont_cls closure for cont 435 * @param cont_cls closure for cont
434 */ 436 */
435void 437struct GNUNET_FS_TEST_ConnectContext *
436GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1, 438GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1,
437 struct GNUNET_FS_TestDaemon *daemon2, 439 struct GNUNET_FS_TestDaemon *daemon2,
438 struct GNUNET_TIME_Relative timeout, 440 struct GNUNET_TIME_Relative timeout,
439 GNUNET_SCHEDULER_Task cont, void *cont_cls) 441 GNUNET_SCHEDULER_Task cont, void *cont_cls)
440{ 442{
441 struct ConnectContext *ncc; 443 struct GNUNET_FS_TEST_ConnectContext *ncc;
442 444
443 ncc = GNUNET_malloc (sizeof (struct ConnectContext)); 445 ncc = GNUNET_malloc (sizeof (struct GNUNET_FS_TEST_ConnectContext));
444 ncc->cont = cont; 446 ncc->cont = cont;
445 ncc->cont_cls = cont_cls; 447 ncc->cont_cls = cont_cls;
446 GNUNET_TESTING_daemons_connect (daemon1->daemon, daemon2->daemon, timeout, 448 ncc->cc = GNUNET_TESTING_daemons_connect (daemon1->daemon, daemon2->daemon, timeout,
447 CONNECT_ATTEMPTS, GNUNET_YES, 449 CONNECT_ATTEMPTS, GNUNET_YES,
448 &notify_connection, ncc); 450 &notify_connection, ncc);
451 return ncc;
452}
453
454
455/**
456 * Cancel connect operation.
457 *
458 * @param cc operation to cancel
459 */
460void
461GNUNET_FS_TEST_daemons_connect_cancel (struct GNUNET_FS_TEST_ConnectContext *cc)
462{
463 GNUNET_TESTING_daemons_connect_cancel (cc->cc);
464 GNUNET_free (cc);
449} 465}
450 466
451 467
diff --git a/src/fs/fs_test_lib.h b/src/fs/fs_test_lib.h
index ad1d96bf0..204d5b2ab 100644
--- a/src/fs/fs_test_lib.h
+++ b/src/fs/fs_test_lib.h
@@ -61,6 +61,9 @@ GNUNET_FS_TEST_daemons_start (const char *template_cfg_file,
61 GNUNET_SCHEDULER_Task cont, void *cont_cls); 61 GNUNET_SCHEDULER_Task cont, void *cont_cls);
62 62
63 63
64struct GNUNET_FS_TEST_ConnectContext;
65
66
64/** 67/**
65 * Connect two daemons for testing. 68 * Connect two daemons for testing.
66 * 69 *
@@ -71,7 +74,7 @@ GNUNET_FS_TEST_daemons_start (const char *template_cfg_file,
71 * @param cont function to call when done 74 * @param cont function to call when done
72 * @param cont_cls closure for cont 75 * @param cont_cls closure for cont
73 */ 76 */
74void 77struct GNUNET_FS_TEST_ConnectContext *
75GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1, 78GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1,
76 struct GNUNET_FS_TestDaemon *daemon2, 79 struct GNUNET_FS_TestDaemon *daemon2,
77 struct GNUNET_TIME_Relative timeout, 80 struct GNUNET_TIME_Relative timeout,
@@ -79,6 +82,15 @@ GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1,
79 82
80 83
81/** 84/**
85 * Cancel connect operation.
86 *
87 * @param cc operation to cancel
88 */
89void
90GNUNET_FS_TEST_daemons_connect_cancel (struct GNUNET_FS_TEST_ConnectContext *cc);
91
92
93/**
82 * Obtain peer group used for testing. 94 * Obtain peer group used for testing.
83 * 95 *
84 * @param daemons array with the daemons (must contain at least one) 96 * @param daemons array with the daemons (must contain at least one)
diff --git a/src/fs/test_fs_test_lib.c b/src/fs/test_fs_test_lib.c
index 458d4606b..1f2119259 100644
--- a/src/fs/test_fs_test_lib.c
+++ b/src/fs/test_fs_test_lib.c
@@ -44,11 +44,18 @@
44 44
45static struct GNUNET_FS_TestDaemon *daemons[NUM_DAEMONS]; 45static struct GNUNET_FS_TestDaemon *daemons[NUM_DAEMONS];
46 46
47static struct GNUNET_FS_TEST_ConnectContext *cc;
48
47static int ret; 49static int ret;
48 50
49static void 51static void
50do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 52do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
51{ 53{
54 if (NULL != cc)
55 {
56 GNUNET_FS_TEST_daemons_connect_cancel (cc);
57 cc = NULL;
58 }
52 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 59 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
53 { 60 {
54 GNUNET_break (0); 61 GNUNET_break (0);
@@ -83,6 +90,7 @@ do_download (void *cls, const struct GNUNET_FS_Uri *uri)
83static void 90static void
84do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 91do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
85{ 92{
93 cc = NULL;
86 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 94 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
87 { 95 {
88 GNUNET_break (0); 96 GNUNET_break (0);
@@ -109,8 +117,8 @@ do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
109 } 117 }
110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
111 "Daemons started, will now try to connect them\n"); 119 "Daemons started, will now try to connect them\n");
112 GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, &do_publish, 120 cc = GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, &do_publish,
113 NULL); 121 NULL);
114} 122}
115 123
116 124
diff --git a/src/fs/test_gnunet_service_fs_migration.c b/src/fs/test_gnunet_service_fs_migration.c
index a5570e1d4..bbf2534d2 100644
--- a/src/fs/test_gnunet_service_fs_migration.c
+++ b/src/fs/test_gnunet_service_fs_migration.c
@@ -52,12 +52,19 @@ static int ok;
52 52
53static struct GNUNET_TIME_Absolute start_time; 53static struct GNUNET_TIME_Absolute start_time;
54 54
55static struct GNUNET_FS_TEST_ConnectContext *cc;
56
55static void 57static void
56do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 58do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
57{ 59{
58 struct GNUNET_TIME_Relative del; 60 struct GNUNET_TIME_Relative del;
59 char *fancy; 61 char *fancy;
60 62
63 if (NULL != cc)
64 {
65 GNUNET_FS_TEST_daemons_connect_cancel (cc);
66 cc = NULL;
67 }
61 GNUNET_FS_TEST_daemons_stop (2, daemons); 68 GNUNET_FS_TEST_daemons_stop (2, daemons);
62 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 69 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
63 { 70 {
@@ -138,6 +145,7 @@ do_wait (void *cls, const struct GNUNET_FS_Uri *uri)
138static void 145static void
139do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 146do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
140{ 147{
148 cc = NULL;
141 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 149 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
142 { 150 {
143 GNUNET_FS_TEST_daemons_stop (2, daemons); 151 GNUNET_FS_TEST_daemons_stop (2, daemons);
@@ -165,8 +173,8 @@ do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
165 } 173 }
166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
167 "Daemons started, will now try to connect them\n"); 175 "Daemons started, will now try to connect them\n");
168 GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, &do_publish, 176 cc = GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, &do_publish,
169 NULL); 177 NULL);
170} 178}
171 179
172 180
diff --git a/src/fs/test_gnunet_service_fs_p2p.c b/src/fs/test_gnunet_service_fs_p2p.c
index aece0e80a..26372cfa8 100644
--- a/src/fs/test_gnunet_service_fs_p2p.c
+++ b/src/fs/test_gnunet_service_fs_p2p.c
@@ -48,12 +48,19 @@ static int ok;
48 48
49static struct GNUNET_TIME_Absolute start_time; 49static struct GNUNET_TIME_Absolute start_time;
50 50
51static struct GNUNET_FS_TEST_ConnectContext *cc;
52
51static void 53static void
52do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 54do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
53{ 55{
54 struct GNUNET_TIME_Relative del; 56 struct GNUNET_TIME_Relative del;
55 char *fancy; 57 char *fancy;
56 58
59 if (NULL != cc)
60 {
61 GNUNET_FS_TEST_daemons_connect_cancel (cc);
62 cc = NULL;
63 }
57 GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); 64 GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons);
58 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 65 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
59 { 66 {
@@ -99,6 +106,7 @@ do_download (void *cls, const struct GNUNET_FS_Uri *uri)
99static void 106static void
100do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 107do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
101{ 108{
109 cc = NULL;
102 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 110 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
103 { 111 {
104 GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); 112 GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons);
@@ -120,8 +128,8 @@ do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
120 GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); 128 GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
122 "Daemons started, will now try to connect them\n"); 130 "Daemons started, will now try to connect them\n");
123 GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, &do_publish, 131 cc = GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, &do_publish,
124 NULL); 132 NULL);
125} 133}
126 134
127 135
diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h
index 945a3900b..39bc9d161 100644
--- a/src/include/gnunet_testing_lib.h
+++ b/src/include/gnunet_testing_lib.h
@@ -432,6 +432,7 @@ typedef void (*GNUNET_TESTING_NotifyConnection) (void *cls,
432 second_daemon, 432 second_daemon,
433 const char *emsg); 433 const char *emsg);
434 434
435
435/** 436/**
436 * Prototype of a callback function indicating that two peers 437 * Prototype of a callback function indicating that two peers
437 * are currently connected. 438 * are currently connected.
@@ -497,12 +498,11 @@ GNUNET_TESTING_daemon_continue_startup (struct GNUNET_TESTING_Daemon *daemon);
497 * Check whether the given daemon is running. 498 * Check whether the given daemon is running.
498 * 499 *
499 * @param daemon the daemon to check 500 * @param daemon the daemon to check
500 *
501 * @return GNUNET_YES if the daemon is up, GNUNET_NO if the 501 * @return GNUNET_YES if the daemon is up, GNUNET_NO if the
502 * daemon is down, GNUNET_SYSERR on error. 502 * daemon is down, GNUNET_SYSERR on error.
503 */ 503 */
504int 504int
505GNUNET_TESTING_daemon_running (struct GNUNET_TESTING_Daemon *daemon); 505GNUNET_TESTING_test_daemon_running (struct GNUNET_TESTING_Daemon *daemon);
506 506
507 507
508/** 508/**
@@ -545,7 +545,7 @@ GNUNET_TESTING_daemon_start_stopped (struct GNUNET_TESTING_Daemon *daemon,
545 */ 545 */
546void 546void
547GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d, 547GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d,
548 char *service, 548 const char *service,
549 struct GNUNET_TIME_Relative timeout, 549 struct GNUNET_TIME_Relative timeout,
550 GNUNET_TESTING_NotifyDaemonRunning cb, 550 GNUNET_TESTING_NotifyDaemonRunning cb,
551 void *cb_cls); 551 void *cb_cls);
@@ -643,7 +643,7 @@ GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d,
643 */ 643 */
644void 644void
645GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d, 645GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d,
646 char *service, 646 const char *service,
647 struct GNUNET_TIME_Relative timeout, 647 struct GNUNET_TIME_Relative timeout,
648 GNUNET_TESTING_NotifyCompletion cb, 648 GNUNET_TESTING_NotifyCompletion cb,
649 void *cb_cls); 649 void *cb_cls);
@@ -715,7 +715,16 @@ GNUNET_TESTING_daemons_continue_startup (struct GNUNET_TESTING_PeerGroup *pg);
715 715
716 716
717/** 717/**
718 * Establish a connection between two GNUnet daemons. 718 * Handle for an active request to connect two peers.
719 */
720struct GNUNET_TESTING_ConnectContext;
721
722
723/**
724 * Establish a connection between two GNUnet daemons. The daemons
725 * must both be running and not be stopped until either the
726 * 'cb' callback is called OR the connection request has been
727 * explicitly cancelled.
719 * 728 *
720 * @param d1 handle for the first daemon 729 * @param d1 handle for the first daemon
721 * @param d2 handle for the second daemon 730 * @param d2 handle for the second daemon
@@ -727,8 +736,9 @@ GNUNET_TESTING_daemons_continue_startup (struct GNUNET_TESTING_PeerGroup *pg);
727 * the HELLO has already been exchanged 736 * the HELLO has already been exchanged
728 * @param cb function to call at the end 737 * @param cb function to call at the end
729 * @param cb_cls closure for cb 738 * @param cb_cls closure for cb
739 * @return handle to cancel the request, NULL on error
730 */ 740 */
731void /* struct GNUNET_TESTING_ConnectContext * */ 741struct GNUNET_TESTING_ConnectContext *
732GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1, 742GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
733 struct GNUNET_TESTING_Daemon *d2, 743 struct GNUNET_TESTING_Daemon *d2,
734 struct GNUNET_TIME_Relative timeout, 744 struct GNUNET_TIME_Relative timeout,
@@ -738,7 +748,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
738 void *cb_cls); 748 void *cb_cls);
739 749
740 750
741#if 0 751
742/** 752/**
743 * Cancel an attempt to connect two daemons. 753 * Cancel an attempt to connect two daemons.
744 * 754 *
@@ -747,7 +757,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
747void 757void
748GNUNET_TESTING_daemons_connect_cancel (struct GNUNET_TESTING_ConnectContext 758GNUNET_TESTING_daemons_connect_cancel (struct GNUNET_TESTING_ConnectContext
749 *cc); 759 *cc);
750#endif 760
751 761
752 762
753/** 763/**
diff --git a/src/nse/gnunet-nse-profiler.c b/src/nse/gnunet-nse-profiler.c
index 0df6ddf7d..9342480c2 100644
--- a/src/nse/gnunet-nse-profiler.c
+++ b/src/nse/gnunet-nse-profiler.c
@@ -251,7 +251,7 @@ connect_nse_service (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
251 current_peer = GNUNET_malloc (sizeof (struct NSEPeer)); 251 current_peer = GNUNET_malloc (sizeof (struct NSEPeer));
252 current_peer->daemon = GNUNET_TESTING_daemon_get (pg, i); 252 current_peer->daemon = GNUNET_TESTING_daemon_get (pg, i);
253 if (GNUNET_YES == 253 if (GNUNET_YES ==
254 GNUNET_TESTING_daemon_running (GNUNET_TESTING_daemon_get (pg, i))) 254 GNUNET_TESTING_test_daemon_running (GNUNET_TESTING_daemon_get (pg, i)))
255 { 255 {
256 current_peer->nse_handle = 256 current_peer->nse_handle =
257 GNUNET_NSE_connect (current_peer->daemon->cfg, &handle_estimate, 257 GNUNET_NSE_connect (current_peer->daemon->cfg, &handle_estimate,
diff --git a/src/testing/test_testing_connect.c b/src/testing/test_testing_connect.c
index 4fe3a1dd6..fd14f76be 100644
--- a/src/testing/test_testing_connect.c
+++ b/src/testing/test_testing_connect.c
@@ -43,6 +43,8 @@ static struct GNUNET_CONFIGURATION_Handle *c1;
43 43
44static struct GNUNET_CONFIGURATION_Handle *c2; 44static struct GNUNET_CONFIGURATION_Handle *c2;
45 45
46static struct GNUNET_TESTING_ConnectContext *cc;
47
46static void 48static void
47end2_cb (void *cls, const char *emsg) 49end2_cb (void *cls, const char *emsg)
48{ 50{
@@ -99,6 +101,7 @@ my_connect_complete (void *cls, const struct GNUNET_PeerIdentity *first,
99 struct GNUNET_TESTING_Daemon *second_daemon, 101 struct GNUNET_TESTING_Daemon *second_daemon,
100 const char *emsg) 102 const char *emsg)
101{ 103{
104 cc = NULL;
102 GNUNET_SCHEDULER_add_now (&finish_testing, NULL); 105 GNUNET_SCHEDULER_add_now (&finish_testing, NULL);
103} 106}
104 107
@@ -113,8 +116,8 @@ my_cb2 (void *cls, const struct GNUNET_PeerIdentity *id,
113 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n", 116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n",
114 GNUNET_i2s (id)); 117 GNUNET_i2s (id));
115#endif 118#endif
116 GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, CONNECT_ATTEMPTS, GNUNET_YES, 119 cc = GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, CONNECT_ATTEMPTS, GNUNET_YES,
117 &my_connect_complete, NULL); 120 &my_connect_complete, NULL);
118} 121}
119 122
120 123
diff --git a/src/testing/test_testing_reconnect.c b/src/testing/test_testing_reconnect.c
index 69b871303..36675012f 100644
--- a/src/testing/test_testing_reconnect.c
+++ b/src/testing/test_testing_reconnect.c
@@ -43,6 +43,8 @@ static struct GNUNET_CONFIGURATION_Handle *c1;
43 43
44static struct GNUNET_CONFIGURATION_Handle *c2; 44static struct GNUNET_CONFIGURATION_Handle *c2;
45 45
46static struct GNUNET_TESTING_ConnectContext *cc;
47
46/** 48/**
47 * How many start-connect-stop iterations should we do? 49 * How many start-connect-stop iterations should we do?
48 */ 50 */
@@ -55,7 +57,7 @@ static int phase;
55 * stopping them again. 57 * stopping them again.
56 */ 58 */
57static void 59static void
58run_phase (); 60run_phase (void);
59 61
60static void 62static void
61end2_cb (void *cls, const char *emsg) 63end2_cb (void *cls, const char *emsg)
@@ -123,6 +125,7 @@ my_connect_complete (void *cls, const struct GNUNET_PeerIdentity *first,
123 struct GNUNET_TESTING_Daemon *second_daemon, 125 struct GNUNET_TESTING_Daemon *second_daemon,
124 const char *emsg) 126 const char *emsg)
125{ 127{
128 cc = NULL;
126#if VERBOSE 129#if VERBOSE
127 fprintf (stderr, "Peer %s ", GNUNET_i2s (first)); 130 fprintf (stderr, "Peer %s ", GNUNET_i2s (first));
128 fprintf (stderr, "connected to %s\n", GNUNET_i2s (second)); 131 fprintf (stderr, "connected to %s\n", GNUNET_i2s (second));
@@ -143,8 +146,8 @@ my_cb2 (void *cls, const struct GNUNET_PeerIdentity *id,
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n", 146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n",
144 GNUNET_i2s (id)); 147 GNUNET_i2s (id));
145#endif 148#endif
146 GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, CONNECT_ATTEMPTS, GNUNET_YES, 149 cc = GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, CONNECT_ATTEMPTS, GNUNET_YES,
147 &my_connect_complete, NULL); 150 &my_connect_complete, NULL);
148} 151}
149 152
150 153
diff --git a/src/testing/testing.c b/src/testing/testing.c
index ecd6140a6..78ed39e4a 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -41,8 +41,6 @@
41 41
42#define DEBUG_TESTING_RECONNECT GNUNET_NO 42#define DEBUG_TESTING_RECONNECT GNUNET_NO
43 43
44#define WAIT_FOR_HELLO GNUNET_NO
45
46/** 44/**
47 * Hack to deal with initial HELLO's being often devoid of addresses. 45 * Hack to deal with initial HELLO's being often devoid of addresses.
48 * This hack causes 'process_hello' to ignore HELLOs without addresses. 46 * This hack causes 'process_hello' to ignore HELLOs without addresses.
@@ -90,10 +88,6 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message)
90{ 88{
91 struct GNUNET_TESTING_Daemon *daemon = cls; 89 struct GNUNET_TESTING_Daemon *daemon = cls;
92 int msize; 90 int msize;
93
94#if WAIT_FOR_HELLO
95 GNUNET_TESTING_NotifyDaemonRunning cb;
96#endif
97#if EMPTY_HACK 91#if EMPTY_HACK
98 int empty; 92 int empty;
99 93
@@ -109,14 +103,8 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message)
109 return; 103 return;
110 } 104 }
111#endif 105#endif
112 if (daemon == NULL)
113 return;
114
115 GNUNET_assert (daemon->phase == SP_GET_HELLO || 106 GNUNET_assert (daemon->phase == SP_GET_HELLO ||
116 daemon->phase == SP_START_DONE); 107 daemon->phase == SP_START_DONE);
117#if WAIT_FOR_HELLO
118 cb = daemon->cb;
119#endif
120 daemon->cb = NULL; 108 daemon->cb = NULL;
121 if (daemon->task != GNUNET_SCHEDULER_NO_TASK) /* Assertion here instead? */ 109 if (daemon->task != GNUNET_SCHEDULER_NO_TASK) /* Assertion here instead? */
122 GNUNET_SCHEDULER_cancel (daemon->task); 110 GNUNET_SCHEDULER_cancel (daemon->task);
@@ -157,105 +145,11 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message)
157 daemon->th = NULL; 145 daemon->th = NULL;
158 } 146 }
159 daemon->phase = SP_START_DONE; 147 daemon->phase = SP_START_DONE;
160
161#if WAIT_FOR_HELLO
162 if (NULL != cb) /* FIXME: what happens when this callback calls GNUNET_TESTING_daemon_stop? */
163 cb (daemon->cb_cls, &daemon->id, daemon->cfg, daemon, NULL);
164#endif
165} 148}
166 149
167static void 150static void
168start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 151start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
169 152
170#if WAIT_FOR_HELLO
171/**
172 * Function called after GNUNET_CORE_connect has succeeded
173 * (or failed for good). Note that the private key of the
174 * peer is intentionally not exposed here; if you need it,
175 * your process should try to read the private key file
176 * directly (which should work if you are authorized...).
177 *
178 * @param cls closure
179 * @param server handle to the server, NULL if we failed
180 * @param my_identity ID of this peer, NULL if we failed
181 * @param publicKey public key of this peer, NULL if we failed
182 */
183static void
184testing_init (void *cls, struct GNUNET_CORE_Handle *server,
185 const struct GNUNET_PeerIdentity *my_identity,
186 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
187{
188 struct GNUNET_TESTING_Daemon *d = cls;
189
190 GNUNET_assert (d->phase == SP_START_CORE);
191 d->phase = SP_GET_HELLO;
192
193 if (server == NULL)
194 {
195 d->server = NULL;
196 if (GNUNET_YES == d->dead)
197 GNUNET_TESTING_daemon_stop (d,
198 GNUNET_TIME_absolute_get_remaining
199 (d->max_timeout), d->dead_cb, d->dead_cb_cls,
200 GNUNET_YES, GNUNET_NO);
201 else if (NULL != d->cb)
202 d->cb (d->cb_cls, NULL, d->cfg, d,
203 _("Failed to connect to core service\n"));
204 return;
205 }
206#if DEBUG_TESTING
207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully started peer `%4s'.\n",
208 GNUNET_i2s (my_identity));
209#endif
210 d->id = *my_identity; /* FIXME: shouldn't we already have this from reading the hostkey file? */
211 if (d->shortname == NULL)
212 d->shortname = strdup (GNUNET_i2s (my_identity));
213 d->server = server;
214 d->running = GNUNET_YES;
215
216 if (GNUNET_NO == d->running)
217 {
218#if DEBUG_TESTING
219 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
220 "Peer is dead (d->running == GNUNET_NO)\n");
221#endif
222 return;
223 }
224#if DEBUG_TESTING
225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
226 "Successfully started peer `%4s', connecting to transport service.\n",
227 GNUNET_i2s (my_identity));
228#endif
229
230 d->th = GNUNET_TRANSPORT_connect (d->cfg, &d->id, d, NULL, NULL, NULL);
231 if (d->th == NULL)
232 {
233 if (GNUNET_YES == d->dead)
234 GNUNET_TESTING_daemon_stop (d,
235 GNUNET_TIME_absolute_get_remaining
236 (d->max_timeout), d->dead_cb, d->dead_cb_cls,
237 GNUNET_YES, GNUNET_NO);
238 else if (NULL != d->cb)
239 d->cb (d->cb_cls, &d->id, d->cfg, d,
240 _("Failed to connect to transport service!\n"));
241 return;
242 }
243#if DEBUG_TESTING
244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
245 "Connected to transport service `%s', getting HELLO\n",
246 GNUNET_i2s (my_identity));
247#endif
248
249 d->ghh = GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d);
250 /* wait some more */
251 if (d->task != GNUNET_SCHEDULER_NO_TASK)
252 GNUNET_SCHEDULER_cancel (d->task);
253 d->task =
254 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d);
255}
256#endif
257
258#if !WAIT_FOR_HELLO
259/** 153/**
260 * Notify of a peer being up and running. Scheduled as a task 154 * Notify of a peer being up and running. Scheduled as a task
261 * so that variables which may need to be set are set before 155 * so that variables which may need to be set are set before
@@ -275,7 +169,7 @@ notify_daemon_started (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
275 if (NULL != cb) 169 if (NULL != cb)
276 cb (d->cb_cls, &d->id, d->cfg, d, NULL); 170 cb (d->cb_cls, &d->id, d->cfg, d, NULL);
277} 171}
278#endif 172
279 173
280/** 174/**
281 * Finite-state machine for starting GNUnet. 175 * Finite-state machine for starting GNUnet.
@@ -664,29 +558,6 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
664 if (d->server != NULL) 558 if (d->server != NULL)
665 GNUNET_CORE_disconnect (d->server); 559 GNUNET_CORE_disconnect (d->server);
666 560
667#if WAIT_FOR_HELLO
668 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
669 {
670 cb = d->cb;
671 d->cb = NULL;
672 if (NULL != cb)
673 cb (d->cb_cls, NULL, d->cfg, d,
674 _("Unable to connect to CORE service for peer!\n"));
675 GNUNET_CONFIGURATION_destroy (d->cfg);
676 GNUNET_free (d->cfgfile);
677 GNUNET_free_non_null (d->hostname);
678 GNUNET_free_non_null (d->username);
679 GNUNET_free (d);
680 return;
681 }
682 d->server =
683 GNUNET_CORE_connect (d->cfg, 1, d, &testing_init, NULL, NULL, NULL,
684 NULL, GNUNET_NO, NULL, GNUNET_NO, no_handlers);
685 d->task =
686 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
687 (GNUNET_CONSTANTS_SERVICE_RETRY, 2),
688 &start_fsm, d);
689#else
690 d->th = GNUNET_TRANSPORT_connect (d->cfg, &d->id, d, NULL, NULL, NULL); 561 d->th = GNUNET_TRANSPORT_connect (d->cfg, &d->id, d, NULL, NULL, NULL);
691 if (d->th == NULL) 562 if (d->th == NULL)
692 { 563 {
@@ -707,6 +578,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
707#endif 578#endif
708 579
709 d->ghh = GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d); 580 d->ghh = GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d);
581 /* FIXME: store task ID somewhere! */
710 GNUNET_SCHEDULER_add_now (&notify_daemon_started, d); 582 GNUNET_SCHEDULER_add_now (&notify_daemon_started, d);
711 /*cb = d->cb; 583 /*cb = d->cb;
712 * d->cb = NULL; 584 * d->cb = NULL;
@@ -714,7 +586,6 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
714 * cb (d->cb_cls, &d->id, d->cfg, d, NULL); */ 586 * cb (d->cb_cls, &d->id, d->cfg, d, NULL); */
715 d->running = GNUNET_YES; 587 d->running = GNUNET_YES;
716 d->phase = SP_GET_HELLO; 588 d->phase = SP_GET_HELLO;
717#endif
718 break; 589 break;
719 case SP_GET_HELLO: 590 case SP_GET_HELLO:
720 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) 591 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)
@@ -985,7 +856,7 @@ GNUNET_TESTING_daemon_continue_startup (struct GNUNET_TESTING_Daemon *daemon)
985 * daemon is down, GNUNET_SYSERR on error. 856 * daemon is down, GNUNET_SYSERR on error.
986 */ 857 */
987int 858int
988GNUNET_TESTING_daemon_running (struct GNUNET_TESTING_Daemon *daemon) 859GNUNET_TESTING_test_daemon_running (struct GNUNET_TESTING_Daemon *daemon)
989{ 860{
990 if (daemon == NULL) 861 if (daemon == NULL)
991 return GNUNET_SYSERR; 862 return GNUNET_SYSERR;
@@ -1098,7 +969,7 @@ GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d,
1098 */ 969 */
1099void 970void
1100GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d, 971GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d,
1101 char *service, 972 const char *service,
1102 struct GNUNET_TIME_Relative timeout, 973 struct GNUNET_TIME_Relative timeout,
1103 GNUNET_TESTING_NotifyDaemonRunning cb, 974 GNUNET_TESTING_NotifyDaemonRunning cb,
1104 void *cb_cls) 975 void *cb_cls)
@@ -1202,7 +1073,7 @@ GNUNET_TESTING_daemon_start_stopped (struct GNUNET_TESTING_Daemon *daemon,
1202 daemon->cb_cls = cb_cls; 1073 daemon->cb_cls = cb_cls;
1203 daemon->phase = SP_TOPOLOGY_SETUP; 1074 daemon->phase = SP_TOPOLOGY_SETUP;
1204 daemon->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); 1075 daemon->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1205 1076 /* FIXME: why add_continuation? */
1206 GNUNET_SCHEDULER_add_continuation (&start_fsm, daemon, 1077 GNUNET_SCHEDULER_add_continuation (&start_fsm, daemon,
1207 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 1078 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
1208} 1079}
@@ -1429,6 +1300,7 @@ GNUNET_TESTING_daemon_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
1429 "No need to copy configuration file since we are running locally.\n"); 1300 "No need to copy configuration file since we are running locally.\n");
1430#endif 1301#endif
1431 ret->phase = SP_COPIED; 1302 ret->phase = SP_COPIED;
1303 /* FIXME: why add_cont? */
1432 GNUNET_SCHEDULER_add_continuation (&start_fsm, ret, 1304 GNUNET_SCHEDULER_add_continuation (&start_fsm, ret,
1433 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 1305 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
1434 } 1306 }
@@ -1551,7 +1423,7 @@ GNUNET_TESTING_daemon_restart (struct GNUNET_TESTING_Daemon *d,
1551 */ 1423 */
1552void 1424void
1553GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d, 1425GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d,
1554 char *service, 1426 const char *service,
1555 struct GNUNET_TIME_Relative timeout, 1427 struct GNUNET_TIME_Relative timeout,
1556 GNUNET_TESTING_NotifyCompletion cb, 1428 GNUNET_TESTING_NotifyCompletion cb,
1557 void *cb_cls) 1429 void *cb_cls)
@@ -1852,7 +1724,7 @@ GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d,
1852 * Data kept for each pair of peers that we try 1724 * Data kept for each pair of peers that we try
1853 * to connect. 1725 * to connect.
1854 */ 1726 */
1855struct ConnectContext 1727struct GNUNET_TESTING_ConnectContext
1856{ 1728{
1857 /** 1729 /**
1858 * Testing handle to the first daemon. 1730 * Testing handle to the first daemon.
@@ -1949,13 +1821,13 @@ reattempt_daemons_connect (void *cls,
1949 * Notify callback about success or failure of the attempt 1821 * Notify callback about success or failure of the attempt
1950 * to connect the two peers 1822 * to connect the two peers
1951 * 1823 *
1952 * @param cls our "struct ConnectContext" (freed) 1824 * @param cls our "struct GNUNET_TESTING_ConnectContext" (freed)
1953 * @param tc reason tells us if we succeeded or failed 1825 * @param tc reason tells us if we succeeded or failed
1954 */ 1826 */
1955static void 1827static void
1956notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1828notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1957{ 1829{
1958 struct ConnectContext *ctx = cls; 1830 struct GNUNET_TESTING_ConnectContext *ctx = cls;
1959 1831
1960 ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK; 1832 ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1961 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK) 1833 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK)
@@ -1977,11 +1849,6 @@ notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1977 ctx->d1th = NULL; 1849 ctx->d1th = NULL;
1978 if (ctx->d1core != NULL) 1850 if (ctx->d1core != NULL)
1979 GNUNET_CORE_disconnect (ctx->d1core); 1851 GNUNET_CORE_disconnect (ctx->d1core);
1980#if CONNECT_CORE2
1981 if (ctx->d2core != NULL)
1982 GNUNET_CORE_disconnect (ctx->d2core);
1983 ctx->d2core = NULL;
1984#endif
1985 ctx->d1core = NULL; 1852 ctx->d1core = NULL;
1986 GNUNET_free (ctx); 1853 GNUNET_free (ctx);
1987 return; 1854 return;
@@ -2005,14 +1872,7 @@ notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2005 else if (ctx->connect_attempts > 0) 1872 else if (ctx->connect_attempts > 0)
2006 { 1873 {
2007 ctx->d1core_ready = GNUNET_NO; 1874 ctx->d1core_ready = GNUNET_NO;
2008#if CONNECT_CORE2 1875 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&reattempt_daemons_connect, ctx);
2009 if (ctx->d2core != NULL)
2010 {
2011 GNUNET_CORE_disconnect (ctx->d2core);
2012 ctx->d2core = NULL;
2013 }
2014#endif
2015 GNUNET_SCHEDULER_add_now (&reattempt_daemons_connect, ctx);
2016 return; 1876 return;
2017 } 1877 }
2018 else 1878 else
@@ -2023,7 +1883,6 @@ notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2023 ctx->d2->cfg, ctx->d1, ctx->d2, _("Peers failed to connect")); 1883 ctx->d2->cfg, ctx->d1, ctx->d2, _("Peers failed to connect"));
2024 } 1884 }
2025 } 1885 }
2026
2027 GNUNET_free (ctx); 1886 GNUNET_free (ctx);
2028} 1887}
2029 1888
@@ -2031,7 +1890,7 @@ notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2031/** 1890/**
2032 * Success, connection is up. Signal client our success. 1891 * Success, connection is up. Signal client our success.
2033 * 1892 *
2034 * @param cls our "struct ConnectContext" 1893 * @param cls our "struct GNUNET_TESTING_ConnectContext"
2035 * @param peer identity of the peer that has connected 1894 * @param peer identity of the peer that has connected
2036 * @param atsi performance information 1895 * @param atsi performance information
2037 * 1896 *
@@ -2040,64 +1899,36 @@ static void
2040connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, 1899connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer,
2041 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 1900 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2042{ 1901{
2043 struct ConnectContext *ctx = cls; 1902 struct GNUNET_TESTING_ConnectContext *ctx = cls;
2044 1903
2045#if DEBUG_TESTING 1904#if DEBUG_TESTING
2046 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Connected peer %s to peer %s\n", 1905 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Connected peer %s to peer %s\n",
2047 ctx->d1->shortname, GNUNET_i2s (peer)); 1906 ctx->d1->shortname, GNUNET_i2s (peer));
2048#endif 1907#endif
2049 1908
2050 if (0 == memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity))) 1909 if (0 != memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity)))
2051 { 1910 return;
2052 1911 ctx->connected = GNUNET_YES;
2053 ctx->connected = GNUNET_YES; 1912 ctx->distance = 0; /* FIXME: distance */
2054 ctx->distance = 0; /* FIXME: distance */ 1913 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK)
2055 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK)
2056 { 1914 {
2057 GNUNET_SCHEDULER_cancel (ctx->hello_send_task); 1915 GNUNET_SCHEDULER_cancel (ctx->hello_send_task);
2058 ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK; 1916 ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK;
2059 } 1917 }
2060 GNUNET_SCHEDULER_cancel (ctx->timeout_task); 1918 GNUNET_SCHEDULER_cancel (ctx->timeout_task);
2061 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result, ctx); 1919 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result, ctx);
2062 }
2063}
2064
2065#if CONNECT_CORE2
2066/**
2067 * Success, connection is up. Signal client our success.
2068 *
2069 * @param cls our "struct ConnectContext"
2070 * @param peer identity of the peer that has connected
2071 * @param atsi performance information
2072 *
2073 */
2074static void
2075connect_notify_core2 (void *cls, const struct GNUNET_PeerIdentity *peer,
2076 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2077{
2078 struct ConnectContext *ctx = cls;
2079
2080 if (memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity)) == 0)
2081 {
2082 ctx->connected = GNUNET_YES;
2083 ctx->distance = 0; /* FIXME: distance */
2084 GNUNET_SCHEDULER_cancel (ctx->timeout_task);
2085 ctx->timeout_task = GNUNET_SCHEDULER_add_now (&notify_connect_result, ctx);
2086 }
2087
2088} 1920}
2089#endif
2090 1921
2091/** 1922/**
2092 * Task called once a core connect request has been transmitted. 1923 * Task called once a core connect request has been transmitted.
2093 * 1924 *
2094 * @param cls struct ConnectContext 1925 * @param cls struct GNUNET_TESTING_ConnectContext
2095 * @param success was the request successful? 1926 * @param success was the request successful?
2096 */ 1927 */
2097void 1928void
2098core_connect_request_cont (void *cls, int success) 1929core_connect_request_cont (void *cls, int success)
2099{ 1930{
2100 struct ConnectContext *ctx = cls; 1931 struct GNUNET_TESTING_ConnectContext *ctx = cls;
2101 1932
2102 ctx->connect_request_handle = NULL; 1933 ctx->connect_request_handle = NULL;
2103} 1934}
@@ -2105,7 +1936,7 @@ core_connect_request_cont (void *cls, int success)
2105static void 1936static void
2106send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1937send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2107{ 1938{
2108 struct ConnectContext *ctx = cls; 1939 struct GNUNET_TESTING_ConnectContext *ctx = cls;
2109 struct GNUNET_MessageHeader *hello; 1940 struct GNUNET_MessageHeader *hello;
2110 1941
2111 ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK; 1942 ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK;
@@ -2156,7 +1987,7 @@ core_init_notify (void *cls, struct GNUNET_CORE_Handle *server,
2156 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded 1987 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
2157 *publicKey) 1988 *publicKey)
2158{ 1989{
2159 struct ConnectContext *connect_ctx = cls; 1990 struct GNUNET_TESTING_ConnectContext *connect_ctx = cls;
2160 1991
2161 connect_ctx->d1core_ready = GNUNET_YES; 1992 connect_ctx->d1core_ready = GNUNET_YES;
2162 1993
@@ -2182,13 +2013,11 @@ static void
2182reattempt_daemons_connect (void *cls, 2013reattempt_daemons_connect (void *cls,
2183 const struct GNUNET_SCHEDULER_TaskContext *tc) 2014 const struct GNUNET_SCHEDULER_TaskContext *tc)
2184{ 2015{
2185 struct ConnectContext *ctx = cls; 2016 struct GNUNET_TESTING_ConnectContext *ctx = cls;
2186 2017
2018 ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2187 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 2019 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
2188 {
2189 GNUNET_free (ctx);
2190 return; 2020 return;
2191 }
2192#if DEBUG_TESTING_RECONNECT 2021#if DEBUG_TESTING_RECONNECT
2193 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2022 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2194 "re-attempting connect of peer %s to peer %s\n", 2023 "re-attempting connect of peer %s to peer %s\n",
@@ -2264,6 +2093,7 @@ reattempt_daemons_connect (void *cls,
2264 _("Failed to connect to transport service!\n")); 2093 _("Failed to connect to transport service!\n"));
2265 return; 2094 return;
2266 } 2095 }
2096 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == ctx->hello_send_task);
2267 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx); 2097 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx);
2268 } 2098 }
2269 else 2099 else
@@ -2282,7 +2112,7 @@ reattempt_daemons_connect (void *cls,
2282 * that we don't try to send duplicate connect 2112 * that we don't try to send duplicate connect
2283 * requests to core. 2113 * requests to core.
2284 * 2114 *
2285 * @param cls our "struct ConnectContext" 2115 * @param cls our "struct GNUNET_TESTING_ConnectContext"
2286 * @param peer identity of the peer that has connected, 2116 * @param peer identity of the peer that has connected,
2287 * NULL when iteration has finished 2117 * NULL when iteration has finished
2288 * @param atsi performance information 2118 * @param atsi performance information
@@ -2292,7 +2122,7 @@ static void
2292core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer, 2122core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer,
2293 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 2123 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2294{ 2124{
2295 struct ConnectContext *ctx = cls; 2125 struct GNUNET_TESTING_ConnectContext *ctx = cls;
2296 2126
2297 if ((peer != NULL) && 2127 if ((peer != NULL) &&
2298 (0 == memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity)))) 2128 (0 == memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity))))
@@ -2301,8 +2131,11 @@ core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer,
2301 ctx->distance = 0; /* FIXME: distance */ 2131 ctx->distance = 0; /* FIXME: distance */
2302 return; 2132 return;
2303 } 2133 }
2304 else if (peer == NULL) /* End of iteration over peers */ 2134 if (peer != NULL)
2305 { 2135 return; /* ignore other peers */
2136 /* peer == NULL: End of iteration over peers */
2137
2138 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == ctx->timeout_task);
2306 if (ctx->connected == GNUNET_YES) 2139 if (ctx->connected == GNUNET_YES)
2307 { 2140 {
2308 ctx->timeout_task = 2141 ctx->timeout_task =
@@ -2325,11 +2158,8 @@ core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer,
2325 2158
2326 if (ctx->d1core == NULL) 2159 if (ctx->d1core == NULL)
2327 { 2160 {
2328 GNUNET_free (ctx); 2161 ctx->timeout_task =
2329 if (NULL != ctx->cb) 2162 GNUNET_SCHEDULER_add_now (&notify_connect_result, ctx);
2330 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg,
2331 ctx->d2->cfg, ctx->d1, ctx->d2,
2332 _("Failed to connect to core service of first peer!\n"));
2333 return; 2163 return;
2334 } 2164 }
2335 2165
@@ -2341,11 +2171,9 @@ core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer,
2341 if (ctx->d2->th == NULL) 2171 if (ctx->d2->th == NULL)
2342 { 2172 {
2343 GNUNET_CORE_disconnect (ctx->d1core); 2173 GNUNET_CORE_disconnect (ctx->d1core);
2344 GNUNET_free (ctx); 2174 ctx->d1core = NULL;
2345 if (NULL != ctx->cb) 2175 ctx->timeout_task =
2346 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, 2176 GNUNET_SCHEDULER_add_now (&notify_connect_result, ctx);
2347 ctx->d2->cfg, ctx->d1, ctx->d2,
2348 _("Failed to connect to transport service!\n"));
2349 return; 2177 return;
2350 } 2178 }
2351 ctx->d2->ghh = 2179 ctx->d2->ghh =
@@ -2360,25 +2188,27 @@ core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer,
2360 if (ctx->d1th == NULL) 2188 if (ctx->d1th == NULL)
2361 { 2189 {
2362 GNUNET_CORE_disconnect (ctx->d1core); 2190 GNUNET_CORE_disconnect (ctx->d1core);
2363 GNUNET_free (ctx); 2191 ctx->d1core = NULL;
2364 if (NULL != ctx->cb) 2192 ctx->timeout_task =
2365 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, 2193 GNUNET_SCHEDULER_add_now (&notify_connect_result, ctx);
2366 ctx->d2->cfg, ctx->d1, ctx->d2,
2367 _("Failed to connect to transport service!\n"));
2368 return; 2194 return;
2369 } 2195 }
2196 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == ctx->hello_send_task);
2370 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx); 2197 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx);
2371 } 2198 }
2372 2199
2373 ctx->timeout_task = 2200 ctx->timeout_task =
2374 GNUNET_SCHEDULER_add_delayed (ctx->relative_timeout, 2201 GNUNET_SCHEDULER_add_delayed (ctx->relative_timeout,
2375 &notify_connect_result, ctx); 2202 &notify_connect_result, ctx);
2376 } 2203
2377} 2204}
2378 2205
2379 2206
2380/** 2207/**
2381 * Establish a connection between two GNUnet daemons. 2208 * Establish a connection between two GNUnet daemons. The daemons
2209 * must both be running and not be stopped until either the
2210 * 'cb' callback is called OR the connection request has been
2211 * explicitly cancelled.
2382 * 2212 *
2383 * @param d1 handle for the first daemon 2213 * @param d1 handle for the first daemon
2384 * @param d2 handle for the second daemon 2214 * @param d2 handle for the second daemon
@@ -2390,8 +2220,9 @@ core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer,
2390 * the HELLO has already been exchanged 2220 * the HELLO has already been exchanged
2391 * @param cb function to call at the end 2221 * @param cb function to call at the end
2392 * @param cb_cls closure for cb 2222 * @param cb_cls closure for cb
2223 * @return handle to cancel the request
2393 */ 2224 */
2394void 2225struct GNUNET_TESTING_ConnectContext *
2395GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1, 2226GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
2396 struct GNUNET_TESTING_Daemon *d2, 2227 struct GNUNET_TESTING_Daemon *d2,
2397 struct GNUNET_TIME_Relative timeout, 2228 struct GNUNET_TIME_Relative timeout,
@@ -2400,7 +2231,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
2400 GNUNET_TESTING_NotifyConnection cb, 2231 GNUNET_TESTING_NotifyConnection cb,
2401 void *cb_cls) 2232 void *cb_cls)
2402{ 2233{
2403 struct ConnectContext *ctx; 2234 struct GNUNET_TESTING_ConnectContext *ctx;
2404 2235
2405 if ((d1->running == GNUNET_NO) || (d2->running == GNUNET_NO)) 2236 if ((d1->running == GNUNET_NO) || (d2->running == GNUNET_NO))
2406 { 2237 {
@@ -2408,10 +2239,10 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
2408 cb (cb_cls, &d1->id, &d2->id, 0, d1->cfg, d2->cfg, d1, d2, 2239 cb (cb_cls, &d1->id, &d2->id, 0, d1->cfg, d2->cfg, d1, d2,
2409 _("Peers are not fully running yet, can not connect!\n")); 2240 _("Peers are not fully running yet, can not connect!\n"));
2410 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Peers are not up!\n"); 2241 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Peers are not up!\n");
2411 return; 2242 return NULL;
2412 } 2243 }
2413 2244
2414 ctx = GNUNET_malloc (sizeof (struct ConnectContext)); 2245 ctx = GNUNET_malloc (sizeof (struct GNUNET_TESTING_ConnectContext));
2415 ctx->d1 = d1; 2246 ctx->d1 = d1;
2416 ctx->d2 = d2; 2247 ctx->d2 = d2;
2417 ctx->timeout_hello = 2248 ctx->timeout_hello =
@@ -2432,7 +2263,41 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
2432 GNUNET_assert (GNUNET_OK == 2263 GNUNET_assert (GNUNET_OK ==
2433 GNUNET_CORE_is_peer_connected (ctx->d1->cfg, &ctx->d2->id, 2264 GNUNET_CORE_is_peer_connected (ctx->d1->cfg, &ctx->d2->id,
2434 &core_initial_iteration, ctx)); 2265 &core_initial_iteration, ctx));
2435 /*GNUNET_assert(GNUNET_OK == GNUNET_CORE_iterate_peers (ctx->d1->cfg, &core_initial_iteration, ctx)); */ 2266 return ctx;
2436} 2267}
2437 2268
2269
2270/**
2271 * Cancel an attempt to connect two daemons.
2272 *
2273 * @param cc connect context
2274 */
2275void
2276GNUNET_TESTING_daemons_connect_cancel (struct GNUNET_TESTING_ConnectContext
2277 *cc)
2278{
2279 if (GNUNET_SCHEDULER_NO_TASK != cc->timeout_task)
2280 {
2281 GNUNET_SCHEDULER_cancel (cc->timeout_task);
2282 cc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2283 }
2284 if (GNUNET_SCHEDULER_NO_TASK != cc->hello_send_task)
2285 {
2286 GNUNET_SCHEDULER_cancel (cc->hello_send_task);
2287 cc->hello_send_task = GNUNET_SCHEDULER_NO_TASK;
2288 }
2289 if (NULL != cc->d1core)
2290 {
2291 GNUNET_CORE_disconnect (cc->d1core);
2292 cc->d1core = NULL;
2293 }
2294 if (NULL != cc->d1th)
2295 {
2296 GNUNET_TRANSPORT_disconnect (cc->d1th);
2297 cc->d1th = NULL;
2298 }
2299 GNUNET_free (cc);
2300}
2301
2302
2438/* end of testing.c */ 2303/* end of testing.c */
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index 88c51abe0..c81373025 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -23,7 +23,6 @@
23 * @brief convenience API for writing testcases for GNUnet 23 * @brief convenience API for writing testcases for GNUnet
24 * @author Nathan Evans 24 * @author Nathan Evans
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 *
27 */ 26 */
28#include "platform.h" 27#include "platform.h"
29#include "gnunet_constants.h" 28#include "gnunet_constants.h"
@@ -710,6 +709,8 @@ struct ConnectTopologyContext
710 void *notify_cls; 709 void *notify_cls;
711}; 710};
712 711
712struct ConnectContext;
713
713/** 714/**
714 * Handle to a group of GNUnet peers. 715 * Handle to a group of GNUnet peers.
715 */ 716 */
@@ -720,6 +721,10 @@ struct GNUNET_TESTING_PeerGroup
720 */ 721 */
721 const struct GNUNET_CONFIGURATION_Handle *cfg; 722 const struct GNUNET_CONFIGURATION_Handle *cfg;
722 723
724 struct ConnectContext *cc_head;
725
726 struct ConnectContext *cc_tail;
727
723 /** 728 /**
724 * Function to call on each started daemon. 729 * Function to call on each started daemon.
725 */ 730 */
@@ -866,6 +871,11 @@ struct UpdateContext
866 871
867struct ConnectContext 872struct ConnectContext
868{ 873{
874
875 struct ConnectContext *next;
876
877 struct ConnectContext *prev;
878
869 /** 879 /**
870 * Index of peer to connect second to. 880 * Index of peer to connect second to.
871 */ 881 */
@@ -877,6 +887,16 @@ struct ConnectContext
877 uint32_t second_index; 887 uint32_t second_index;
878 888
879 /** 889 /**
890 * Task associated with the attempt to connect.
891 */
892 GNUNET_SCHEDULER_TaskIdentifier task;
893
894 /**
895 * Context in 'testing.c', to cancel connection attempt.
896 */
897 struct GNUNET_TESTING_ConnectContext *cc;
898
899 /**
880 * Higher level topology connection context. 900 * Higher level topology connection context.
881 */ 901 */
882 struct ConnectTopologyContext *ct_ctx; 902 struct ConnectTopologyContext *ct_ctx;
@@ -3188,7 +3208,7 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
3188 * Choose a random peer's next connection to create, and 3208 * Choose a random peer's next connection to create, and
3189 * call schedule_connect to set up the connect task. 3209 * call schedule_connect to set up the connect task.
3190 * 3210 *
3191 * @param ct_ctx the overall connection context 3211 * @param pg the peer group to connect
3192 */ 3212 */
3193static void 3213static void
3194preschedule_connect (struct GNUNET_TESTING_PeerGroup *pg) 3214preschedule_connect (struct GNUNET_TESTING_PeerGroup *pg)
@@ -3211,7 +3231,10 @@ preschedule_connect (struct GNUNET_TESTING_PeerGroup *pg)
3211 connect_context->first_index = random_peer; 3231 connect_context->first_index = random_peer;
3212 connect_context->second_index = connection_iter->index; 3232 connect_context->second_index = connection_iter->index;
3213 connect_context->ct_ctx = ct_ctx; 3233 connect_context->ct_ctx = ct_ctx;
3214 GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context); 3234 connect_context->task = GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
3235 GNUNET_CONTAINER_DLL_insert (pg->cc_head,
3236 pg->cc_tail,
3237 connect_context);
3215 GNUNET_CONTAINER_DLL_remove (pg->peers[random_peer].connect_peers_head, 3238 GNUNET_CONTAINER_DLL_remove (pg->peers[random_peer].connect_peers_head,
3216 pg->peers[random_peer].connect_peers_tail, 3239 pg->peers[random_peer].connect_peers_tail,
3217 connection_iter); 3240 connection_iter);
@@ -3508,15 +3531,6 @@ hello_sent_callback (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3508 GNUNET_assert (send_hello_context->peer->daemon->th != NULL); 3531 GNUNET_assert (send_hello_context->peer->daemon->th != NULL);
3509 GNUNET_TRANSPORT_disconnect (send_hello_context->peer->daemon->th); 3532 GNUNET_TRANSPORT_disconnect (send_hello_context->peer->daemon->th);
3510 send_hello_context->peer->daemon->th = NULL; 3533 send_hello_context->peer->daemon->th = NULL;
3511
3512 /*if (send_hello_context->pg->remaining_hellos == 0)
3513 * {
3514 * for (pg_iter = 0; pg_iter < send_hello_context->pg->max_outstanding_connections; pg_iter++)
3515 * {
3516 * preschedule_connect(&send_hello_context->pg->ct_ctx);
3517 * }
3518 * }
3519 */
3520 GNUNET_assert (send_hello_context->peer->daemon->server == NULL); 3534 GNUNET_assert (send_hello_context->peer->daemon->server == NULL);
3521 send_hello_context->peer->daemon->server = 3535 send_hello_context->peer->daemon->server =
3522 GNUNET_CORE_connect (send_hello_context->peer->cfg, 1, 3536 GNUNET_CORE_connect (send_hello_context->peer->cfg, 1,
@@ -3621,9 +3635,13 @@ internal_connect_notify (void *cls, const struct GNUNET_PeerIdentity *first,
3621 struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg; 3635 struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg;
3622 struct PeerConnection *connection; 3636 struct PeerConnection *connection;
3623 3637
3638 GNUNET_assert (NULL != connect_ctx->cc);
3639 connect_ctx->cc = NULL;
3624 GNUNET_assert (0 < pg->outstanding_connects); 3640 GNUNET_assert (0 < pg->outstanding_connects);
3625 pg->outstanding_connects--; 3641 pg->outstanding_connects--;
3626 3642 GNUNET_CONTAINER_DLL_remove (pg->cc_head,
3643 pg->cc_tail,
3644 connect_ctx);
3627 /* 3645 /*
3628 * Check whether the inverse connection has been scheduled yet, 3646 * Check whether the inverse connection has been scheduled yet,
3629 * if not, we can remove it from the other peers list and avoid 3647 * if not, we can remove it from the other peers list and avoid
@@ -3638,9 +3656,7 @@ internal_connect_notify (void *cls, const struct GNUNET_PeerIdentity *first,
3638 (0 != 3656 (0 !=
3639 memcmp (first, &pg->peers[connection->index].daemon->id, 3657 memcmp (first, &pg->peers[connection->index].daemon->id,
3640 sizeof (struct GNUNET_PeerIdentity)))) 3658 sizeof (struct GNUNET_PeerIdentity))))
3641 {
3642 connection = connection->next; 3659 connection = connection->next;
3643 }
3644 3660
3645 if (connection != NULL) /* Can safely remove! */ 3661 if (connection != NULL) /* Can safely remove! */
3646 { 3662 {
@@ -3675,7 +3691,6 @@ internal_connect_notify (void *cls, const struct GNUNET_PeerIdentity *first,
3675 pg->notify_connection (pg->notify_connection_cls, first, second, distance, 3691 pg->notify_connection (pg->notify_connection_cls, first, second, distance,
3676 first_cfg, second_cfg, first_daemon, second_daemon, 3692 first_cfg, second_cfg, first_daemon, second_daemon,
3677 emsg); 3693 emsg);
3678
3679 GNUNET_free (connect_ctx); 3694 GNUNET_free (connect_ctx);
3680} 3695}
3681 3696
@@ -3692,6 +3707,7 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3692 struct ConnectContext *connect_context = cls; 3707 struct ConnectContext *connect_context = cls;
3693 struct GNUNET_TESTING_PeerGroup *pg = connect_context->ct_ctx->pg; 3708 struct GNUNET_TESTING_PeerGroup *pg = connect_context->ct_ctx->pg;
3694 3709
3710 connect_context->task = GNUNET_SCHEDULER_NO_TASK;
3695 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 3711 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
3696 return; 3712 return;
3697 3713
@@ -3703,12 +3719,11 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3703 _ 3719 _
3704 ("Delaying connect, we have too many outstanding connections!\n")); 3720 ("Delaying connect, we have too many outstanding connections!\n"));
3705#endif 3721#endif
3706 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 3722 connect_context->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
3707 (GNUNET_TIME_UNIT_MILLISECONDS, 100), 3723 (GNUNET_TIME_UNIT_MILLISECONDS, 100),
3708 &schedule_connect, connect_context); 3724 &schedule_connect, connect_context);
3725 return;
3709 } 3726 }
3710 else
3711 {
3712#if VERBOSE_TESTING 3727#if VERBOSE_TESTING
3713 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3728 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3714 _ 3729 _
@@ -3717,7 +3732,9 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3717#endif 3732#endif
3718 pg->outstanding_connects++; 3733 pg->outstanding_connects++;
3719 pg->total_connects_scheduled++; 3734 pg->total_connects_scheduled++;
3720 GNUNET_TESTING_daemons_connect (pg-> 3735 GNUNET_assert (NULL == connect_context->cc);
3736 connect_context->cc
3737 = GNUNET_TESTING_daemons_connect (pg->
3721 peers[connect_context->first_index].daemon, 3738 peers[connect_context->first_index].daemon,
3722 pg->peers[connect_context-> 3739 pg->peers[connect_context->
3723 second_index].daemon, 3740 second_index].daemon,
@@ -3728,8 +3745,8 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3728#else 3745#else
3729 GNUNET_YES, 3746 GNUNET_YES,
3730#endif 3747#endif
3731 &internal_connect_notify, connect_context); /* FIXME: free connect context! */ 3748 &internal_connect_notify, connect_context);
3732 } 3749
3733} 3750}
3734 3751
3735#if !OLD 3752#if !OLD
@@ -3755,8 +3772,10 @@ connect_iterator (void *cls, const GNUNET_HashCode * key, void *value)
3755 connect_context->first = first->daemon; 3772 connect_context->first = first->daemon;
3756 connect_context->second = second; 3773 connect_context->second = second;
3757 connect_context->ct_ctx = ct_ctx; 3774 connect_context->ct_ctx = ct_ctx;
3758 GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context); 3775 connect_context->task = GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
3759 3776 GNUNET_CONTAINER_DLL_insert (ct_ctx->pg->cc_head,
3777 ct_ctx->pg->cc_tail,
3778 connect_context);
3760 return GNUNET_YES; 3779 return GNUNET_YES;
3761} 3780}
3762#endif 3781#endif
@@ -7080,8 +7099,20 @@ GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg,
7080 struct PeerConnection *conn_iter; 7099 struct PeerConnection *conn_iter;
7081 struct PeerConnection *temp_conn; 7100 struct PeerConnection *temp_conn;
7082#endif 7101#endif
7102 struct ConnectContext *cc;
7083 7103
7084 GNUNET_assert (pg->total > 0); 7104 GNUNET_assert (pg->total > 0);
7105 while (NULL != (cc = pg->cc_head))
7106 {
7107 GNUNET_CONTAINER_DLL_remove (pg->cc_head,
7108 pg->cc_tail,
7109 cc);
7110 if (GNUNET_SCHEDULER_NO_TASK != cc->task)
7111 GNUNET_SCHEDULER_cancel (cc->task);
7112 if (NULL != cc->cc)
7113 GNUNET_TESTING_daemons_connect_cancel (cc->cc);
7114 GNUNET_free (cc);
7115 }
7085 7116
7086 shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext)); 7117 shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext));
7087 shutdown_ctx->delete_files = 7118 shutdown_ctx->delete_files =
@@ -7091,7 +7122,6 @@ GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg,
7091 shutdown_ctx->total_peers = pg->total; 7122 shutdown_ctx->total_peers = pg->total;
7092 shutdown_ctx->timeout = timeout; 7123 shutdown_ctx->timeout = timeout;
7093 shutdown_ctx->pg = pg; 7124 shutdown_ctx->pg = pg;
7094 /* shtudown_ctx->outstanding = 0; */
7095 7125
7096 for (off = 0; off < pg->total; off++) 7126 for (off = 0; off < pg->total; off++)
7097 { 7127 {
diff --git a/src/topology/test_gnunet_daemon_topology.c b/src/topology/test_gnunet_daemon_topology.c
index c9a43ecd7..3429f50ec 100644
--- a/src/topology/test_gnunet_daemon_topology.c
+++ b/src/topology/test_gnunet_daemon_topology.c
@@ -49,6 +49,11 @@ static struct GNUNET_TESTING_Daemon *first;
49static struct GNUNET_TESTING_Daemon *last; 49static struct GNUNET_TESTING_Daemon *last;
50 50
51/** 51/**
52 * Active connection attempt.
53 */
54struct GNUNET_TESTING_ConnectContext *cc[NUM_PEERS];
55
56/**
52 * Check whether peers successfully shut down. 57 * Check whether peers successfully shut down.
53 */ 58 */
54static void 59static void
@@ -74,6 +79,16 @@ shutdown_callback (void *cls, const char *emsg)
74static void 79static void
75clean_up_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 80clean_up_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
76{ 81{
82 unsigned int i;
83
84 for (i=0;i<NUM_PEERS;i++)
85 {
86 if (NULL != cc[i])
87 {
88 GNUNET_TESTING_daemons_connect_cancel (cc[i]);
89 cc[i] = NULL;
90 }
91 }
77 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); 92 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
78 ok = 0; 93 ok = 0;
79} 94}
@@ -89,9 +104,19 @@ notify_connect_complete (void *cls, const struct GNUNET_PeerIdentity *first,
89 struct GNUNET_TESTING_Daemon *second_daemon, 104 struct GNUNET_TESTING_Daemon *second_daemon,
90 const char *emsg) 105 const char *emsg)
91{ 106{
107 struct GNUNET_TESTING_ConnectContext **cc;
108 unsigned int i;
109
110 *cc = NULL;
92 if (NULL != emsg) 111 if (NULL != emsg)
93 { 112 {
94 fprintf (stderr, "Failed to connect two peers: %s\n", emsg); 113 fprintf (stderr, "Failed to connect two peers: %s\n", emsg);
114 for (i=0;i<NUM_PEERS;i++)
115 if (NULL != cc[i])
116 {
117 GNUNET_TESTING_daemons_connect_cancel (cc[i]);
118 cc[i] = NULL;
119 }
95 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); 120 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
96 GNUNET_assert (0); 121 GNUNET_assert (0);
97 return; 122 return;
@@ -120,13 +145,13 @@ my_cb (void *cls, const struct GNUNET_PeerIdentity *id,
120 last = d; 145 last = d;
121 return; 146 return;
122 } 147 }
123 GNUNET_TESTING_daemons_connect (last, d, TIMEOUT, CONNECT_ATTEMPTS, 148 cc[peers_left] = GNUNET_TESTING_daemons_connect (last, d, TIMEOUT, CONNECT_ATTEMPTS,
124 GNUNET_YES, &notify_connect_complete, NULL); 149 GNUNET_YES, &notify_connect_complete, &cc[peers_left]);
125 if (peers_left == 0) 150 if (peers_left == 0)
126 { 151 {
127 /* close circle */ 152 /* close circle */
128 GNUNET_TESTING_daemons_connect (d, first, TIMEOUT, CONNECT_ATTEMPTS, 153 cc[NUM_PEERS-1] = GNUNET_TESTING_daemons_connect (d, first, TIMEOUT, CONNECT_ATTEMPTS,
129 GNUNET_YES, &notify_connect_complete, NULL); 154 GNUNET_YES, &notify_connect_complete, &cc[peers_left]);
130 } 155 }
131} 156}
132 157