aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2011-02-22 15:19:49 +0000
committerNathan S. Evans <evans@in.tum.de>2011-02-22 15:19:49 +0000
commit7c0698d2296e00d9544f48819f24ed4319e3fad8 (patch)
tree343507da792d950d8d24ed11648e433bcad304a9 /src/testing
parentac5cf07b590f788946d4b05f8e11b2414493f4eb (diff)
downloadgnunet-7c0698d2296e00d9544f48819f24ed4319e3fad8.tar.gz
gnunet-7c0698d2296e00d9544f48819f24ed4319e3fad8.zip
Testing and core related changes.
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/test_testing_topology.c11
-rw-r--r--src/testing/testing.c380
-rw-r--r--src/testing/testing_group.c690
3 files changed, 830 insertions, 251 deletions
diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c
index 5af3e9ed2..b328873f2 100644
--- a/src/testing/test_testing_topology.c
+++ b/src/testing/test_testing_topology.c
@@ -1027,6 +1027,7 @@ run (void *cls,
1027 char *connect_topology_option_str; 1027 char *connect_topology_option_str;
1028 char *connect_topology_option_modifier_string; 1028 char *connect_topology_option_modifier_string;
1029 unsigned long long temp_settle; 1029 unsigned long long temp_settle;
1030 unsigned long long max_outstanding_connections;
1030 ok = 1; 1031 ok = 1;
1031 1032
1032 dotOutFile = fopen (dotOutFileName, "w"); 1033 dotOutFile = fopen (dotOutFileName, "w");
@@ -1152,6 +1153,14 @@ run (void *cls,
1152 return; 1153 return;
1153 } 1154 }
1154 1155
1156 if (GNUNET_OK !=
1157 GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "max_outstanding_connections",
1158 &max_outstanding_connections))
1159 {
1160 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", "testing", "max_outstanding_connections");
1161 return;
1162 }
1163
1155 if (GNUNET_SYSERR == 1164 if (GNUNET_SYSERR ==
1156 GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", 1165 GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
1157 &num_peers)) 1166 &num_peers))
@@ -1180,7 +1189,7 @@ run (void *cls,
1180 GNUNET_assert (num_peers > 0 && num_peers < (unsigned int) -1); 1189 GNUNET_assert (num_peers > 0 && num_peers < (unsigned int) -1);
1181 pg = GNUNET_TESTING_daemons_start (cfg, 1190 pg = GNUNET_TESTING_daemons_start (cfg,
1182 peers_left, 1191 peers_left,
1183 peers_left / 2, 1192 max_outstanding_connections,
1184 peers_left, 1193 peers_left,
1185 GNUNET_TIME_relative_multiply 1194 GNUNET_TIME_relative_multiply
1186 (GNUNET_TIME_UNIT_SECONDS, 1195 (GNUNET_TIME_UNIT_SECONDS,
diff --git a/src/testing/testing.c b/src/testing/testing.c
index ddfe17d43..4a321c6e6 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -38,7 +38,7 @@
38#include "gnunet_hello_lib.h" 38#include "gnunet_hello_lib.h"
39 39
40#define DEBUG_TESTING GNUNET_NO 40#define DEBUG_TESTING GNUNET_NO
41#define DEBUG_TESTING_RECONNECT GNUNET_NO 41#define DEBUG_TESTING_RECONNECT GNUNET_YES
42 42
43/** 43/**
44 * How long do we wait after starting gnunet-service-arm 44 * How long do we wait after starting gnunet-service-arm
@@ -65,10 +65,19 @@ static void
65process_hello (void *cls, const struct GNUNET_MessageHeader *message) 65process_hello (void *cls, const struct GNUNET_MessageHeader *message)
66{ 66{
67 struct GNUNET_TESTING_Daemon *daemon = cls; 67 struct GNUNET_TESTING_Daemon *daemon = cls;
68 GNUNET_TESTING_NotifyDaemonRunning cb;
69
68 int msize; 70 int msize;
69 if (daemon == NULL) 71 if (daemon == NULL)
70 return; 72 return;
71 73
74 GNUNET_assert (daemon->phase == SP_GET_HELLO);
75
76 cb = daemon->cb;
77 daemon->cb = NULL;
78 if (daemon->task != GNUNET_SCHEDULER_NO_TASK) /* Assertion here instead? */
79 GNUNET_SCHEDULER_cancel(daemon->task);
80
72 if (daemon->server != NULL) 81 if (daemon->server != NULL)
73 { 82 {
74#if DEBUG_TESTING 83#if DEBUG_TESTING
@@ -105,9 +114,15 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message)
105 GNUNET_TRANSPORT_disconnect (daemon->th); 114 GNUNET_TRANSPORT_disconnect (daemon->th);
106 daemon->th = NULL; 115 daemon->th = NULL;
107 } 116 }
117 daemon->phase = SP_START_DONE;
108 118
119 if (NULL != cb) /* FIXME: what happens when this callback calls GNUNET_TESTING_daemon_stop? */
120 cb (daemon->cb_cls, &daemon->id, daemon->cfg, daemon, NULL);
109} 121}
110 122
123static void
124start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
125
111/** 126/**
112 * Function called after GNUNET_CORE_connect has succeeded 127 * Function called after GNUNET_CORE_connect has succeeded
113 * (or failed for good). Note that the private key of the 128 * (or failed for good). Note that the private key of the
@@ -127,12 +142,10 @@ testing_init (void *cls,
127 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) 142 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
128{ 143{
129 struct GNUNET_TESTING_Daemon *d = cls; 144 struct GNUNET_TESTING_Daemon *d = cls;
130 GNUNET_TESTING_NotifyDaemonRunning cb;
131 145
132 GNUNET_assert (d->phase == SP_START_CORE); 146 GNUNET_assert (d->phase == SP_START_CORE);
133 d->phase = SP_START_DONE; 147 d->phase = SP_GET_HELLO;
134 cb = d->cb; 148
135 d->cb = NULL;
136 if (server == NULL) 149 if (server == NULL)
137 { 150 {
138 d->server = NULL; 151 d->server = NULL;
@@ -141,8 +154,8 @@ testing_init (void *cls,
141 GNUNET_TIME_absolute_get_remaining 154 GNUNET_TIME_absolute_get_remaining
142 (d->max_timeout), d->dead_cb, 155 (d->max_timeout), d->dead_cb,
143 d->dead_cb_cls, GNUNET_YES, GNUNET_NO); 156 d->dead_cb_cls, GNUNET_YES, GNUNET_NO);
144 else if (NULL != cb) 157 else if (NULL != d->cb)
145 cb (d->cb_cls, NULL, d->cfg, d, 158 d->cb (d->cb_cls, NULL, d->cfg, d,
146 _("Failed to connect to core service\n")); 159 _("Failed to connect to core service\n"));
147 return; 160 return;
148 } 161 }
@@ -155,9 +168,6 @@ testing_init (void *cls,
155 d->server = server; 168 d->server = server;
156 d->running = GNUNET_YES; 169 d->running = GNUNET_YES;
157 170
158 if (NULL != cb) /* FIXME: what happens when this callback calls GNUNET_TESTING_daemon_stop? */
159 cb (d->cb_cls, my_identity, d->cfg, d, NULL);
160
161 if (GNUNET_NO == d->running) 171 if (GNUNET_NO == d->running)
162 { 172 {
163#if DEBUG_TESTING 173#if DEBUG_TESTING
@@ -192,6 +202,12 @@ testing_init (void *cls,
192#endif 202#endif
193 203
194 GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d); 204 GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d);
205 /* wait some more */
206 if (d->task != GNUNET_SCHEDULER_NO_TASK)
207 GNUNET_SCHEDULER_cancel(d->task);
208 d->task
209 = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT,
210 &start_fsm, d);
195} 211}
196 212
197 213
@@ -551,7 +567,12 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
551 (NULL == d->hostname) 567 (NULL == d->hostname)
552 ? _("`gnunet-arm' does not seem to terminate.\n") 568 ? _("`gnunet-arm' does not seem to terminate.\n")
553 : _("`ssh' does not seem to terminate.\n")); 569 : _("`ssh' does not seem to terminate.\n"));
570 GNUNET_CONFIGURATION_destroy (d->cfg);
571 GNUNET_free (d->cfgfile);
572 GNUNET_free_non_null (d->hostname);
573 GNUNET_free_non_null (d->username);
554 GNUNET_free(d->proc); 574 GNUNET_free(d->proc);
575 GNUNET_free(d);
555 return; 576 return;
556 } 577 }
557 /* wait some more */ 578 /* wait some more */
@@ -570,18 +591,68 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
570 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 591 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
571 "Calling CORE_connect\n"); 592 "Calling CORE_connect\n");
572#endif 593#endif
594 /* Fall through */
595 case SP_START_CORE:
596 if (d->server != NULL)
597 GNUNET_CORE_disconnect(d->server);
598
599 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value ==
600 0)
601 {
602 cb = d->cb;
603 d->cb = NULL;
604 if (NULL != cb)
605 cb (d->cb_cls,
606 NULL,
607 d->cfg,
608 d,
609 _("Unable to connect to CORE service for peer!\n"));
610 GNUNET_CONFIGURATION_destroy (d->cfg);
611 GNUNET_free (d->cfgfile);
612 GNUNET_free_non_null (d->hostname);
613 GNUNET_free_non_null (d->username);
614 GNUNET_free (d);
615 return;
616 }
573 d->server = GNUNET_CORE_connect (d->cfg, 1, 617 d->server = GNUNET_CORE_connect (d->cfg, 1,
574#if NO_MORE_TIMEOUT_FIXME
575 ARM_START_WAIT,
576#endif
577 d, 618 d,
578 &testing_init, 619 &testing_init,
579 NULL, NULL, NULL, 620 NULL, NULL, NULL,
580 NULL, GNUNET_NO, 621 NULL, GNUNET_NO,
581 NULL, GNUNET_NO, no_handlers); 622 NULL, GNUNET_NO, no_handlers);
623 d->task
624 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_CONSTANTS_SERVICE_RETRY, 2),
625 &start_fsm, d);
582 break; 626 break;
583 case SP_START_CORE: 627 case SP_GET_HELLO:
584 GNUNET_break (0); 628 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value ==
629 0)
630 {
631 if (d->server != NULL)
632 GNUNET_CORE_disconnect(d->server);
633 if (d->th != NULL)
634 GNUNET_TRANSPORT_disconnect(d->th);
635 cb = d->cb;
636 d->cb = NULL;
637 if (NULL != cb)
638 cb (d->cb_cls,
639 NULL,
640 d->cfg,
641 d,
642 _("Unable to get HELLO for peer!\n"));
643 GNUNET_CONFIGURATION_destroy (d->cfg);
644 GNUNET_free (d->cfgfile);
645 GNUNET_free_non_null (d->hostname);
646 GNUNET_free_non_null (d->username);
647 GNUNET_free (d);
648 return;
649 }
650 if (d->hello != NULL)
651 return;
652 GNUNET_assert(d->task == GNUNET_SCHEDULER_NO_TASK);
653 d->task
654 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_CONSTANTS_SERVICE_RETRY, 2),
655 &start_fsm, d);
585 break; 656 break;
586 case SP_START_DONE: 657 case SP_START_DONE:
587 GNUNET_break (0); 658 GNUNET_break (0);
@@ -1368,12 +1439,6 @@ struct ConnectContext
1368 void *cb_cls; 1439 void *cb_cls;
1369 1440
1370 /** 1441 /**
1371 * When should this operation be complete (or we must trigger
1372 * a timeout).
1373 */
1374 struct GNUNET_TIME_Absolute timeout;
1375
1376 /**
1377 * The relative timeout from whence this connect attempt was 1442 * The relative timeout from whence this connect attempt was
1378 * started. Allows for reconnect attempts. 1443 * started. Allows for reconnect attempts.
1379 */ 1444 */
@@ -1383,7 +1448,7 @@ struct ConnectContext
1383 * Maximum number of connect attempts, will retry connection 1448 * Maximum number of connect attempts, will retry connection
1384 * this number of times on failures. 1449 * this number of times on failures.
1385 */ 1450 */
1386 unsigned int max_connect_attempts; 1451 unsigned int connect_attempts;
1387 1452
1388 /** 1453 /**
1389 * Hello timeout task 1454 * Hello timeout task
@@ -1407,6 +1472,11 @@ struct ConnectContext
1407 int connected; 1472 int connected;
1408 1473
1409 /** 1474 /**
1475 * When connecting, do we need to send the HELLO?
1476 */
1477 int send_hello;
1478
1479 /**
1410 * The distance between the two connected peers 1480 * The distance between the two connected peers
1411 */ 1481 */
1412 uint32_t distance; 1482 uint32_t distance;
@@ -1431,8 +1501,6 @@ notify_connect_result (void *cls,
1431 const struct GNUNET_SCHEDULER_TaskContext *tc) 1501 const struct GNUNET_SCHEDULER_TaskContext *tc)
1432{ 1502{
1433 struct ConnectContext *ctx = cls; 1503 struct ConnectContext *ctx = cls;
1434 struct GNUNET_TIME_Relative remaining;
1435
1436 ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK; 1504 ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1437 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK) 1505 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK)
1438 { 1506 {
@@ -1445,6 +1513,7 @@ notify_connect_result (void *cls,
1445 GNUNET_CORE_peer_request_connect_cancel (ctx->connect_request_handle); 1513 GNUNET_CORE_peer_request_connect_cancel (ctx->connect_request_handle);
1446 ctx->connect_request_handle = NULL; 1514 ctx->connect_request_handle = NULL;
1447 } 1515 }
1516
1448 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 1517 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1449 { 1518 {
1450 if (ctx->d1th != NULL) 1519 if (ctx->d1th != NULL)
@@ -1458,12 +1527,16 @@ notify_connect_result (void *cls,
1458 ctx->d2core = NULL; 1527 ctx->d2core = NULL;
1459#endif 1528#endif
1460 ctx->d1core = NULL; 1529 ctx->d1core = NULL;
1461
1462 GNUNET_free (ctx); 1530 GNUNET_free (ctx);
1463 return; 1531 return;
1464 } 1532 }
1465 1533
1466 remaining = GNUNET_TIME_absolute_get_remaining (ctx->timeout); 1534 if (ctx->d1th != NULL)
1535 GNUNET_TRANSPORT_disconnect (ctx->d1th);
1536 ctx->d1th = NULL;
1537 if (ctx->d1core != NULL)
1538 GNUNET_CORE_disconnect (ctx->d1core);
1539 ctx->d1core = NULL;
1467 1540
1468 if (ctx->connected == GNUNET_YES) 1541 if (ctx->connected == GNUNET_YES)
1469 { 1542 {
@@ -1476,13 +1549,8 @@ notify_connect_result (void *cls,
1476 ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2, NULL); 1549 ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2, NULL);
1477 } 1550 }
1478 } 1551 }
1479 else if (remaining.rel_value > 0) 1552 else if (ctx->connect_attempts > 0)
1480 { 1553 {
1481 if (ctx->d1core != NULL)
1482 {
1483 GNUNET_CORE_disconnect (ctx->d1core);
1484 ctx->d1core = NULL;
1485 }
1486 ctx->d1core_ready = GNUNET_NO; 1554 ctx->d1core_ready = GNUNET_NO;
1487#if CONNECT_CORE2 1555#if CONNECT_CORE2
1488 if (ctx->d2core != NULL) 1556 if (ctx->d2core != NULL)
@@ -1491,12 +1559,6 @@ notify_connect_result (void *cls,
1491 ctx->d2core = NULL; 1559 ctx->d2core = NULL;
1492 } 1560 }
1493#endif 1561#endif
1494
1495 if (ctx->d1th != NULL)
1496 {
1497 GNUNET_TRANSPORT_disconnect (ctx->d1th);
1498 ctx->d1th = NULL;
1499 }
1500 GNUNET_SCHEDULER_add_now (&reattempt_daemons_connect, ctx); 1562 GNUNET_SCHEDULER_add_now (&reattempt_daemons_connect, ctx);
1501 return; 1563 return;
1502 } 1564 }
@@ -1510,12 +1572,6 @@ notify_connect_result (void *cls,
1510 } 1572 }
1511 } 1573 }
1512 1574
1513 if (ctx->d1th != NULL)
1514 GNUNET_TRANSPORT_disconnect (ctx->d1th);
1515 ctx->d1th = NULL;
1516 if (ctx->d1core != NULL)
1517 GNUNET_CORE_disconnect (ctx->d1core);
1518 ctx->d1core = NULL;
1519 GNUNET_free (ctx); 1575 GNUNET_free (ctx);
1520} 1576}
1521 1577
@@ -1535,8 +1591,15 @@ connect_notify (void *cls,
1535{ 1591{
1536 struct ConnectContext *ctx = cls; 1592 struct ConnectContext *ctx = cls;
1537 1593
1594#if DEBUG_TESTING
1595 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1596 "Connected peer %s to peer %s\n",
1597 ctx->d1->shortname, GNUNET_i2s(peer));
1598#endif
1599
1538 if (0 == memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity))) 1600 if (0 == memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity)))
1539 { 1601 {
1602
1540 ctx->connected = GNUNET_YES; 1603 ctx->connected = GNUNET_YES;
1541 ctx->distance = 0; /* FIXME: distance */ 1604 ctx->distance = 0; /* FIXME: distance */
1542 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK) 1605 if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK)
@@ -1606,17 +1669,16 @@ send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1606 { 1669 {
1607 hello = GNUNET_HELLO_get_header (ctx->d2->hello); 1670 hello = GNUNET_HELLO_get_header (ctx->d2->hello);
1608 GNUNET_assert (hello != NULL); 1671 GNUNET_assert (hello != NULL);
1609 GNUNET_TRANSPORT_offer_hello (ctx->d1th, hello); 1672 GNUNET_TRANSPORT_offer_hello (ctx->d1th, hello, NULL, NULL);
1610 GNUNET_assert (ctx->d1core != NULL); 1673 GNUNET_assert (ctx->d1core != NULL);
1611 ctx->connect_request_handle = 1674 ctx->connect_request_handle =
1612 GNUNET_CORE_peer_request_connect (ctx->d1core, 1675 GNUNET_CORE_peer_request_connect (ctx->d1core,
1613 GNUNET_TIME_relative_divide 1676 ctx->relative_timeout,
1614 (ctx->relative_timeout, 1677 &ctx->d2->id,
1615 ctx->max_connect_attempts + 1), 1678 &core_connect_request_cont, ctx);
1616 &ctx->d2->id, 1679
1617 &core_connect_request_cont, ctx);
1618#if DEBUG_TESTING 1680#if DEBUG_TESTING
1619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1681 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1620 "Sending connect request to CORE of %s for peer %s\n", 1682 "Sending connect request to CORE of %s for peer %s\n",
1621 GNUNET_i2s (&ctx->d1->id), 1683 GNUNET_i2s (&ctx->d1->id),
1622 GNUNET_h2s (&ctx->d2->id.hashPubKey)); 1684 GNUNET_h2s (&ctx->d2->id.hashPubKey));
@@ -1649,6 +1711,88 @@ core_init_notify (void *cls,
1649{ 1711{
1650 struct ConnectContext *connect_ctx = cls; 1712 struct ConnectContext *connect_ctx = cls;
1651 connect_ctx->d1core_ready = GNUNET_YES; 1713 connect_ctx->d1core_ready = GNUNET_YES;
1714
1715 if (connect_ctx->send_hello == GNUNET_NO)
1716 {
1717 connect_ctx->connect_request_handle =
1718 GNUNET_CORE_peer_request_connect (connect_ctx->d1core,
1719 connect_ctx->relative_timeout,
1720 &connect_ctx->d2->id,
1721 &core_connect_request_cont, connect_ctx);
1722 GNUNET_assert(connect_ctx->connect_request_handle != NULL);
1723#if DEBUG_TESTING
1724 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1725 "Sending connect request to CORE of %s for peer %s\n",
1726 connect_ctx->d1->shortname,
1727 connect_ctx->d2->shortname);
1728#endif
1729 }
1730
1731}
1732
1733
1734static void
1735reattempt_daemons_connect (void *cls,
1736 const struct GNUNET_SCHEDULER_TaskContext *tc)
1737{
1738 struct ConnectContext *ctx = cls;
1739 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1740 {
1741 GNUNET_free(ctx);
1742 return;
1743 }
1744#if DEBUG_TESTING_RECONNECT
1745 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1746 "re-attempting connect of peer %s to peer %s\n",
1747 ctx->d1->shortname, ctx->d2->shortname);
1748#endif
1749 ctx->connect_attempts--;
1750 GNUNET_assert (ctx->d1core == NULL);
1751 ctx->d1core_ready = GNUNET_NO;
1752 ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg, 1,
1753 ctx,
1754 &core_init_notify,
1755 &connect_notify, NULL, NULL,
1756 NULL, GNUNET_NO,
1757 NULL, GNUNET_NO, no_handlers);
1758 if (ctx->d1core == NULL)
1759 {
1760 if (NULL != ctx->cb)
1761 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg,
1762 ctx->d2->cfg, ctx->d1, ctx->d2,
1763 _("Failed to connect to core service of first peer!\n"));
1764 GNUNET_free (ctx);
1765 return;
1766 }
1767
1768 if (ctx->send_hello == GNUNET_YES)
1769 {
1770 ctx->d1th = GNUNET_TRANSPORT_connect (ctx->d1->cfg,
1771 &ctx->d1->id,
1772 ctx->d1, NULL, NULL, NULL);
1773 if (ctx->d1th == NULL)
1774 {
1775 GNUNET_CORE_disconnect (ctx->d1core);
1776 GNUNET_free (ctx);
1777 if (NULL != ctx->cb)
1778 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg,
1779 ctx->d2->cfg, ctx->d1, ctx->d2,
1780 _("Failed to connect to transport service!\n"));
1781 return;
1782 }
1783 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx);
1784 }
1785 else
1786 {
1787 ctx->connect_request_handle =
1788 GNUNET_CORE_peer_request_connect (ctx->d1core,
1789 ctx->relative_timeout,
1790 &ctx->d2->id,
1791 &core_connect_request_cont, ctx);
1792 }
1793 ctx->timeout_task =
1794 GNUNET_SCHEDULER_add_delayed (ctx->relative_timeout,
1795 &notify_connect_result, ctx);
1652} 1796}
1653 1797
1654/** 1798/**
@@ -1676,7 +1820,7 @@ core_initial_iteration (void *cls,
1676 ctx->distance = 0; /* FIXME: distance */ 1820 ctx->distance = 0; /* FIXME: distance */
1677 return; 1821 return;
1678 } 1822 }
1679 else if (peer == NULL) /* Peer not already connected, need to schedule connect request! */ 1823 else if (peer == NULL) /* End of iteration over peers */
1680 { 1824 {
1681 if (ctx->connected == GNUNET_YES) 1825 if (ctx->connected == GNUNET_YES)
1682 { 1826 {
@@ -1685,12 +1829,21 @@ core_initial_iteration (void *cls,
1685 return; 1829 return;
1686 } 1830 }
1687 1831
1688 ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg, 1, 1832 /* Peer not already connected, need to schedule connect request! */
1689 ctx, 1833 if (ctx->d1core == NULL)
1690 &core_init_notify, 1834 {
1691 &connect_notify, NULL, NULL, 1835#if DEBUG_TESTING
1692 NULL, GNUNET_NO, 1836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1693 NULL, GNUNET_NO, no_handlers); 1837 "Peers are NOT connected, connecting to core!\n");
1838#endif
1839 ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg, 1,
1840 ctx,
1841 &core_init_notify,
1842 &connect_notify, NULL, NULL,
1843 NULL, GNUNET_NO,
1844 NULL, GNUNET_NO, no_handlers);
1845 }
1846
1694 if (ctx->d1core == NULL) 1847 if (ctx->d1core == NULL)
1695 { 1848 {
1696 GNUNET_free (ctx); 1849 GNUNET_free (ctx);
@@ -1700,34 +1853,25 @@ core_initial_iteration (void *cls,
1700 return; 1853 return;
1701 } 1854 }
1702 1855
1703#if DEBUG_TESTING > 2 1856 if (ctx->send_hello == GNUNET_YES)
1704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1705 "Asked to connect peer %s to peer %s\n",
1706 ctx->d1->shortname, ctx->d2->shortname);
1707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1708 "Connecting to transport service of peer %s\n", ctx->d2->shortname);
1709
1710#endif
1711
1712 ctx->d1th = GNUNET_TRANSPORT_connect (ctx->d1->cfg,
1713 &ctx->d1->id, ctx->d1, NULL, NULL, NULL);
1714 if (ctx->d1th == NULL)
1715 { 1857 {
1716 GNUNET_CORE_disconnect (ctx->d1core); 1858 ctx->d1th = GNUNET_TRANSPORT_connect (ctx->d1->cfg,
1717 GNUNET_free (ctx); 1859 &ctx->d1->id, ctx->d1, NULL, NULL, NULL);
1718 if (NULL != ctx->cb) 1860 if (ctx->d1th == NULL)
1719 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2, 1861 {
1720 _("Failed to connect to transport service!\n")); 1862 GNUNET_CORE_disconnect (ctx->d1core);
1721 return; 1863 GNUNET_free (ctx);
1864 if (NULL != ctx->cb)
1865 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2,
1866 _("Failed to connect to transport service!\n"));
1867 return;
1868 }
1869 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx);
1722 } 1870 }
1723 1871
1724 ctx->timeout_task = 1872 ctx->timeout_task =
1725 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide 1873 GNUNET_SCHEDULER_add_delayed (ctx->relative_timeout,
1726 (ctx->relative_timeout, 1874 &notify_connect_result, ctx);
1727 ctx->max_connect_attempts),
1728 &notify_connect_result, ctx);
1729
1730 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx);
1731 } 1875 }
1732} 1876}
1733 1877
@@ -1741,6 +1885,8 @@ core_initial_iteration (void *cls,
1741 * allowed to take? 1885 * allowed to take?
1742 * @param max_connect_attempts how many times should we try to reconnect 1886 * @param max_connect_attempts how many times should we try to reconnect
1743 * (within timeout) 1887 * (within timeout)
1888 * @param send_hello GNUNET_YES to send the HELLO, GNUNET_NO to assume
1889 * the HELLO has already been exchanged
1744 * @param cb function to call at the end 1890 * @param cb function to call at the end
1745 * @param cb_cls closure for cb 1891 * @param cb_cls closure for cb
1746 */ 1892 */
@@ -1749,6 +1895,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1749 struct GNUNET_TESTING_Daemon *d2, 1895 struct GNUNET_TESTING_Daemon *d2,
1750 struct GNUNET_TIME_Relative timeout, 1896 struct GNUNET_TIME_Relative timeout,
1751 unsigned int max_connect_attempts, 1897 unsigned int max_connect_attempts,
1898 int send_hello,
1752 GNUNET_TESTING_NotifyConnection cb, 1899 GNUNET_TESTING_NotifyConnection cb,
1753 void *cb_cls) 1900 void *cb_cls)
1754{ 1901{
@@ -1761,17 +1908,18 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1761 _("Peers are not fully running yet, can not connect!\n")); 1908 _("Peers are not fully running yet, can not connect!\n"));
1762 return; 1909 return;
1763 } 1910 }
1911
1764 ctx = GNUNET_malloc (sizeof (struct ConnectContext)); 1912 ctx = GNUNET_malloc (sizeof (struct ConnectContext));
1765 ctx->d1 = d1; 1913 ctx->d1 = d1;
1766 ctx->d2 = d2; 1914 ctx->d2 = d2;
1767 ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1768 ctx->timeout_hello = 1915 ctx->timeout_hello =
1769 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500); 1916 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500);
1770 ctx->relative_timeout = timeout; 1917 ctx->relative_timeout = GNUNET_TIME_relative_divide(timeout, max_connect_attempts);
1771 ctx->cb = cb; 1918 ctx->cb = cb;
1772 ctx->cb_cls = cb_cls; 1919 ctx->cb_cls = cb_cls;
1773 ctx->max_connect_attempts = max_connect_attempts; 1920 ctx->connect_attempts = max_connect_attempts;
1774 ctx->connected = GNUNET_NO; 1921 ctx->connected = GNUNET_NO;
1922 ctx->send_hello = send_hello;
1775#if DEBUG_TESTING 1923#if DEBUG_TESTING
1776 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1777 "Asked to connect peer %s to peer %s\n", 1925 "Asked to connect peer %s to peer %s\n",
@@ -1779,66 +1927,8 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1779#endif 1927#endif
1780 1928
1781 /* Core is up! Iterate over all _known_ peers first to check if we are already connected to the peer! */ 1929 /* Core is up! Iterate over all _known_ peers first to check if we are already connected to the peer! */
1782 GNUNET_CORE_is_peer_connected (ctx->d1->cfg, &ctx->d2->id, &core_initial_iteration, ctx); 1930 GNUNET_assert(GNUNET_OK == GNUNET_CORE_is_peer_connected (ctx->d1->cfg, &ctx->d2->id, &core_initial_iteration, ctx));
1783 /* GNUNET_CORE_iterate_peers(ctx->d1->cfg, &core_initial_iteration, ctx); */ 1931 /*GNUNET_assert(GNUNET_OK == GNUNET_CORE_iterate_peers (ctx->d1->cfg, &core_initial_iteration, ctx));*/
1784
1785}
1786
1787static void
1788reattempt_daemons_connect (void *cls,
1789 const struct GNUNET_SCHEDULER_TaskContext *tc)
1790{
1791
1792 struct ConnectContext *ctx = cls;
1793 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1794 {
1795 return;
1796 }
1797#if DEBUG_TESTING_RECONNECT
1798 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1799 "re-attempting connect of peer %s to peer %s\n",
1800 ctx->d1->shortname, ctx->d2->shortname);
1801#endif
1802
1803 GNUNET_assert (ctx->d1core == NULL);
1804 ctx->d1core_ready = GNUNET_NO;
1805 ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg, 1,
1806 ctx,
1807 &core_init_notify,
1808 &connect_notify, NULL, NULL,
1809 NULL, GNUNET_NO,
1810 NULL, GNUNET_NO, no_handlers);
1811 if (ctx->d1core == NULL)
1812 {
1813 if (NULL != ctx->cb)
1814 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg,
1815 ctx->d2->cfg, ctx->d1, ctx->d2,
1816 _("Failed to connect to core service of first peer!\n"));
1817 GNUNET_free (ctx);
1818 return;
1819 }
1820
1821 ctx->d1th = GNUNET_TRANSPORT_connect (ctx->d1->cfg,
1822 &ctx->d1->id,
1823 ctx->d1, NULL, NULL, NULL);
1824 if (ctx->d1th == NULL)
1825 {
1826 GNUNET_CORE_disconnect (ctx->d1core);
1827 GNUNET_free (ctx);
1828 if (NULL != ctx->cb)
1829 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg,
1830 ctx->d2->cfg, ctx->d1, ctx->d2,
1831 _("Failed to connect to transport service!\n"));
1832 return;
1833 }
1834
1835 ctx->timeout_task =
1836 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
1837 (ctx->relative_timeout,
1838 ctx->max_connect_attempts),
1839 &notify_connect_result, ctx);
1840
1841 ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx);
1842} 1932}
1843 1933
1844/* end of testing.c */ 1934/* end of testing.c */
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index fc527efe3..90aad3ca2 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -30,7 +30,7 @@
30#include "gnunet_testing_lib.h" 30#include "gnunet_testing_lib.h"
31#include "gnunet_core_service.h" 31#include "gnunet_core_service.h"
32 32
33#define VERBOSE_TESTING GNUNET_YES 33#define VERBOSE_TESTING GNUNET_NO
34 34
35#define VERBOSE_TOPOLOGY GNUNET_YES 35#define VERBOSE_TOPOLOGY GNUNET_YES
36 36
@@ -38,6 +38,8 @@
38 38
39#define OLD 1 39#define OLD 1
40 40
41#define USE_SEND_HELLOS GNUNET_NO
42
41/** 43/**
42 * Lowest port used for GNUnet testing. Should be high enough to not 44 * Lowest port used for GNUnet testing. Should be high enough to not
43 * conflict with other applications running on the hosts but be low 45 * conflict with other applications running on the hosts but be low
@@ -159,6 +161,40 @@ struct RestartContext
159}; 161};
160 162
161 163
164struct SendHelloContext
165{
166 /**
167 * Global handle to the peer group.
168 */
169 struct GNUNET_TESTING_PeerGroup *pg;
170
171 /**
172 * The data about this specific peer.
173 */
174 struct PeerData *peer;
175
176 /**
177 * The next HELLO that needs sent to this peer.
178 */
179 struct PeerConnection *peer_pos;
180
181 /**
182 * Are we connected to CORE yet?
183 */
184 unsigned int core_ready;
185
186 /**
187 * How many attempts should we make for failed connections?
188 */
189 unsigned int connect_attempts;
190
191 /**
192 * Task for scheduling core connect requests to be sent.
193 */
194 GNUNET_SCHEDULER_TaskIdentifier core_connect_task;
195};
196
197
162struct ShutdownContext 198struct ShutdownContext
163{ 199{
164 struct GNUNET_TESTING_PeerGroup *pg; 200 struct GNUNET_TESTING_PeerGroup *pg;
@@ -599,6 +635,46 @@ struct StatsCoreContext
599 struct GNUNET_STATISTICS_GetHandle *stats_get_handle; 635 struct GNUNET_STATISTICS_GetHandle *stats_get_handle;
600}; 636};
601 637
638
639struct ConnectTopologyContext
640{
641 /**
642 * How many connections are left to create.
643 */
644 unsigned int remaining_connections;
645
646 /**
647 * Handle to group of peers.
648 */
649 struct GNUNET_TESTING_PeerGroup *pg;
650
651 /**
652 * How long to try this connection before timing out.
653 */
654 struct GNUNET_TIME_Relative connect_timeout;
655
656 /**
657 * How many times to retry connecting the two peers.
658 */
659 unsigned int connect_attempts;
660
661 /**
662 * Temp value set for each iteration.
663 */
664 //struct PeerData *first;
665
666 /**
667 * Notification that all peers are connected.
668 */
669 GNUNET_TESTING_NotifyCompletion notify_connections_done;
670
671 /**
672 * Closure for notify.
673 */
674 void *notify_cls;
675};
676
677
602/** 678/**
603 * Handle to a group of GNUnet peers. 679 * Handle to a group of GNUnet peers.
604 */ 680 */
@@ -682,6 +758,11 @@ struct GNUNET_TESTING_PeerGroup
682 unsigned int outstanding_connects; 758 unsigned int outstanding_connects;
683 759
684 /** 760 /**
761 * Number of HELLOs we have yet to send.
762 */
763 unsigned int remaining_hellos;
764
765 /**
685 * How many connects have already been scheduled? 766 * How many connects have already been scheduled?
686 */ 767 */
687 unsigned int total_connects_scheduled; 768 unsigned int total_connects_scheduled;
@@ -707,72 +788,59 @@ struct GNUNET_TESTING_PeerGroup
707 * Stop scheduling peers connecting. 788 * Stop scheduling peers connecting.
708 */ 789 */
709 unsigned int stop_connects; 790 unsigned int stop_connects;
710};
711
712struct UpdateContext
713{
714 struct GNUNET_CONFIGURATION_Handle *ret;
715 const struct GNUNET_CONFIGURATION_Handle *orig;
716 const char *hostname;
717 unsigned int nport;
718 unsigned int upnum;
719 unsigned int fdnum;
720};
721
722struct ConnectTopologyContext
723{
724 /**
725 * How many connections are left to create.
726 */
727 unsigned int remaining_connections;
728 791
729 /** 792 /**
730 * How many more connections do we need to schedule? 793 * Connection context for peer group.
731 */ 794 */
732 unsigned int remaining_connects_to_schedule; 795 struct ConnectTopologyContext ct_ctx;
796};
733 797
798struct UpdateContext
799{
734 /** 800 /**
735 * Handle to group of peers. 801 * The altered configuration.
736 */ 802 */
737 struct GNUNET_TESTING_PeerGroup *pg; 803 struct GNUNET_CONFIGURATION_Handle *ret;
738 804
739 /** 805 /**
740 * How long to try this connection before timing out. 806 * The original configuration to alter.
741 */ 807 */
742 struct GNUNET_TIME_Relative connect_timeout; 808 const struct GNUNET_CONFIGURATION_Handle *orig;
743 809
744 /** 810 /**
745 * How many times to retry connecting the two peers. 811 * The hostname that this peer will run on.
746 */ 812 */
747 unsigned int connect_attempts; 813 const char *hostname;
748 814
749 /** 815 /**
750 * Temp value set for each iteration. 816 * The next possible port to assign.
751 */ 817 */
752 //struct PeerData *first; 818 unsigned int nport;
753 819
754 /** 820 /**
755 * Notification that all peers are connected. 821 * Unique number for unix domain sockets.
756 */ 822 */
757 GNUNET_TESTING_NotifyCompletion notify_connections_done; 823 unsigned int upnum;
758 824
759 /** 825 /**
760 * Closure for notify. 826 * Unique number for this peer/host to offset
827 * things that are grouped by host.
761 */ 828 */
762 void *notify_cls; 829 unsigned int fdnum;
763}; 830};
764 831
832
765struct ConnectContext 833struct ConnectContext
766{ 834{
767 /** 835 /**
768 * Peer to connect second to. 836 * Index of peer to connect second to.
769 */ 837 */
770 struct GNUNET_TESTING_Daemon *first; 838 uint32_t first_index;
771 839
772 /** 840 /**
773 * Peer to connect first to. 841 * Index of peer to connect first to.
774 */ 842 */
775 struct GNUNET_TESTING_Daemon *second; 843 uint32_t second_index;
776 844
777 /** 845 /**
778 * Higher level topology connection context. 846 * Higher level topology connection context.
@@ -915,6 +983,10 @@ uid_from_hash (const GNUNET_HashCode * hash, uint32_t * uid)
915} 983}
916#endif 984#endif
917 985
986#if USE_SEND_HELLOS
987static struct GNUNET_CORE_MessageHandler no_handlers[] = { {NULL, 0, 0} };
988#endif
989
918/** 990/**
919 * Get a topology from a string input. 991 * Get a topology from a string input.
920 * 992 *
@@ -1102,25 +1174,34 @@ update_config (void *cls,
1102 char *per_host_variable; 1174 char *per_host_variable;
1103 unsigned long long num_per_host; 1175 unsigned long long num_per_host;
1104 1176
1177 GNUNET_asprintf (&single_variable, "single_%s_per_host", section);
1178 GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section);
1179
1105 if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival))) 1180 if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival)))
1106 { 1181 {
1107 GNUNET_asprintf (&single_variable, "single_%s_per_host", section); 1182 if ((ival != 0) &&
1108 if ((ival != 0) 1183 (GNUNET_YES !=
1109 && (GNUNET_YES !=
1110 GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing", 1184 GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing",
1111 single_variable))) 1185 single_variable)))
1112 { 1186 {
1113 GNUNET_snprintf (cval, sizeof (cval), "%u", ctx->nport++); 1187 GNUNET_snprintf (cval, sizeof (cval), "%u", ctx->nport++);
1114 value = cval; 1188 value = cval;
1115 } 1189 }
1116 1190 else if ((ival != 0) &&
1117 GNUNET_free (single_variable); 1191 (GNUNET_YES ==
1192 GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing",
1193 single_variable)) &&
1194 GNUNET_CONFIGURATION_get_value_number (ctx->orig, "testing",
1195 per_host_variable,
1196 &num_per_host))
1197 {
1198 GNUNET_snprintf (cval, sizeof (cval), "%u", ival + ctx->fdnum % num_per_host);
1199 value = cval;
1200 }
1118 } 1201 }
1119 1202
1120 if (0 == strcmp (option, "UNIXPATH")) 1203 if (0 == strcmp (option, "UNIXPATH"))
1121 { 1204 {
1122 GNUNET_asprintf (&single_variable, "single_%s_per_host", section);
1123 GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section);
1124 if (GNUNET_YES != 1205 if (GNUNET_YES !=
1125 GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing", 1206 GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing",
1126 single_variable)) 1207 single_variable))
@@ -1142,15 +1223,14 @@ update_config (void *cls,
1142 section, ctx->fdnum % num_per_host); 1223 section, ctx->fdnum % num_per_host);
1143 value = uval; 1224 value = uval;
1144 } 1225 }
1145 GNUNET_free (single_variable);
1146 GNUNET_free (per_host_variable);
1147 } 1226 }
1148 1227
1149 if ((0 == strcmp (option, "HOSTNAME")) && (ctx->hostname != NULL)) 1228 if ((0 == strcmp (option, "HOSTNAME")) && (ctx->hostname != NULL))
1150 { 1229 {
1151 value = ctx->hostname; 1230 value = ctx->hostname;
1152 } 1231 }
1153 1232 GNUNET_free (single_variable);
1233 GNUNET_free (per_host_variable);
1154 GNUNET_CONFIGURATION_set_value_string (ctx->ret, section, option, value); 1234 GNUNET_CONFIGURATION_set_value_string (ctx->ret, section, option, value);
1155} 1235}
1156 1236
@@ -1176,13 +1256,13 @@ static struct GNUNET_CONFIGURATION_Handle *
1176make_config (const struct GNUNET_CONFIGURATION_Handle *cfg, 1256make_config (const struct GNUNET_CONFIGURATION_Handle *cfg,
1177 uint32_t off, 1257 uint32_t off,
1178 uint16_t * port, 1258 uint16_t * port,
1179 uint32_t * upnum, const char *hostname, uint32_t * fdnum) 1259 uint32_t * upnum, const char *hostname,
1260 uint32_t * fdnum)
1180{ 1261{
1181 struct UpdateContext uc; 1262 struct UpdateContext uc;
1182 uint16_t orig; 1263 uint16_t orig;
1183 char *control_host; 1264 char *control_host;
1184 char *allowed_hosts; 1265 char *allowed_hosts;
1185 unsigned long long temp_port;
1186 1266
1187 orig = *port; 1267 orig = *port;
1188 uc.nport = *port; 1268 uc.nport = *port;
@@ -1223,16 +1303,6 @@ make_config (const struct GNUNET_CONFIGURATION_Handle *cfg,
1223 GNUNET_CONFIGURATION_set_value_string (uc.ret, "dht", "UNIXPATH", ""); 1303 GNUNET_CONFIGURATION_set_value_string (uc.ret, "dht", "UNIXPATH", "");
1224 GNUNET_CONFIGURATION_set_value_string (uc.ret, "statistics", "UNIXPATH", ""); 1304 GNUNET_CONFIGURATION_set_value_string (uc.ret, "statistics", "UNIXPATH", "");
1225 1305
1226
1227 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(uc.orig, "statistics", "port", &temp_port) &&
1228 (temp_port != 0) &&
1229 (GNUNET_YES !=
1230 GNUNET_CONFIGURATION_get_value_yesno (uc.orig, "testing",
1231 "single_statistics_per_host")))
1232 {
1233 GNUNET_CONFIGURATION_set_value_number (uc.ret, "statistics", "port", temp_port + off);
1234 }
1235
1236 GNUNET_free_non_null (control_host); 1306 GNUNET_free_non_null (control_host);
1237 GNUNET_free (allowed_hosts); 1307 GNUNET_free (allowed_hosts);
1238 } 1308 }
@@ -1493,9 +1563,6 @@ add_connections (struct GNUNET_TESTING_PeerGroup *pg,
1493 new_first = GNUNET_malloc (sizeof (struct PeerConnection)); 1563 new_first = GNUNET_malloc (sizeof (struct PeerConnection));
1494 new_first->index = second; 1564 new_first->index = second;
1495 GNUNET_CONTAINER_DLL_insert(*first_list, *first_tail, new_first); 1565 GNUNET_CONTAINER_DLL_insert(*first_list, *first_tail, new_first);
1496 /*
1497 new_first->next = *first_list;
1498 *first_list = new_first;*/
1499#else 1566#else
1500 GNUNET_assert (GNUNET_OK == 1567 GNUNET_assert (GNUNET_OK ==
1501 GNUNET_CONTAINER_multihashmap_put (pg-> 1568 GNUNET_CONTAINER_multihashmap_put (pg->
@@ -1516,10 +1583,6 @@ add_connections (struct GNUNET_TESTING_PeerGroup *pg,
1516 new_second = GNUNET_malloc (sizeof (struct PeerConnection)); 1583 new_second = GNUNET_malloc (sizeof (struct PeerConnection));
1517 new_second->index = first; 1584 new_second->index = first;
1518 GNUNET_CONTAINER_DLL_insert(*second_list, *second_tail, new_second); 1585 GNUNET_CONTAINER_DLL_insert(*second_list, *second_tail, new_second);
1519 /*
1520 new_second->next = *second_list;
1521 *second_list = new_second;
1522 *second_list */
1523#else 1586#else
1524 GNUNET_assert (GNUNET_OK == 1587 GNUNET_assert (GNUNET_OK ==
1525 GNUNET_CONTAINER_multihashmap_put (pg-> 1588 GNUNET_CONTAINER_multihashmap_put (pg->
@@ -2606,7 +2669,8 @@ create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg)
2606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2607 _("Copying file with command cp %s %s\n"), mytemp, arg); 2670 _("Copying file with command cp %s %s\n"), mytemp, arg);
2608#endif 2671#endif
2609 2672 ret = GNUNET_OS_process_wait(procarr[pg_iter]); /* FIXME: schedule this, throttle! */
2673 GNUNET_OS_process_close (procarr[pg_iter]);
2610 GNUNET_free (arg); 2674 GNUNET_free (arg);
2611 } 2675 }
2612 else /* Remote, scp the file to the correct place */ 2676 else /* Remote, scp the file to the correct place */
@@ -2895,34 +2959,403 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
2895 * 2959 *
2896 * @param ct_ctx the overall connection context 2960 * @param ct_ctx the overall connection context
2897 */ 2961 */
2898static void preschedule_connect(struct ConnectTopologyContext *ct_ctx) 2962static void preschedule_connect(struct GNUNET_TESTING_PeerGroup *pg)
2899{ 2963{
2900 struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg; 2964 struct ConnectTopologyContext *ct_ctx = &pg->ct_ctx;
2901 struct PeerConnection *connection_iter; 2965 struct PeerConnection *connection_iter;
2902 struct ConnectContext *connect_context; 2966 struct ConnectContext *connect_context;
2903 uint32_t random_peer; 2967 uint32_t random_peer;
2904 2968
2905 if (ct_ctx->remaining_connects_to_schedule == 0) 2969 if (ct_ctx->remaining_connections == 0)
2906 return; 2970 return;
2907 random_peer = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, pg->total); 2971 random_peer = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, pg->total);
2908 while (pg->peers[random_peer].connect_peers_head == NULL) 2972 while (pg->peers[random_peer].connect_peers_head == NULL)
2909 random_peer = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, pg->total); 2973 random_peer = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, pg->total);
2910 2974
2911 connection_iter = pg->peers[random_peer].connect_peers_head; 2975 connection_iter = pg->peers[random_peer].connect_peers_head;
2912#if DEBUG_TESTING
2913 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Scheduling connection between %d and %d\n", random_peer, connection_iter->index);
2914#endif
2915 connect_context = GNUNET_malloc (sizeof (struct ConnectContext)); 2976 connect_context = GNUNET_malloc (sizeof (struct ConnectContext));
2916 connect_context->first = pg->peers[random_peer].daemon; 2977 connect_context->first_index = random_peer;
2917 connect_context->second = pg->peers[connection_iter->index].daemon; 2978 connect_context->second_index = connection_iter->index;
2918 connect_context->ct_ctx = ct_ctx; 2979 connect_context->ct_ctx = ct_ctx;
2919 GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context); 2980 GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context);
2920 GNUNET_CONTAINER_DLL_remove(pg->peers[random_peer].connect_peers_head, pg->peers[random_peer].connect_peers_tail, connection_iter); 2981 GNUNET_CONTAINER_DLL_remove(pg->peers[random_peer].connect_peers_head, pg->peers[random_peer].connect_peers_tail, connection_iter);
2921 ct_ctx->remaining_connects_to_schedule--; 2982 GNUNET_free(connection_iter);
2983 ct_ctx->remaining_connections--;
2984}
2985
2986#if USE_SEND_HELLOS
2987/* Forward declaration */
2988static void schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
2989
2990
2991/**
2992 * Close connections and free the hello context.
2993 *
2994 * @param cls the 'struct SendHelloContext *'
2995 * @param tc scheduler context
2996 */
2997static void
2998free_hello_context (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2999{
3000 struct SendHelloContext *send_hello_context = cls;
3001 if (send_hello_context->peer->daemon->server != NULL)
3002 {
3003 GNUNET_CORE_disconnect(send_hello_context->peer->daemon->server);
3004 send_hello_context->peer->daemon->server = NULL;
3005 }
3006 if (send_hello_context->peer->daemon->th != NULL)
3007 {
3008 GNUNET_TRANSPORT_disconnect(send_hello_context->peer->daemon->th);
3009 send_hello_context->peer->daemon->th = NULL;
3010 }
3011 if (send_hello_context->core_connect_task != GNUNET_SCHEDULER_NO_TASK)
3012 {
3013 GNUNET_SCHEDULER_cancel(send_hello_context->core_connect_task);
3014 send_hello_context->core_connect_task = GNUNET_SCHEDULER_NO_TASK;
3015 }
3016 send_hello_context->pg->outstanding_connects--;
3017 GNUNET_free(send_hello_context);
3018}
3019
3020/**
3021 * For peers that haven't yet connected, notify
3022 * the caller that they have failed (timeout).
3023 *
3024 * @param cls the 'struct SendHelloContext *'
3025 * @param tc scheduler context
3026 */
3027static void
3028notify_remaining_connections_failed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3029{
3030 struct SendHelloContext *send_hello_context = cls;
3031 struct GNUNET_TESTING_PeerGroup *pg = send_hello_context->pg;
3032 struct PeerConnection *connection;
3033
3034 GNUNET_CORE_disconnect(send_hello_context->peer->daemon->server);
3035 send_hello_context->peer->daemon->server = NULL;
3036
3037 connection = send_hello_context->peer->connect_peers_head;
3038
3039 while (connection != NULL)
3040 {
3041 if (pg->notify_connection != NULL)
3042 {
3043 pg->notify_connection(pg->notify_connection_cls,
3044 &send_hello_context->peer->daemon->id,
3045 &pg->peers[connection->index].daemon->id,
3046 0, /* FIXME */
3047 send_hello_context->peer->daemon->cfg,
3048 pg->peers[connection->index].daemon->cfg,
3049 send_hello_context->peer->daemon,
3050 pg->peers[connection->index].daemon,
3051 "Peers failed to connect (timeout)");
3052 }
3053 GNUNET_CONTAINER_DLL_remove(send_hello_context->peer->connect_peers_head, send_hello_context->peer->connect_peers_tail, connection);
3054 GNUNET_free(connection);
3055 connection = connection->next;
3056 }
3057 GNUNET_SCHEDULER_add_now(&free_hello_context, send_hello_context);
3058#if BAD
3059 other_peer = &pg->peers[connection->index];
3060#endif
2922} 3061}
2923 3062
2924 3063
2925/** 3064/**
3065 * For peers that haven't yet connected, send
3066 * CORE connect requests.
3067 *
3068 * @param cls the 'struct SendHelloContext *'
3069 * @param tc scheduler context
3070 */
3071static void
3072send_core_connect_requests (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3073{
3074 struct SendHelloContext *send_hello_context = cls;
3075 struct PeerConnection *conn;
3076 GNUNET_assert(send_hello_context->peer->daemon->server != NULL);
3077
3078 send_hello_context->core_connect_task = GNUNET_SCHEDULER_NO_TASK;
3079
3080 send_hello_context->connect_attempts++;
3081 if (send_hello_context->connect_attempts < send_hello_context->pg->ct_ctx.connect_attempts)
3082 {
3083 conn = send_hello_context->peer->connect_peers_head;
3084 while (conn != NULL)
3085 {
3086 GNUNET_CORE_peer_request_connect(send_hello_context->peer->daemon->server,
3087 GNUNET_TIME_relative_get_forever(),
3088 &send_hello_context->pg->peers[conn->index].daemon->id,
3089 NULL,
3090 NULL);
3091 conn = conn->next;
3092 }
3093 send_hello_context->core_connect_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_divide(send_hello_context->pg->ct_ctx.connect_timeout, send_hello_context->pg->ct_ctx.connect_attempts) ,
3094 &send_core_connect_requests,
3095 send_hello_context);
3096 }
3097 else
3098 {
3099 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Timeout before all connections created, marking rest as failed!\n");
3100 GNUNET_SCHEDULER_add_now(&notify_remaining_connections_failed, send_hello_context);
3101 }
3102
3103}
3104
3105
3106/**
3107 * Success, connection is up. Signal client our success.
3108 *
3109 * @param cls our "struct SendHelloContext"
3110 * @param peer identity of the peer that has connected
3111 * @param atsi performance information
3112 *
3113 * FIXME: remove peers from BOTH lists, call notify twice, should
3114 * double the speed of connections as long as the list iteration
3115 * doesn't take too long!
3116 */
3117static void
3118core_connect_notify (void *cls,
3119 const struct GNUNET_PeerIdentity *peer,
3120 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
3121{
3122 struct SendHelloContext *send_hello_context = cls;
3123 struct PeerConnection *connection;
3124 struct GNUNET_TESTING_PeerGroup *pg = send_hello_context->pg;
3125#if BAD
3126 struct PeerData *other_peer;
3127#endif
3128#if DEBUG_TESTING
3129 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3130 "Connected peer %s to peer %s\n",
3131 ctx->d1->shortname, GNUNET_i2s(peer));
3132#endif
3133
3134 if (0 == memcmp(&send_hello_context->peer->daemon->id, peer, sizeof(struct GNUNET_PeerIdentity)))
3135 return;
3136
3137 connection = send_hello_context->peer->connect_peers_head;
3138#if BAD
3139 other_peer = NULL;
3140#endif
3141
3142 while ((connection != NULL) &&
3143 (0 != memcmp(&pg->peers[connection->index].daemon->id, peer, sizeof(struct GNUNET_PeerIdentity))))
3144 {
3145 connection = connection->next;
3146 }
3147
3148 if (connection == NULL)
3149 {
3150 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Connected peer %s to %s, not in list (no problem(?))\n", GNUNET_i2s(peer), send_hello_context->peer->daemon->shortname);
3151 }
3152 else
3153 {
3154#if BAD
3155 other_peer = &pg->peers[connection->index];
3156#endif
3157 if (pg->notify_connection != NULL)
3158 {
3159 pg->notify_connection(pg->notify_connection_cls,
3160 &send_hello_context->peer->daemon->id,
3161 peer,
3162 0, /* FIXME */
3163 send_hello_context->peer->daemon->cfg,
3164 pg->peers[connection->index].daemon->cfg,
3165 send_hello_context->peer->daemon,
3166 pg->peers[connection->index].daemon,
3167 NULL);
3168 }
3169 GNUNET_CONTAINER_DLL_remove(send_hello_context->peer->connect_peers_head, send_hello_context->peer->connect_peers_tail, connection);
3170 GNUNET_free(connection);
3171 }
3172
3173#if BAD
3174 /* Notify of reverse connection and remove from other peers list of outstanding */
3175 if (other_peer != NULL)
3176 {
3177 connection = other_peer->connect_peers_head;
3178 while ((connection != NULL) &&
3179 (0 != memcmp(&send_hello_context->peer->daemon->id, &pg->peers[connection->index].daemon->id, sizeof(struct GNUNET_PeerIdentity))))
3180 {
3181 connection = connection->next;
3182 }
3183 if (connection != NULL)
3184 {
3185 if (pg->notify_connection != NULL)
3186 {
3187 pg->notify_connection(pg->notify_connection_cls,
3188 peer,
3189 &send_hello_context->peer->daemon->id,
3190 0, /* FIXME */
3191 pg->peers[connection->index].daemon->cfg,
3192 send_hello_context->peer->daemon->cfg,
3193 pg->peers[connection->index].daemon,
3194 send_hello_context->peer->daemon,
3195 NULL);
3196 }
3197
3198 GNUNET_CONTAINER_DLL_remove(other_peer->connect_peers_head, other_peer->connect_peers_tail, connection);
3199 GNUNET_free(connection);
3200 }
3201 }
3202#endif
3203
3204 if (send_hello_context->peer->connect_peers_head == NULL)
3205 {
3206 GNUNET_SCHEDULER_add_now(&free_hello_context, send_hello_context);
3207 }
3208}
3209
3210/**
3211 * Notify of a successful connection to the core service.
3212 *
3213 * @param cls a struct SendHelloContext *
3214 * @param server handle to the core service
3215 * @param my_identity the peer identity of this peer
3216 * @param publicKey the public key of the peer
3217 */
3218void
3219core_init (void *cls,
3220 struct GNUNET_CORE_Handle * server,
3221 const struct GNUNET_PeerIdentity *
3222 my_identity,
3223 const struct
3224 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *
3225 publicKey)
3226{
3227 struct SendHelloContext *send_hello_context = cls;
3228 send_hello_context->core_ready = GNUNET_YES;
3229}
3230
3231
3232/**
3233 * Function called once a hello has been sent
3234 * to the transport, move on to the next one
3235 * or go away forever.
3236 *
3237 * @param cls the 'struct SendHelloContext *'
3238 * @param tc scheduler context
3239 */
3240static void
3241hello_sent_callback (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3242{
3243 struct SendHelloContext *send_hello_context = cls;
3244 //unsigned int pg_iter;
3245 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
3246 {
3247 GNUNET_free(send_hello_context);
3248 return;
3249 }
3250
3251 send_hello_context->pg->remaining_hellos--;
3252#if DEBUG_TESTING
3253 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sent HELLO, have %d remaining!\n", send_hello_context->pg->remaining_hellos);
3254#endif
3255 if (send_hello_context->peer_pos == NULL) /* All HELLOs (for this peer!) have been transmitted! */
3256 {
3257#if DEBUG_TESTING
3258 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "All hellos for this peer sent, disconnecting transport!\n");
3259#endif
3260 GNUNET_assert(send_hello_context->peer->daemon->th != NULL);
3261 GNUNET_TRANSPORT_disconnect(send_hello_context->peer->daemon->th);
3262 send_hello_context->peer->daemon->th = NULL;
3263
3264 /*if (send_hello_context->pg->remaining_hellos == 0)
3265 {
3266 for (pg_iter = 0; pg_iter < send_hello_context->pg->max_outstanding_connections; pg_iter++)
3267 {
3268 preschedule_connect(&send_hello_context->pg->ct_ctx);
3269 }
3270 }
3271 */
3272 GNUNET_assert (send_hello_context->peer->daemon->server == NULL);
3273 send_hello_context->peer->daemon->server = GNUNET_CORE_connect(send_hello_context->peer->cfg,
3274 1,
3275 send_hello_context,
3276 &core_init,
3277 &core_connect_notify,
3278 NULL,
3279 NULL,
3280 NULL, GNUNET_NO,
3281 NULL, GNUNET_NO,
3282 no_handlers);
3283
3284 send_hello_context->core_connect_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_divide(send_hello_context->pg->ct_ctx.connect_timeout, send_hello_context->pg->ct_ctx.connect_attempts),
3285 &send_core_connect_requests,
3286 send_hello_context);
3287 }
3288 else
3289 GNUNET_SCHEDULER_add_now(&schedule_send_hellos, send_hello_context);
3290}
3291
3292
3293/**
3294 * Connect to a peer, give it all the HELLO's of those peers
3295 * we will later ask it to connect to.
3296 *
3297 * @param ct_ctx the overall connection context
3298 */
3299static void schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3300{
3301 struct SendHelloContext *send_hello_context = cls;
3302 struct GNUNET_TESTING_PeerGroup *pg = send_hello_context->pg;
3303
3304 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
3305 {
3306 GNUNET_free(send_hello_context);
3307 return;
3308 }
3309
3310 GNUNET_assert(send_hello_context->peer_pos != NULL); /* All of the HELLO sends to be scheduled have been scheduled! */
3311
3312 if (((send_hello_context->peer->daemon->th == NULL) &&
3313 (pg->outstanding_connects > pg->max_outstanding_connections)) ||
3314 (pg->stop_connects == GNUNET_YES))
3315 {
3316#if VERBOSE_TESTING > 2
3317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3318 _
3319 ("Delaying connect, we have too many outstanding connections!\n"));
3320#endif
3321 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
3322 (GNUNET_TIME_UNIT_MILLISECONDS, 100),
3323 &schedule_send_hellos, send_hello_context);
3324 }
3325 else
3326 {
3327#if VERBOSE_TESTING > 2
3328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3329 _("Creating connection, outstanding_connections is %d\n"),
3330 outstanding_connects);
3331#endif
3332 if (send_hello_context->peer->daemon->th == NULL)
3333 {
3334 pg->outstanding_connects++; /* Actual TRANSPORT, CORE connections! */
3335 send_hello_context->peer->daemon->th = GNUNET_TRANSPORT_connect(send_hello_context->peer->cfg,
3336 NULL,
3337 send_hello_context,
3338 NULL,
3339 NULL,
3340 NULL);
3341 }
3342#if DEBUG_TESTING
3343 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3344 _("Offering Hello of peer %s to peer %s\n"),
3345 send_hello_context->peer->daemon->shortname, pg->peers[send_hello_context->peer_pos->index].daemon->shortname);
3346#endif
3347 GNUNET_TRANSPORT_offer_hello(send_hello_context->peer->daemon->th,
3348 (const struct GNUNET_MessageHeader *)pg->peers[send_hello_context->peer_pos->index].daemon->hello,
3349 &hello_sent_callback,
3350 send_hello_context);
3351 send_hello_context->peer_pos = send_hello_context->peer_pos->next;
3352 GNUNET_assert(send_hello_context->peer->daemon->th != NULL);
3353 }
3354}
3355#endif
3356
3357
3358/**
2926 * Internal notification of a connection, kept so that we can ensure some connections 3359 * Internal notification of a connection, kept so that we can ensure some connections
2927 * happen instead of flooding all testing daemons with requests to connect. 3360 * happen instead of flooding all testing daemons with requests to connect.
2928 */ 3361 */
@@ -2937,23 +3370,54 @@ internal_connect_notify (void *cls,
2937 struct GNUNET_TESTING_Daemon *second_daemon, 3370 struct GNUNET_TESTING_Daemon *second_daemon,
2938 const char *emsg) 3371 const char *emsg)
2939{ 3372{
2940 struct ConnectTopologyContext *ct_ctx = cls; 3373 struct ConnectContext *connect_ctx = cls;
3374 struct ConnectTopologyContext *ct_ctx = connect_ctx->ct_ctx;
2941 struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg; 3375 struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg;
3376 struct PeerConnection *connection;
2942 pg->outstanding_connects--; 3377 pg->outstanding_connects--;
2943 ct_ctx->remaining_connections--; 3378
3379 /*
3380 * Check whether the inverse connection has been scheduled yet,
3381 * if not, we can remove it from the other peers list and avoid
3382 * even trying to connect them again!
3383 */
3384 connection = pg->peers[connect_ctx->second_index].connect_peers_head;
3385#if BAD
3386 other_peer = NULL;
3387#endif
3388
3389 while ((connection != NULL) &&
3390 (0 != memcmp(first, &pg->peers[connection->index].daemon->id, sizeof(struct GNUNET_PeerIdentity))))
3391 {
3392 connection = connection->next;
3393 }
3394
3395 if (connection != NULL) /* Can safely remove! */
3396 {
3397 ct_ctx->remaining_connections--;
3398 if (pg->notify_connection != NULL) /* Notify of reverse connection */
3399 pg->notify_connection (pg->notify_connection_cls, second, first, distance,
3400 second_cfg, first_cfg, second_daemon, first_daemon,
3401 emsg);
3402
3403 GNUNET_CONTAINER_DLL_remove(pg->peers[connect_ctx->second_index].connect_peers_head, pg->peers[connect_ctx->second_index].connect_peers_tail, connection);
3404 GNUNET_free(connection);
3405 }
3406
2944 if (ct_ctx->remaining_connections == 0) 3407 if (ct_ctx->remaining_connections == 0)
2945 { 3408 {
2946 if (ct_ctx->notify_connections_done != NULL) 3409 if (ct_ctx->notify_connections_done != NULL)
2947 ct_ctx->notify_connections_done (ct_ctx->notify_cls, NULL); 3410 ct_ctx->notify_connections_done (ct_ctx->notify_cls, NULL);
2948 GNUNET_free (ct_ctx);
2949 } 3411 }
2950 else 3412 else
2951 preschedule_connect(ct_ctx); 3413 preschedule_connect(pg);
2952 3414
2953 if (pg->notify_connection != NULL) 3415 if (pg->notify_connection != NULL)
2954 pg->notify_connection (pg->notify_connection_cls, first, second, distance, 3416 pg->notify_connection (pg->notify_connection_cls, first, second, distance,
2955 first_cfg, second_cfg, first_daemon, second_daemon, 3417 first_cfg, second_cfg, first_daemon, second_daemon,
2956 emsg); 3418 emsg);
3419
3420 GNUNET_free(connect_ctx);
2957} 3421}
2958 3422
2959 3423
@@ -2975,8 +3439,8 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2975 3439
2976 if ((pg->outstanding_connects > pg->max_outstanding_connections) || (pg->stop_connects == GNUNET_YES)) 3440 if ((pg->outstanding_connects > pg->max_outstanding_connections) || (pg->stop_connects == GNUNET_YES))
2977 { 3441 {
2978#if VERBOSE_TESTING > 2 3442#if VERBOSE_TESTING
2979 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3443 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2980 _ 3444 _
2981 ("Delaying connect, we have too many outstanding connections!\n")); 3445 ("Delaying connect, we have too many outstanding connections!\n"));
2982#endif 3446#endif
@@ -2986,20 +3450,24 @@ schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2986 } 3450 }
2987 else 3451 else
2988 { 3452 {
2989#if VERBOSE_TESTING > 2 3453#if VERBOSE_TESTING
2990 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3454 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2991 _("Creating connection, outstanding_connections is %d\n"), 3455 _("Creating connection, outstanding_connections is %d (max %d)\n"),
2992 outstanding_connects); 3456 pg->outstanding_connects, pg->max_outstanding_connections);
2993#endif 3457#endif
2994 pg->outstanding_connects++; 3458 pg->outstanding_connects++;
2995 pg->total_connects_scheduled++; 3459 pg->total_connects_scheduled++;
2996 GNUNET_TESTING_daemons_connect (connect_context->first, 3460 GNUNET_TESTING_daemons_connect (pg->peers[connect_context->first_index].daemon,
2997 connect_context->second, 3461 pg->peers[connect_context->second_index].daemon,
2998 connect_context->ct_ctx->connect_timeout, 3462 connect_context->ct_ctx->connect_timeout,
2999 connect_context->ct_ctx->connect_attempts, 3463 connect_context->ct_ctx->connect_attempts,
3464#if USE_SEND_HELLOS
3465 GNUNET_NO,
3466#else
3467 GNUNET_YES,
3468#endif
3000 &internal_connect_notify, 3469 &internal_connect_notify,
3001 connect_context->ct_ctx); 3470 connect_context); /* FIXME: free connect context! */
3002 GNUNET_free (connect_context);
3003 } 3471 }
3004} 3472}
3005 3473
@@ -3123,16 +3591,18 @@ connect_topology (struct GNUNET_TESTING_PeerGroup *pg,
3123{ 3591{
3124 unsigned int pg_iter; 3592 unsigned int pg_iter;
3125 unsigned int total; 3593 unsigned int total;
3126 struct ConnectTopologyContext *ct_ctx; 3594
3127#if OLD 3595#if OLD
3128 struct PeerConnection *connection_iter; 3596 struct PeerConnection *connection_iter;
3129#endif 3597#endif
3598#if USE_SEND_HELLOS
3599 struct SendHelloContext *send_hello_context
3600#endif
3130 3601
3131 total = 0; 3602 total = 0;
3132 ct_ctx = GNUNET_malloc (sizeof (struct ConnectTopologyContext)); 3603 pg->ct_ctx.notify_connections_done = notify_callback;
3133 ct_ctx->notify_connections_done = notify_callback; 3604 pg->ct_ctx.notify_cls = notify_cls;
3134 ct_ctx->notify_cls = notify_cls; 3605 pg->ct_ctx.pg = pg;
3135 ct_ctx->pg = pg;
3136 3606
3137 for (pg_iter = 0; pg_iter < pg->total; pg_iter++) 3607 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
3138 { 3608 {
@@ -3150,19 +3620,29 @@ connect_topology (struct GNUNET_TESTING_PeerGroup *pg,
3150 } 3620 }
3151 3621
3152 if (total == 0) 3622 if (total == 0)
3623 return total;
3624
3625 pg->ct_ctx.connect_timeout = connect_timeout;
3626 pg->ct_ctx.connect_attempts = connect_attempts;
3627 pg->ct_ctx.remaining_connections = total;
3628
3629#if USE_SEND_HELLOS
3630 /* First give all peers the HELLO's of other peers (connect to first peer's transport service, give HELLO's of other peers, continue...) */
3631 pg->remaining_hellos = total;
3632 for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
3153 { 3633 {
3154 GNUNET_free (ct_ctx); 3634 send_hello_context = GNUNET_malloc(sizeof(struct SendHelloContext));
3155 return total; 3635 send_hello_context->peer = &pg->peers[pg_iter];
3636 send_hello_context->peer_pos = pg->peers[pg_iter].connect_peers_head;
3637 send_hello_context->pg = pg;
3638 GNUNET_SCHEDULER_add_now(&schedule_send_hellos, send_hello_context);
3156 } 3639 }
3157 ct_ctx->connect_timeout = connect_timeout; 3640#else
3158 ct_ctx->connect_attempts = connect_attempts;
3159 ct_ctx->remaining_connections = total;
3160 ct_ctx->remaining_connects_to_schedule = total;
3161
3162 for (pg_iter = 0; pg_iter < pg->max_outstanding_connections; pg_iter++) 3641 for (pg_iter = 0; pg_iter < pg->max_outstanding_connections; pg_iter++)
3163 { 3642 {
3164 preschedule_connect(ct_ctx); 3643 preschedule_connect(pg);
3165 } 3644 }
3645#endif
3166 return total; 3646 return total;
3167 3647
3168} 3648}