diff options
author | Nathan S. Evans <evans@in.tum.de> | 2011-02-22 15:19:49 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2011-02-22 15:19:49 +0000 |
commit | 7c0698d2296e00d9544f48819f24ed4319e3fad8 (patch) | |
tree | 343507da792d950d8d24ed11648e433bcad304a9 /src/testing | |
parent | ac5cf07b590f788946d4b05f8e11b2414493f4eb (diff) | |
download | gnunet-7c0698d2296e00d9544f48819f24ed4319e3fad8.tar.gz gnunet-7c0698d2296e00d9544f48819f24ed4319e3fad8.zip |
Testing and core related changes.
Diffstat (limited to 'src/testing')
-rw-r--r-- | src/testing/test_testing_topology.c | 11 | ||||
-rw-r--r-- | src/testing/testing.c | 380 | ||||
-rw-r--r-- | src/testing/testing_group.c | 690 |
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 | |||
65 | process_hello (void *cls, const struct GNUNET_MessageHeader *message) | 65 | process_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 | ||
123 | static void | ||
124 | start_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 | |||
1734 | static void | ||
1735 | reattempt_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 | ¬ify_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 | ¬ify_connect_result, ctx); |
1727 | ctx->max_connect_attempts), | ||
1728 | ¬ify_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 | |||
1787 | static void | ||
1788 | reattempt_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 | ¬ify_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 | ||
164 | struct 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 | |||
162 | struct ShutdownContext | 198 | struct 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 | |||
639 | struct 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 | |||
712 | struct 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 | |||
722 | struct 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 | ||
798 | struct 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 | |||
765 | struct ConnectContext | 833 | struct 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 | ||
987 | static 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 * | |||
1176 | make_config (const struct GNUNET_CONFIGURATION_Handle *cfg, | 1256 | make_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 | */ |
2898 | static void preschedule_connect(struct ConnectTopologyContext *ct_ctx) | 2962 | static 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 */ | ||
2988 | static 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 | */ | ||
2997 | static void | ||
2998 | free_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 | */ | ||
3027 | static void | ||
3028 | notify_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 | */ | ||
3071 | static void | ||
3072 | send_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(¬ify_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 | */ | ||
3117 | static void | ||
3118 | core_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 | */ | ||
3218 | void | ||
3219 | core_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 | */ | ||
3240 | static void | ||
3241 | hello_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 | */ | ||
3299 | static 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 | } |