diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-09-16 14:13:57 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-09-16 14:13:57 +0000 |
commit | 797a58626759227befd9b055f01d2505216e2ccb (patch) | |
tree | f9ec2055955ba20b51916c0cc011f438cd866cbc /src | |
parent | 8583688db9b49c1bef90321e0c464fbfe9121885 (diff) | |
download | gnunet-797a58626759227befd9b055f01d2505216e2ccb.tar.gz gnunet-797a58626759227befd9b055f01d2505216e2ccb.zip |
many useless changes to the dht testing driver, mostly for churn (which may not even be useful)
Diffstat (limited to 'src')
-rw-r--r-- | src/dht/gnunet-dht-driver.c | 1182 |
1 files changed, 917 insertions, 265 deletions
diff --git a/src/dht/gnunet-dht-driver.c b/src/dht/gnunet-dht-driver.c index 07f1fbb04..cdd5e7c16 100644 --- a/src/dht/gnunet-dht-driver.c +++ b/src/dht/gnunet-dht-driver.c | |||
@@ -59,7 +59,7 @@ | |||
59 | 59 | ||
60 | #define DEFAULT_BUCKET_SIZE 4 | 60 | #define DEFAULT_BUCKET_SIZE 4 |
61 | 61 | ||
62 | #define FIND_PEER_THRESHOLD DEFAULT_BUCKET_SIZE * 2 | 62 | #define FIND_PEER_THRESHOLD 1 |
63 | 63 | ||
64 | /* If more than this many peers are added, slow down sending */ | 64 | /* If more than this many peers are added, slow down sending */ |
65 | #define MAX_FIND_PEER_CUTOFF 2500 | 65 | #define MAX_FIND_PEER_CUTOFF 2500 |
@@ -79,6 +79,8 @@ | |||
79 | 79 | ||
80 | #define DEFAULT_TOPOLOGY_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 8) | 80 | #define DEFAULT_TOPOLOGY_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 8) |
81 | 81 | ||
82 | #define DEFAULT_RECONNECT_ATTEMPTS 8 | ||
83 | |||
82 | /* | 84 | /* |
83 | * Default frequency for sending malicious get messages | 85 | * Default frequency for sending malicious get messages |
84 | */ | 86 | */ |
@@ -259,6 +261,104 @@ struct TopologyIteratorContext | |||
259 | struct GNUNET_TIME_Relative timeout; | 261 | struct GNUNET_TIME_Relative timeout; |
260 | }; | 262 | }; |
261 | 263 | ||
264 | |||
265 | struct PeerCount | ||
266 | { | ||
267 | /** Node in the heap */ | ||
268 | struct GNUNET_CONTAINER_HeapNode *heap_node; | ||
269 | |||
270 | /** Peer the count refers to */ | ||
271 | struct GNUNET_PeerIdentity peer_id; | ||
272 | |||
273 | /** Count of connections this peer has */ | ||
274 | unsigned int count; | ||
275 | }; | ||
276 | |||
277 | /** | ||
278 | * Context for sending out find peer requests. | ||
279 | */ | ||
280 | struct FindPeerContext | ||
281 | { | ||
282 | /** | ||
283 | * How long to send find peer requests, once the settle time | ||
284 | * is over don't send any more out! | ||
285 | * | ||
286 | * TODO: Add option for settle time and find peer sending time? | ||
287 | */ | ||
288 | struct GNUNET_TIME_Absolute endtime; | ||
289 | |||
290 | /** | ||
291 | * Number of connections in the current topology | ||
292 | * (after this round of find peer requests has ended). | ||
293 | */ | ||
294 | unsigned int current_peers; | ||
295 | |||
296 | /** | ||
297 | * Number of connections in the current topology | ||
298 | * (before this round of find peer requests started). | ||
299 | */ | ||
300 | unsigned int previous_peers; | ||
301 | |||
302 | /** | ||
303 | * Number of find peer requests we have currently | ||
304 | * outstanding. | ||
305 | */ | ||
306 | unsigned int outstanding; | ||
307 | |||
308 | /** | ||
309 | * Number of find peer requests to send in this round. | ||
310 | */ | ||
311 | unsigned int total; | ||
312 | |||
313 | /** | ||
314 | * Number of find peer requests sent last time around. | ||
315 | */ | ||
316 | unsigned int last_sent; | ||
317 | |||
318 | /** | ||
319 | * Hashmap of peers in the current topology, value | ||
320 | * is a PeerCount, with the number of connections | ||
321 | * this peer has. | ||
322 | */ | ||
323 | struct GNUNET_CONTAINER_MultiHashMap *peer_hash; | ||
324 | |||
325 | /** | ||
326 | * Min heap which orders values in the peer_hash for | ||
327 | * easy lookup. | ||
328 | */ | ||
329 | struct GNUNET_CONTAINER_Heap *peer_min_heap; | ||
330 | |||
331 | /** | ||
332 | * Callback for counting the peers in the current topology. | ||
333 | */ | ||
334 | GNUNET_TESTING_NotifyTopology count_peers_cb; | ||
335 | }; | ||
336 | |||
337 | enum DHT_ROUND_TYPES | ||
338 | { | ||
339 | /** | ||
340 | * Next full round (puts + gets). | ||
341 | */ | ||
342 | DHT_ROUND_NORMAL, | ||
343 | |||
344 | /** | ||
345 | * Next round of gets. | ||
346 | */ | ||
347 | DHT_ROUND_GET, | ||
348 | |||
349 | /** | ||
350 | * Next round of puts. | ||
351 | */ | ||
352 | DHT_ROUND_PUT, | ||
353 | |||
354 | /** | ||
355 | * Next round of churn. | ||
356 | */ | ||
357 | DHT_ROUND_CHURN | ||
358 | }; | ||
359 | |||
360 | |||
361 | |||
262 | /* Globals */ | 362 | /* Globals */ |
263 | 363 | ||
264 | /** | 364 | /** |
@@ -281,7 +381,9 @@ static struct GNUNET_TIME_Relative find_peer_offset; | |||
281 | 381 | ||
282 | static struct GNUNET_TIME_Relative seconds_per_peer_start; | 382 | static struct GNUNET_TIME_Relative seconds_per_peer_start; |
283 | 383 | ||
284 | static int do_find_peer; | 384 | static unsigned int do_find_peer; |
385 | |||
386 | static unsigned int in_dht_replication; | ||
285 | 387 | ||
286 | static unsigned long long test_data_size = DEFAULT_TEST_DATA_SIZE; | 388 | static unsigned long long test_data_size = DEFAULT_TEST_DATA_SIZE; |
287 | 389 | ||
@@ -295,6 +397,8 @@ static unsigned long long max_outstanding_find_peers; | |||
295 | 397 | ||
296 | static unsigned long long malicious_putters; | 398 | static unsigned long long malicious_putters; |
297 | 399 | ||
400 | static unsigned long long round_delay; | ||
401 | |||
298 | static unsigned long long malicious_droppers; | 402 | static unsigned long long malicious_droppers; |
299 | 403 | ||
300 | static unsigned long long malicious_get_frequency; | 404 | static unsigned long long malicious_get_frequency; |
@@ -310,6 +414,42 @@ static struct GNUNET_DHTLOG_Handle *dhtlog_handle; | |||
310 | static unsigned long long trialuid; | 414 | static unsigned long long trialuid; |
311 | 415 | ||
312 | /** | 416 | /** |
417 | * If GNUNET_YES, insert data at the same peers every time. | ||
418 | * Otherwise, choose a new random peer to insert at each time. | ||
419 | */ | ||
420 | static unsigned int replicate_same; | ||
421 | |||
422 | /** | ||
423 | * Number of rounds for testing (PUTS + GETS) | ||
424 | */ | ||
425 | static unsigned long long total_rounds; | ||
426 | |||
427 | /** | ||
428 | * Number of rounds already run | ||
429 | */ | ||
430 | static unsigned int rounds_finished; | ||
431 | |||
432 | /** | ||
433 | * Number of rounds of churn to read from the file (first line, should be a single number). | ||
434 | */ | ||
435 | static unsigned int churn_rounds; | ||
436 | |||
437 | /** | ||
438 | * Current round we are in for churn, tells us how many peers to connect/disconnect. | ||
439 | */ | ||
440 | static unsigned int current_churn_round; | ||
441 | |||
442 | /** | ||
443 | * Number of times to churn per round | ||
444 | */ | ||
445 | static unsigned long long churns_per_round; | ||
446 | |||
447 | /** | ||
448 | * Array of churn values. | ||
449 | */ | ||
450 | static unsigned int *churn_array; | ||
451 | |||
452 | /** | ||
313 | * Hash map of stats contexts. | 453 | * Hash map of stats contexts. |
314 | */ | 454 | */ |
315 | struct GNUNET_CONTAINER_MultiHashMap *stats_map; | 455 | struct GNUNET_CONTAINER_MultiHashMap *stats_map; |
@@ -449,6 +589,8 @@ static struct ProgressMeter *put_meter; | |||
449 | 589 | ||
450 | static struct ProgressMeter *get_meter; | 590 | static struct ProgressMeter *get_meter; |
451 | 591 | ||
592 | static GNUNET_HashCode *known_keys; | ||
593 | |||
452 | /* Global return value (0 for success, anything else for failure) */ | 594 | /* Global return value (0 for success, anything else for failure) */ |
453 | static int ok; | 595 | static int ok; |
454 | 596 | ||
@@ -516,6 +658,24 @@ update_meter(struct ProgressMeter *meter) | |||
516 | } | 658 | } |
517 | 659 | ||
518 | /** | 660 | /** |
661 | * Reset progress meter. | ||
662 | * | ||
663 | * @param meter the meter to reset | ||
664 | * | ||
665 | * @return GNUNET_YES if meter reset, | ||
666 | * GNUNET_SYSERR on error | ||
667 | */ | ||
668 | static int | ||
669 | reset_meter(struct ProgressMeter *meter) | ||
670 | { | ||
671 | if (meter == NULL) | ||
672 | return GNUNET_SYSERR; | ||
673 | |||
674 | meter->completed = 0; | ||
675 | return GNUNET_YES; | ||
676 | } | ||
677 | |||
678 | /** | ||
519 | * Release resources for meter | 679 | * Release resources for meter |
520 | * | 680 | * |
521 | * @param meter the meter to free | 681 | * @param meter the meter to free |
@@ -550,6 +710,7 @@ put_disconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
550 | test_put->disconnect_task = GNUNET_SCHEDULER_NO_TASK; | 710 | test_put->disconnect_task = GNUNET_SCHEDULER_NO_TASK; |
551 | GNUNET_DHT_disconnect(test_put->dht_handle); | 711 | GNUNET_DHT_disconnect(test_put->dht_handle); |
552 | test_put->dht_handle = NULL; | 712 | test_put->dht_handle = NULL; |
713 | test_put->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers)); | ||
553 | } | 714 | } |
554 | 715 | ||
555 | /** | 716 | /** |
@@ -826,6 +987,475 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
826 | } | 987 | } |
827 | 988 | ||
828 | /** | 989 | /** |
990 | * Forward declaration. | ||
991 | */ | ||
992 | static void | ||
993 | do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc); | ||
994 | |||
995 | /** | ||
996 | * Forward declaration. | ||
997 | */ | ||
998 | static void | ||
999 | do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc); | ||
1000 | |||
1001 | /** | ||
1002 | * Iterator over hash map entries. | ||
1003 | * | ||
1004 | * @param cls closure | ||
1005 | * @param key current key code | ||
1006 | * @param value value in the hash map | ||
1007 | * @return GNUNET_YES if we should continue to | ||
1008 | * iterate, | ||
1009 | * GNUNET_NO if not. | ||
1010 | */ | ||
1011 | static int remove_peer_count (void *cls, | ||
1012 | const GNUNET_HashCode * key, | ||
1013 | void *value) | ||
1014 | { | ||
1015 | struct FindPeerContext *find_peer_ctx = cls; | ||
1016 | struct PeerCount *peer_count = value; | ||
1017 | GNUNET_CONTAINER_heap_remove_node(find_peer_ctx->peer_min_heap, peer_count->heap_node); | ||
1018 | GNUNET_free(peer_count); | ||
1019 | |||
1020 | return GNUNET_YES; | ||
1021 | } | ||
1022 | |||
1023 | /** | ||
1024 | * Connect to all peers in the peer group and iterate over their | ||
1025 | * connections. | ||
1026 | */ | ||
1027 | static void | ||
1028 | count_new_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1029 | { | ||
1030 | struct FindPeerContext *find_peer_context = cls; | ||
1031 | find_peer_context->previous_peers = find_peer_context->current_peers; | ||
1032 | find_peer_context->current_peers = 0; | ||
1033 | GNUNET_TESTING_get_topology (pg, find_peer_context->count_peers_cb, find_peer_context); | ||
1034 | } | ||
1035 | |||
1036 | static void | ||
1037 | decrement_find_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1038 | { | ||
1039 | struct TestFindPeer *test_find_peer = cls; | ||
1040 | GNUNET_assert(test_find_peer->find_peer_context->outstanding > 0); | ||
1041 | test_find_peer->find_peer_context->outstanding--; | ||
1042 | test_find_peer->find_peer_context->total--; | ||
1043 | if ((0 == test_find_peer->find_peer_context->total) && | ||
1044 | (GNUNET_TIME_absolute_get_remaining(test_find_peer->find_peer_context->endtime).value > 0)) | ||
1045 | { | ||
1046 | GNUNET_SCHEDULER_add_now(sched, &count_new_peers, test_find_peer->find_peer_context); | ||
1047 | } | ||
1048 | GNUNET_free(test_find_peer); | ||
1049 | } | ||
1050 | |||
1051 | /** | ||
1052 | * A find peer request has been sent to the server, now we will schedule a task | ||
1053 | * to wait the appropriate time to allow the request to go out and back. | ||
1054 | * | ||
1055 | * @param cls closure - a TestFindPeer struct | ||
1056 | * @param tc context the task is being called with | ||
1057 | */ | ||
1058 | static void | ||
1059 | handle_find_peer_sent (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1060 | { | ||
1061 | struct TestFindPeer *test_find_peer = cls; | ||
1062 | |||
1063 | GNUNET_DHT_disconnect(test_find_peer->dht_handle); | ||
1064 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_divide(find_peer_delay, 2), &decrement_find_peers, test_find_peer); | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | static void | ||
1069 | send_find_peer_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1070 | { | ||
1071 | struct TestFindPeer *test_find_peer = cls; | ||
1072 | |||
1073 | if (test_find_peer->find_peer_context->outstanding > max_outstanding_find_peers) | ||
1074 | { | ||
1075 | GNUNET_SCHEDULER_add_delayed(sched, find_peer_offset, &send_find_peer_request, test_find_peer); | ||
1076 | return; | ||
1077 | } | ||
1078 | |||
1079 | test_find_peer->find_peer_context->outstanding++; | ||
1080 | if (GNUNET_TIME_absolute_get_remaining(test_find_peer->find_peer_context->endtime).value == 0) | ||
1081 | { | ||
1082 | GNUNET_SCHEDULER_add_now(sched, &decrement_find_peers, test_find_peer); | ||
1083 | return; | ||
1084 | } | ||
1085 | |||
1086 | test_find_peer->dht_handle = GNUNET_DHT_connect(sched, test_find_peer->daemon->cfg, 1); | ||
1087 | GNUNET_assert(test_find_peer->dht_handle != NULL); | ||
1088 | GNUNET_DHT_find_peers (test_find_peer->dht_handle, | ||
1089 | &handle_find_peer_sent, test_find_peer); | ||
1090 | } | ||
1091 | |||
1092 | /** | ||
1093 | * Set up a single find peer request for each peer in the topology. Do this | ||
1094 | * until the settle time is over, limited by the number of outstanding requests | ||
1095 | * and the time allowed for each one! | ||
1096 | */ | ||
1097 | static void | ||
1098 | schedule_churn_find_peer_requests (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1099 | { | ||
1100 | struct FindPeerContext *find_peer_ctx = cls; | ||
1101 | struct TestFindPeer *test_find_peer; | ||
1102 | struct PeerCount *peer_count; | ||
1103 | uint32_t i; | ||
1104 | |||
1105 | if (find_peer_ctx->previous_peers == 0) /* First time, go slowly */ | ||
1106 | find_peer_ctx->total = 1; | ||
1107 | else if (find_peer_ctx->current_peers - find_peer_ctx->previous_peers > MAX_FIND_PEER_CUTOFF) /* Found LOTS of peers, still go slowly */ | ||
1108 | find_peer_ctx->total = find_peer_ctx->last_sent - (find_peer_ctx->last_sent / 8); | ||
1109 | else | ||
1110 | find_peer_ctx->total = find_peer_ctx->last_sent * 2; | ||
1111 | |||
1112 | if (find_peer_ctx->total > max_outstanding_find_peers) | ||
1113 | find_peer_ctx->total = max_outstanding_find_peers; | ||
1114 | |||
1115 | find_peer_ctx->last_sent = find_peer_ctx->total; | ||
1116 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending %u find peer messages (after churn)\n", find_peer_ctx->total); | ||
1117 | |||
1118 | find_peer_offset = GNUNET_TIME_relative_divide(find_peer_delay, find_peer_ctx->total); | ||
1119 | for (i = 0; i < find_peer_ctx->total; i++) | ||
1120 | { | ||
1121 | test_find_peer = GNUNET_malloc(sizeof(struct TestFindPeer)); | ||
1122 | /* If we have sent requests, choose peers with a low number of connections to send requests from */ | ||
1123 | peer_count = GNUNET_CONTAINER_heap_remove_root(find_peer_ctx->peer_min_heap); | ||
1124 | GNUNET_CONTAINER_multihashmap_remove(find_peer_ctx->peer_hash, &peer_count->peer_id.hashPubKey, peer_count); | ||
1125 | test_find_peer->daemon = GNUNET_TESTING_daemon_get_by_id(pg, &peer_count->peer_id); | ||
1126 | GNUNET_assert(test_find_peer->daemon != NULL); | ||
1127 | test_find_peer->find_peer_context = find_peer_ctx; | ||
1128 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(find_peer_offset, i), &send_find_peer_request, test_find_peer); | ||
1129 | } | ||
1130 | |||
1131 | if ((find_peer_ctx->peer_hash == NULL) && (find_peer_ctx->peer_min_heap == NULL)) | ||
1132 | { | ||
1133 | find_peer_ctx->peer_hash = GNUNET_CONTAINER_multihashmap_create(num_peers); | ||
1134 | find_peer_ctx->peer_min_heap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1135 | } | ||
1136 | else | ||
1137 | { | ||
1138 | GNUNET_CONTAINER_multihashmap_iterate(find_peer_ctx->peer_hash, &remove_peer_count, find_peer_ctx); | ||
1139 | GNUNET_CONTAINER_multihashmap_destroy(find_peer_ctx->peer_hash); | ||
1140 | find_peer_ctx->peer_hash = GNUNET_CONTAINER_multihashmap_create(num_peers); | ||
1141 | } | ||
1142 | |||
1143 | GNUNET_assert(0 == GNUNET_CONTAINER_multihashmap_size(find_peer_ctx->peer_hash)); | ||
1144 | GNUNET_assert(0 == GNUNET_CONTAINER_heap_get_size(find_peer_ctx->peer_min_heap)); | ||
1145 | } | ||
1146 | |||
1147 | /** | ||
1148 | * Add a connection to the find_peer_context given. This may | ||
1149 | * be complete overkill, but allows us to choose the peers with | ||
1150 | * the least connections to initiate find peer requests from. | ||
1151 | */ | ||
1152 | static void add_new_connection(struct FindPeerContext *find_peer_context, | ||
1153 | const struct GNUNET_PeerIdentity *first, | ||
1154 | const struct GNUNET_PeerIdentity *second) | ||
1155 | { | ||
1156 | struct PeerCount *first_count; | ||
1157 | struct PeerCount *second_count; | ||
1158 | |||
1159 | if (GNUNET_CONTAINER_multihashmap_contains(find_peer_context->peer_hash, &first->hashPubKey)) | ||
1160 | { | ||
1161 | first_count = GNUNET_CONTAINER_multihashmap_get(find_peer_context->peer_hash, &first->hashPubKey); | ||
1162 | first_count->count++; | ||
1163 | GNUNET_CONTAINER_heap_update_cost(find_peer_context->peer_min_heap, first_count->heap_node, first_count->count); | ||
1164 | } | ||
1165 | else | ||
1166 | { | ||
1167 | first_count = GNUNET_malloc(sizeof(struct PeerCount)); | ||
1168 | first_count->count = 1; | ||
1169 | memcpy(&first_count->peer_id, first, sizeof(struct GNUNET_PeerIdentity)); | ||
1170 | first_count->heap_node = GNUNET_CONTAINER_heap_insert(find_peer_context->peer_min_heap, first_count, first_count->count); | ||
1171 | GNUNET_CONTAINER_multihashmap_put(find_peer_context->peer_hash, &first->hashPubKey, first_count, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1172 | } | ||
1173 | |||
1174 | if (GNUNET_CONTAINER_multihashmap_contains(find_peer_context->peer_hash, &second->hashPubKey)) | ||
1175 | { | ||
1176 | second_count = GNUNET_CONTAINER_multihashmap_get(find_peer_context->peer_hash, &second->hashPubKey); | ||
1177 | second_count->count++; | ||
1178 | GNUNET_CONTAINER_heap_update_cost(find_peer_context->peer_min_heap, second_count->heap_node, second_count->count); | ||
1179 | } | ||
1180 | else | ||
1181 | { | ||
1182 | second_count = GNUNET_malloc(sizeof(struct PeerCount)); | ||
1183 | second_count->count = 1; | ||
1184 | memcpy(&second_count->peer_id, second, sizeof(struct GNUNET_PeerIdentity)); | ||
1185 | second_count->heap_node = GNUNET_CONTAINER_heap_insert(find_peer_context->peer_min_heap, second_count, second_count->count); | ||
1186 | GNUNET_CONTAINER_multihashmap_put(find_peer_context->peer_hash, &second->hashPubKey, second_count, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | |||
1191 | /** | ||
1192 | * Iterate over min heap of connections per peer. For any | ||
1193 | * peer that has 0 connections, attempt to connect them to | ||
1194 | * some random peer. | ||
1195 | * | ||
1196 | * @param cls closure a struct FindPeerContext | ||
1197 | * @param node internal node of the heap | ||
1198 | * @param element value stored, a struct PeerCount | ||
1199 | * @param cost cost associated with the node | ||
1200 | * @return GNUNET_YES if we should continue to iterate, | ||
1201 | * GNUNET_NO if not. | ||
1202 | */ | ||
1203 | static int iterate_min_heap_peers (void *cls, | ||
1204 | struct GNUNET_CONTAINER_HeapNode *node, | ||
1205 | void *element, | ||
1206 | GNUNET_CONTAINER_HeapCostType cost) | ||
1207 | { | ||
1208 | struct FindPeerContext *find_peer_context = cls; | ||
1209 | struct PeerCount *peer_count = element; | ||
1210 | struct GNUNET_TESTING_Daemon *d1; | ||
1211 | struct GNUNET_TESTING_Daemon *d2; | ||
1212 | struct GNUNET_TIME_Relative timeout; | ||
1213 | if (cost == 0) | ||
1214 | { | ||
1215 | d1 = GNUNET_TESTING_daemon_get_by_id (pg, &peer_count->peer_id); | ||
1216 | d2 = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers)); | ||
1217 | /** Just try to connect the peers, don't worry about callbacks, etc. **/ | ||
1218 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Peer %s has 0 connections. Trying to connect to %s...\n", GNUNET_i2s(&peer_count->peer_id), d2->shortname); | ||
1219 | timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, DEFAULT_CONNECT_TIMEOUT); | ||
1220 | if (GNUNET_TIME_relative_to_absolute(timeout).value > find_peer_context->endtime.value) | ||
1221 | { | ||
1222 | timeout = GNUNET_TIME_absolute_get_remaining(find_peer_context->endtime); | ||
1223 | } | ||
1224 | GNUNET_TESTING_daemons_connect(d1, d2, timeout, DEFAULT_RECONNECT_ATTEMPTS, NULL, NULL); | ||
1225 | } | ||
1226 | if (GNUNET_TIME_absolute_get_remaining(find_peer_context->endtime).value > 0) | ||
1227 | return GNUNET_YES; | ||
1228 | else | ||
1229 | return GNUNET_NO; | ||
1230 | } | ||
1231 | |||
1232 | /** | ||
1233 | * Callback for iterating over all the peer connections of a peer group. | ||
1234 | * Used after we have churned on some peers to find which ones have zero | ||
1235 | * connections so we can make them issue find peer requests. | ||
1236 | */ | ||
1237 | void count_peers_churn_cb (void *cls, | ||
1238 | const struct GNUNET_PeerIdentity *first, | ||
1239 | const struct GNUNET_PeerIdentity *second, | ||
1240 | struct GNUNET_TIME_Relative latency, | ||
1241 | uint32_t distance, | ||
1242 | const char *emsg) | ||
1243 | { | ||
1244 | struct FindPeerContext *find_peer_context = cls; | ||
1245 | struct TopologyIteratorContext *topo_ctx; | ||
1246 | struct PeerCount *peer_count; | ||
1247 | |||
1248 | if ((first != NULL) && (second != NULL)) | ||
1249 | { | ||
1250 | add_new_connection(find_peer_context, first, second); | ||
1251 | find_peer_context->current_peers++; | ||
1252 | } | ||
1253 | else | ||
1254 | { | ||
1255 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Peer count finished (%u connections)\n", | ||
1256 | find_peer_context->current_peers); | ||
1257 | peer_count = GNUNET_CONTAINER_heap_peek(find_peer_context->peer_min_heap); | ||
1258 | |||
1259 | /* WAIT. When peers are churned they will come back with their peers (at least in peerinfo), because the HOSTS file doesn't likely get removed. CRAP. */ | ||
1260 | /* NO they won't, because we have disabled peerinfo writing to disk (remember?) so we WILL have to give them new connections */ | ||
1261 | /* Best course of action: have DHT automatically try to add peers from peerinfo on startup. This way IF peerinfo writes to file | ||
1262 | * then some peers will end up connected. | ||
1263 | * | ||
1264 | * Also, find any peers that have zero connections here and set up a task to choose at random another peer in the network to | ||
1265 | * connect to. Of course, if they are blacklisted from that peer they won't be able to connect, so we will have to keep trying | ||
1266 | * until they get a peer. | ||
1267 | */ | ||
1268 | /* However, they won't automatically be connected to any of their previous peers... How can we handle that? */ | ||
1269 | /* So now we have choices: do we want them to come back with all their connections? Probably not, but it solves this mess. */ | ||
1270 | |||
1271 | /* Second problem, which is still a problem, is that a FIND_PEER request won't work when a peer has no connections */ | ||
1272 | |||
1273 | /** | ||
1274 | * Okay, so here's how this *should* work now. | ||
1275 | * | ||
1276 | * 1. We check the min heap for any peers that have 0 connections. | ||
1277 | * a. If any are found, we iterate over the heap and just randomly | ||
1278 | * choose another peer and ask testing to please connect the two. | ||
1279 | * This takes care of the case that a peer just randomly joins the | ||
1280 | * network. However, if there are strict topology restrictions | ||
1281 | * (imagine a ring) choosing randomly most likely won't help. | ||
1282 | * We make sure the connection attempt doesn't take longer than | ||
1283 | * the total timeout, but don't care too much about the result. | ||
1284 | * b. After that, we still schedule the find peer requests (concurrently | ||
1285 | * with the connect attempts most likely). This handles the case | ||
1286 | * that the DHT iterates over peerinfo and just needs to try to send | ||
1287 | * a message to get connected. This should handle the case that the | ||
1288 | * topology is very strict. | ||
1289 | * | ||
1290 | * 2. If all peers have > 0 connections, we still send find peer requests | ||
1291 | * as long as possible (until timeout is reached) to help out those | ||
1292 | * peers that were newly churned and need more connections. This is because | ||
1293 | * once all new peers have established a single connection, they won't be | ||
1294 | * well connected. | ||
1295 | * | ||
1296 | * 3. Once we reach the timeout, we can do no more. We must schedule the | ||
1297 | * next iteration of get requests regardless of connections that peers | ||
1298 | * may or may not have. | ||
1299 | * | ||
1300 | * Caveat: it would be nice to get peers to take data offline with them and | ||
1301 | * come back with it (or not) based on the testing framework. The | ||
1302 | * same goes for remembering previous connections, but putting either | ||
1303 | * into the general testing churn options seems like overkill because | ||
1304 | * these are very specialized cases. | ||
1305 | */ | ||
1306 | if ((peer_count->count == 0) && (GNUNET_TIME_absolute_get_remaining(find_peer_context->endtime).value > 0)) | ||
1307 | { | ||
1308 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Found peer with no connections, will choose some peers at random to connect to!\n"); | ||
1309 | GNUNET_CONTAINER_heap_iterate (find_peer_context->peer_min_heap, &iterate_min_heap_peers, find_peer_context); | ||
1310 | GNUNET_SCHEDULER_add_now(sched, &schedule_churn_find_peer_requests, find_peer_context); | ||
1311 | } | ||
1312 | else if (GNUNET_TIME_absolute_get_remaining(find_peer_context->endtime).value > 0) | ||
1313 | { | ||
1314 | GNUNET_SCHEDULER_add_now(sched, &schedule_churn_find_peer_requests, find_peer_context); | ||
1315 | } | ||
1316 | else | ||
1317 | { | ||
1318 | GNUNET_CONTAINER_multihashmap_iterate(find_peer_context->peer_hash, &remove_peer_count, find_peer_context); | ||
1319 | GNUNET_CONTAINER_multihashmap_destroy(find_peer_context->peer_hash); | ||
1320 | GNUNET_CONTAINER_heap_destroy(find_peer_context->peer_min_heap); | ||
1321 | GNUNET_free(find_peer_context); | ||
1322 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Churn round %u of %llu finished, scheduling next GET round.\n", current_churn_round, churn_rounds); | ||
1323 | if (dhtlog_handle != NULL) | ||
1324 | { | ||
1325 | topo_ctx = GNUNET_malloc(sizeof(struct TopologyIteratorContext)); | ||
1326 | topo_ctx->cont = &do_get; | ||
1327 | topo_ctx->cls = all_gets; | ||
1328 | topo_ctx->timeout = DEFAULT_GET_TIMEOUT; | ||
1329 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), | ||
1330 | &end_badly, "from do gets (count_peers_churn_cb)"); | ||
1331 | GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx); | ||
1332 | } | ||
1333 | else | ||
1334 | { | ||
1335 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), | ||
1336 | &end_badly, "from do gets (count_peers_churn_cb)"); | ||
1337 | GNUNET_SCHEDULER_add_now(sched, &do_get, all_gets); | ||
1338 | } | ||
1339 | } | ||
1340 | } | ||
1341 | } | ||
1342 | |||
1343 | /** | ||
1344 | * Called when churning of the topology has finished. | ||
1345 | * | ||
1346 | * @param cls closure unused | ||
1347 | * @param emsg NULL on success, or a printable error on failure | ||
1348 | */ | ||
1349 | static void churn_complete (void *cls, const char *emsg) | ||
1350 | { | ||
1351 | struct FindPeerContext *find_peer_context = cls; | ||
1352 | struct PeerCount *peer_count; | ||
1353 | unsigned int i; | ||
1354 | struct GNUNET_TESTING_Daemon *temp_daemon; | ||
1355 | struct TopologyIteratorContext *topo_ctx; | ||
1356 | |||
1357 | if (emsg != NULL) | ||
1358 | { | ||
1359 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ending test, churning of peers failed with error `%s'", emsg); | ||
1360 | GNUNET_SCHEDULER_add_now(sched, &end_badly, (void *)emsg); | ||
1361 | return; | ||
1362 | } | ||
1363 | |||
1364 | /** | ||
1365 | * If we switched any peers on, we have to somehow force connect the new peer to | ||
1366 | * SOME bootstrap peer in the network. First schedule a task to find all peers | ||
1367 | * with no connections, then choose a random peer for each and connect them. | ||
1368 | */ | ||
1369 | if (find_peer_context != NULL) | ||
1370 | { | ||
1371 | for (i = 0; i < num_peers; i ++) | ||
1372 | { | ||
1373 | temp_daemon = GNUNET_TESTING_daemon_get(pg, i); | ||
1374 | peer_count = GNUNET_malloc(sizeof(struct PeerCount)); | ||
1375 | memcpy(&peer_count->peer_id, &temp_daemon->id, sizeof(struct GNUNET_PeerIdentity)); | ||
1376 | peer_count->heap_node = GNUNET_CONTAINER_heap_insert(find_peer_context->peer_min_heap, peer_count, peer_count->count); | ||
1377 | GNUNET_CONTAINER_multihashmap_put(find_peer_context->peer_hash, &temp_daemon->id.hashPubKey, peer_count, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1378 | } | ||
1379 | GNUNET_TESTING_get_topology (pg, &count_peers_churn_cb, find_peer_context); | ||
1380 | } | ||
1381 | else | ||
1382 | { | ||
1383 | if (dhtlog_handle != NULL) | ||
1384 | { | ||
1385 | topo_ctx = GNUNET_malloc(sizeof(struct TopologyIteratorContext)); | ||
1386 | topo_ctx->cont = &do_get; | ||
1387 | topo_ctx->cls = all_gets; | ||
1388 | topo_ctx->timeout = DEFAULT_GET_TIMEOUT; | ||
1389 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), | ||
1390 | &end_badly, "from do gets (churn_complete)"); | ||
1391 | GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx); | ||
1392 | } | ||
1393 | else | ||
1394 | { | ||
1395 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), | ||
1396 | &end_badly, "from do gets (churn_complete)"); | ||
1397 | if (dhtlog_handle != NULL) | ||
1398 | dhtlog_handle->insert_round(DHT_ROUND_GET, rounds_finished); | ||
1399 | GNUNET_SCHEDULER_add_now(sched, &do_get, all_gets); | ||
1400 | } | ||
1401 | } | ||
1402 | } | ||
1403 | |||
1404 | /** | ||
1405 | * Decide how many peers to turn on or off in this round, make sure the | ||
1406 | * numbers actually make sense, then do so. This function sets in motion | ||
1407 | * churn, find peer requests for newly joined peers, and issuing get | ||
1408 | * requests once the new peers have done so. | ||
1409 | * | ||
1410 | * @param cls closure (unused) | ||
1411 | * @param cls task context (unused) | ||
1412 | */ | ||
1413 | static void | ||
1414 | churn_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1415 | { | ||
1416 | unsigned int count_running; | ||
1417 | unsigned int churn_up; | ||
1418 | unsigned int churn_down; | ||
1419 | struct GNUNET_TIME_Relative timeout; | ||
1420 | struct FindPeerContext *find_peer_context; | ||
1421 | |||
1422 | churn_up = churn_down = 0; | ||
1423 | count_running = GNUNET_TESTING_daemons_running(pg); | ||
1424 | if (count_running > churn_array[current_churn_round]) | ||
1425 | churn_down = count_running - churn_array[current_churn_round]; | ||
1426 | else if (count_running < churn_array[current_churn_round]) | ||
1427 | churn_up = churn_array[current_churn_round] - count_running; | ||
1428 | else | ||
1429 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Not churning any peers, topology unchanged.\n"); | ||
1430 | |||
1431 | if (churn_up > num_peers - count_running) | ||
1432 | { | ||
1433 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Churn file specified %u peers (up); only have %u!", churn_array[current_churn_round], num_peers); | ||
1434 | churn_up = num_peers - count_running; | ||
1435 | } | ||
1436 | else if (churn_down > count_running) | ||
1437 | { | ||
1438 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Churn file specified %u peers (down); only have %u!", churn_array[current_churn_round], count_running); | ||
1439 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "This will leave NO peers running (mistake in churn configuration?)!"); | ||
1440 | churn_down = count_running; | ||
1441 | } | ||
1442 | timeout = GNUNET_TIME_relative_multiply(seconds_per_peer_start, churn_up > 0 ? churn_up : churn_down); | ||
1443 | |||
1444 | find_peer_context = NULL; | ||
1445 | if (churn_up > 0) /* Only need to do find peer requests if we turned new peers on */ | ||
1446 | { | ||
1447 | find_peer_context = GNUNET_malloc(sizeof(struct FindPeerContext)); | ||
1448 | find_peer_context->count_peers_cb = &count_peers_churn_cb; | ||
1449 | find_peer_context->previous_peers = 0; | ||
1450 | find_peer_context->current_peers = 0; | ||
1451 | find_peer_context->endtime = GNUNET_TIME_relative_to_absolute(timeout); | ||
1452 | } | ||
1453 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "churn_peers: want %u total, %u running, starting %u, stopping %u\n", | ||
1454 | churn_array[current_churn_round], count_running, churn_up, churn_down); | ||
1455 | GNUNET_TESTING_daemons_churn(pg, churn_down, churn_up, timeout, &churn_complete, find_peer_context); | ||
1456 | } | ||
1457 | |||
1458 | /** | ||
829 | * Task to release DHT handle associated with GET request. | 1459 | * Task to release DHT handle associated with GET request. |
830 | */ | 1460 | */ |
831 | static void | 1461 | static void |
@@ -837,22 +1467,78 @@ get_stop_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
837 | GNUNET_DHT_disconnect(test_get->dht_handle); | 1467 | GNUNET_DHT_disconnect(test_get->dht_handle); |
838 | test_get->dht_handle = NULL; | 1468 | test_get->dht_handle = NULL; |
839 | 1469 | ||
1470 | /* Reset the uid (which item to search for) and the daemon (which peer to search from) for later get request iterations */ | ||
1471 | test_get->uid = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_puts); | ||
1472 | test_get->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers)); | ||
1473 | |||
840 | #if VERBOSE > 1 | 1474 | #if VERBOSE > 1 |
841 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d gets succeeded, %d gets failed!\n", gets_completed, gets_failed); | 1475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d gets succeeded, %d gets failed!\n", gets_completed, gets_failed); |
842 | #endif | 1476 | #endif |
843 | update_meter(get_meter); | 1477 | update_meter(get_meter); |
844 | if ((gets_completed + gets_failed == num_gets) && (outstanding_gets == 0)) | 1478 | if ((gets_completed + gets_failed == num_gets) && (outstanding_gets == 0)) |
845 | { | 1479 | { |
1480 | fprintf(stderr, "Canceling die task (get_stop_finished) %llu gets completed, %llu gets failed\n", gets_completed, gets_failed); | ||
846 | GNUNET_SCHEDULER_cancel(sched, die_task); | 1481 | GNUNET_SCHEDULER_cancel(sched, die_task); |
847 | //GNUNET_SCHEDULER_add_now(sched, &finish_testing, NULL); | 1482 | reset_meter(put_meter); |
848 | if (dhtlog_handle != NULL) | 1483 | reset_meter(get_meter); |
1484 | /** | ||
1485 | * Handle all cases: | ||
1486 | * 1) Testing is completely finished, call the topology iteration dealy and die | ||
1487 | * 2) Testing is not finished, churn the network and do gets again (current_churn_round < churn_rounds) | ||
1488 | * 3) Testing is not finished, reschedule all the PUTS *and* GETS again (num_rounds > 1) | ||
1489 | */ | ||
1490 | if (rounds_finished == total_rounds - 1) /* Everything is finished, end testing */ | ||
849 | { | 1491 | { |
850 | topo_ctx = GNUNET_malloc(sizeof(struct TopologyIteratorContext)); | 1492 | if (dhtlog_handle != NULL) |
851 | topo_ctx->cont = &log_dht_statistics; | 1493 | { |
852 | GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx); | 1494 | topo_ctx = GNUNET_malloc(sizeof(struct TopologyIteratorContext)); |
1495 | topo_ctx->cont = &log_dht_statistics; | ||
1496 | GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx); | ||
1497 | } | ||
1498 | else | ||
1499 | GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL); | ||
1500 | } | ||
1501 | else if (current_churn_round < churns_per_round * (rounds_finished + 1)) /* Do next round of churn */ | ||
1502 | { | ||
1503 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Current churn round %u, real round %u, scheduling next round of churn.\n", current_churn_round, rounds_finished + 1); | ||
1504 | gets_completed = 0; | ||
1505 | gets_failed = 0; | ||
1506 | current_churn_round++; | ||
1507 | |||
1508 | if (dhtlog_handle != NULL) | ||
1509 | dhtlog_handle->insert_round(DHT_ROUND_CHURN, rounds_finished); | ||
1510 | |||
1511 | GNUNET_SCHEDULER_add_now(sched, &churn_peers, NULL); | ||
1512 | } | ||
1513 | else if (rounds_finished < total_rounds - 1) /* Start a new complete round */ | ||
1514 | { | ||
1515 | rounds_finished++; | ||
1516 | gets_completed = 0; | ||
1517 | gets_failed = 0; | ||
1518 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Round %u of %llu finished, scheduling next round.\n", rounds_finished, total_rounds); | ||
1519 | /** Make sure we only get here after churning appropriately */ | ||
1520 | GNUNET_assert(current_churn_round == churn_rounds); | ||
1521 | current_churn_round = 0; | ||
1522 | |||
1523 | /** We reset the peer daemon for puts and gets on each disconnect, so all we need to do is start another round! */ | ||
1524 | if (GNUNET_YES == in_dht_replication) /* Replication done in DHT, don't redo puts! */ | ||
1525 | { | ||
1526 | if (dhtlog_handle != NULL) | ||
1527 | dhtlog_handle->insert_round(DHT_ROUND_GET, rounds_finished); | ||
1528 | |||
1529 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, round_delay), all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), | ||
1530 | &end_badly, "from do gets (next round)"); | ||
1531 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, round_delay), &do_get, all_gets); | ||
1532 | } | ||
1533 | else | ||
1534 | { | ||
1535 | if (dhtlog_handle != NULL) | ||
1536 | dhtlog_handle->insert_round(DHT_ROUND_NORMAL, rounds_finished); | ||
1537 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, round_delay), GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, num_puts * 2)), | ||
1538 | &end_badly, "from do puts"); | ||
1539 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, round_delay), &do_put, all_puts); | ||
1540 | } | ||
853 | } | 1541 | } |
854 | else | ||
855 | GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL); | ||
856 | } | 1542 | } |
857 | } | 1543 | } |
858 | 1544 | ||
@@ -890,18 +1576,14 @@ void get_result_iterator (void *cls, | |||
890 | const void *data) | 1576 | const void *data) |
891 | { | 1577 | { |
892 | struct TestGetContext *test_get = cls; | 1578 | struct TestGetContext *test_get = cls; |
893 | GNUNET_HashCode search_key; /* Key stored under */ | ||
894 | char original_data[test_data_size]; /* Made up data to store */ | ||
895 | |||
896 | memset(original_data, test_get->uid, sizeof(original_data)); | ||
897 | GNUNET_CRYPTO_hash(original_data, test_data_size, &search_key); | ||
898 | 1579 | ||
899 | if (test_get->succeeded == GNUNET_YES) | 1580 | if (test_get->succeeded == GNUNET_YES) |
900 | return; /* Get has already been successful, probably ending now */ | 1581 | return; /* Get has already been successful, probably ending now */ |
901 | 1582 | ||
902 | if ((0 != memcmp(&search_key, key, sizeof (GNUNET_HashCode))) || (0 != memcmp(original_data, data, sizeof(original_data)))) | 1583 | if (0 != memcmp(&known_keys[test_get->uid], key, sizeof (GNUNET_HashCode))) /* || (0 != memcmp(original_data, data, sizeof(original_data))))*/ |
903 | { | 1584 | { |
904 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Key or data is not the same as was inserted!\n"); | 1585 | gets_completed++; |
1586 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Key or data is not the same as was inserted!\n"); | ||
905 | } | 1587 | } |
906 | else | 1588 | else |
907 | { | 1589 | { |
@@ -933,8 +1615,6 @@ static void | |||
933 | do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | 1615 | do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) |
934 | { | 1616 | { |
935 | struct TestGetContext *test_get = cls; | 1617 | struct TestGetContext *test_get = cls; |
936 | GNUNET_HashCode key; /* Made up key to store data under */ | ||
937 | char data[test_data_size]; /* Made up data to store */ | ||
938 | 1618 | ||
939 | if (num_gets == 0) | 1619 | if (num_gets == 0) |
940 | { | 1620 | { |
@@ -944,23 +1624,26 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
944 | if (test_get == NULL) | 1624 | if (test_get == NULL) |
945 | return; /* End of the list */ | 1625 | return; /* End of the list */ |
946 | 1626 | ||
947 | memset(data, test_get->uid, sizeof(data)); | 1627 | /* Set this here in case we are re-running gets */ |
948 | GNUNET_CRYPTO_hash(data, test_data_size, &key); | 1628 | test_get->succeeded = GNUNET_NO; |
949 | 1629 | ||
1630 | /* Check if more gets are outstanding than should be */ | ||
950 | if (outstanding_gets > max_outstanding_gets) | 1631 | if (outstanding_gets > max_outstanding_gets) |
951 | { | 1632 | { |
952 | GNUNET_SCHEDULER_add_delayed (sched, get_delay, &do_get, test_get); | 1633 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 200), &do_get, test_get); |
953 | return; | 1634 | return; |
954 | } | 1635 | } |
955 | 1636 | ||
1637 | /* Connect to the first peer's DHT */ | ||
956 | test_get->dht_handle = GNUNET_DHT_connect(sched, test_get->daemon->cfg, 10); | 1638 | test_get->dht_handle = GNUNET_DHT_connect(sched, test_get->daemon->cfg, 10); |
957 | /* Insert the data at the first peer */ | ||
958 | GNUNET_assert(test_get->dht_handle != NULL); | 1639 | GNUNET_assert(test_get->dht_handle != NULL); |
959 | outstanding_gets++; | 1640 | outstanding_gets++; |
1641 | |||
1642 | /* Insert the data at the first peer */ | ||
960 | test_get->get_handle = GNUNET_DHT_get_start(test_get->dht_handle, | 1643 | test_get->get_handle = GNUNET_DHT_get_start(test_get->dht_handle, |
961 | GNUNET_TIME_relative_get_forever(), | 1644 | get_delay, |
962 | 1, | 1645 | 1, |
963 | &key, | 1646 | &known_keys[test_get->uid], |
964 | &get_result_iterator, | 1647 | &get_result_iterator, |
965 | test_get, | 1648 | test_get, |
966 | &get_continuation, | 1649 | &get_continuation, |
@@ -971,6 +1654,8 @@ do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
971 | test_get->daemon->shortname); | 1654 | test_get->daemon->shortname); |
972 | #endif | 1655 | #endif |
973 | test_get->disconnect_task = GNUNET_SCHEDULER_add_delayed(sched, get_timeout, &get_stop_task, test_get); | 1656 | test_get->disconnect_task = GNUNET_SCHEDULER_add_delayed(sched, get_timeout, &get_stop_task, test_get); |
1657 | |||
1658 | /* Schedule the next request in the linked list of get requests */ | ||
974 | GNUNET_SCHEDULER_add_now (sched, &do_get, test_get->next); | 1659 | GNUNET_SCHEDULER_add_now (sched, &do_get, test_get->next); |
975 | } | 1660 | } |
976 | 1661 | ||
@@ -989,6 +1674,10 @@ put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
989 | if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) | 1674 | if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) |
990 | fprintf(stderr, "PUT Request failed!\n"); | 1675 | fprintf(stderr, "PUT Request failed!\n"); |
991 | 1676 | ||
1677 | /* Reset the daemon (which peer to insert at) for later put request iterations */ | ||
1678 | if (replicate_same == GNUNET_NO) | ||
1679 | test_put->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers)); | ||
1680 | |||
992 | GNUNET_SCHEDULER_cancel(sched, test_put->disconnect_task); | 1681 | GNUNET_SCHEDULER_cancel(sched, test_put->disconnect_task); |
993 | test_put->disconnect_task = GNUNET_SCHEDULER_add_now(sched, &put_disconnect_task, test_put); | 1682 | test_put->disconnect_task = GNUNET_SCHEDULER_add_now(sched, &put_disconnect_task, test_put); |
994 | if (GNUNET_YES == update_meter(put_meter)) | 1683 | if (GNUNET_YES == update_meter(put_meter)) |
@@ -1002,15 +1691,15 @@ put_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
1002 | topo_ctx->cls = all_gets; | 1691 | topo_ctx->cls = all_gets; |
1003 | topo_ctx->timeout = DEFAULT_GET_TIMEOUT; | 1692 | topo_ctx->timeout = DEFAULT_GET_TIMEOUT; |
1004 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), | 1693 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), DEFAULT_TOPOLOGY_CAPTURE_TIMEOUT), |
1005 | &end_badly, "from do gets"); | 1694 | &end_badly, "from do gets (put finished)"); |
1006 | GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx); | 1695 | GNUNET_SCHEDULER_add_now(sched, &capture_current_topology, topo_ctx); |
1007 | } | 1696 | } |
1008 | else | 1697 | else |
1009 | { | 1698 | { |
1699 | fprintf(stderr, "Scheduling die task (put finished)\n"); | ||
1010 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), | 1700 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_add(DEFAULT_GET_TIMEOUT, all_get_timeout), |
1011 | &end_badly, "from do gets"); | 1701 | &end_badly, "from do gets (put finished)"); |
1012 | GNUNET_SCHEDULER_add_delayed(sched, DEFAULT_GET_TIMEOUT, &do_get, all_gets); | 1702 | GNUNET_SCHEDULER_add_delayed(sched, DEFAULT_GET_TIMEOUT, &do_get, all_gets); |
1013 | GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL); | ||
1014 | } | 1703 | } |
1015 | return; | 1704 | return; |
1016 | } | 1705 | } |
@@ -1023,98 +1712,45 @@ static void | |||
1023 | do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | 1712 | do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) |
1024 | { | 1713 | { |
1025 | struct TestPutContext *test_put = cls; | 1714 | struct TestPutContext *test_put = cls; |
1026 | GNUNET_HashCode key; /* Made up key to store data under */ | ||
1027 | char data[test_data_size]; /* Made up data to store */ | 1715 | char data[test_data_size]; /* Made up data to store */ |
1028 | uint32_t rand; | 1716 | uint32_t rand; |
1717 | int i; | ||
1029 | 1718 | ||
1030 | if (test_put == NULL) | 1719 | if (test_put == NULL) |
1031 | return; /* End of list */ | 1720 | return; /* End of list */ |
1032 | 1721 | ||
1033 | memset(data, test_put->uid, sizeof(data)); | 1722 | for (i = 0; i < sizeof(data); i++) |
1034 | GNUNET_CRYPTO_hash(data, test_data_size, &key); | 1723 | { |
1724 | memset(&data[i], GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t)-1), 1); | ||
1725 | } | ||
1035 | 1726 | ||
1036 | if (outstanding_puts > max_outstanding_puts) | 1727 | if (outstanding_puts > max_outstanding_puts) |
1037 | { | 1728 | { |
1038 | GNUNET_SCHEDULER_add_delayed (sched, put_delay, &do_put, test_put); | 1729 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 200), &do_put, test_put); |
1039 | return; | 1730 | return; |
1040 | } | 1731 | } |
1041 | 1732 | ||
1042 | #if VERBOSE > 1 | 1733 | #if VERBOSE > 1 |
1043 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting put for uid %u from peer %s\n", | 1734 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting put for uid %u from peer %s\n", |
1044 | test_put->uid, | 1735 | test_put->uid, |
1045 | test_put->daemon->shortname); | 1736 | test_put->daemon->shortname); |
1046 | #endif | 1737 | #endif |
1047 | test_put->dht_handle = GNUNET_DHT_connect(sched, test_put->daemon->cfg, 10); | 1738 | test_put->dht_handle = GNUNET_DHT_connect(sched, test_put->daemon->cfg, 10); |
1048 | 1739 | ||
1049 | GNUNET_assert(test_put->dht_handle != NULL); | 1740 | GNUNET_assert(test_put->dht_handle != NULL); |
1050 | outstanding_puts++; | 1741 | outstanding_puts++; |
1051 | GNUNET_DHT_put(test_put->dht_handle, | 1742 | GNUNET_DHT_put(test_put->dht_handle, |
1052 | &key, | 1743 | &known_keys[test_put->uid], |
1053 | 1, | 1744 | 1, |
1054 | sizeof(data), data, | 1745 | sizeof(data), data, |
1055 | GNUNET_TIME_absolute_get_forever(), | 1746 | GNUNET_TIME_absolute_get_forever(), |
1056 | GNUNET_TIME_relative_get_forever(), | 1747 | put_delay, |
1057 | &put_finished, test_put); | 1748 | &put_finished, test_put); |
1058 | test_put->disconnect_task = GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_get_forever(), &put_disconnect_task, test_put); | 1749 | test_put->disconnect_task = GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_get_forever(), &put_disconnect_task, test_put); |
1059 | rand = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 2); | 1750 | rand = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 2); |
1060 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, rand), &do_put, test_put->next); | 1751 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, rand), &do_put, test_put->next); |
1061 | } | 1752 | } |
1062 | 1753 | ||
1063 | /** | ||
1064 | * Context for sending out find peer requests. | ||
1065 | */ | ||
1066 | struct FindPeerContext | ||
1067 | { | ||
1068 | /** | ||
1069 | * How long to send find peer requests, once the settle time | ||
1070 | * is over don't send any more out! | ||
1071 | * | ||
1072 | * TODO: Add option for settle time and find peer sending time? | ||
1073 | */ | ||
1074 | struct GNUNET_TIME_Absolute endtime; | ||
1075 | |||
1076 | /** | ||
1077 | * Number of connections in the current topology | ||
1078 | * (after this round of find peer requests has ended). | ||
1079 | */ | ||
1080 | unsigned int current_peers; | ||
1081 | |||
1082 | /** | ||
1083 | * Number of connections in the current topology | ||
1084 | * (before this round of find peer requests started). | ||
1085 | */ | ||
1086 | unsigned int previous_peers; | ||
1087 | |||
1088 | /** | ||
1089 | * Number of find peer requests we have currently | ||
1090 | * outstanding. | ||
1091 | */ | ||
1092 | unsigned int outstanding; | ||
1093 | |||
1094 | /** | ||
1095 | * Number of find peer requests to send in this round. | ||
1096 | */ | ||
1097 | unsigned int total; | ||
1098 | |||
1099 | /** | ||
1100 | * Number of find peer requests sent last time around. | ||
1101 | */ | ||
1102 | unsigned int last_sent; | ||
1103 | |||
1104 | /** | ||
1105 | * Hashmap of peers in the current topology, value | ||
1106 | * is a PeerCount, with the number of connections | ||
1107 | * this peer has. | ||
1108 | */ | ||
1109 | struct GNUNET_CONTAINER_MultiHashMap *peer_hash; | ||
1110 | |||
1111 | /** | ||
1112 | * Min heap which orders values in the peer_hash for | ||
1113 | * easy lookup. | ||
1114 | */ | ||
1115 | struct GNUNET_CONTAINER_Heap *peer_min_heap; | ||
1116 | }; | ||
1117 | |||
1118 | static void | 1754 | static void |
1119 | schedule_find_peer_requests (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc); | 1755 | schedule_find_peer_requests (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc); |
1120 | 1756 | ||
@@ -1139,61 +1775,6 @@ static unsigned int connection_estimate(unsigned int peer_count, unsigned int bu | |||
1139 | 1775 | ||
1140 | } | 1776 | } |
1141 | 1777 | ||
1142 | struct PeerCount | ||
1143 | { | ||
1144 | /** Node in the heap */ | ||
1145 | struct GNUNET_CONTAINER_HeapNode *heap_node; | ||
1146 | |||
1147 | /** Peer the count refers to */ | ||
1148 | struct GNUNET_PeerIdentity peer_id; | ||
1149 | |||
1150 | /** Count of connections this peer has */ | ||
1151 | unsigned int count; | ||
1152 | }; | ||
1153 | |||
1154 | |||
1155 | /** | ||
1156 | * Add a connection to the find_peer_context given. This may | ||
1157 | * be complete overkill, but allows us to choose the peers with | ||
1158 | * the least connections to initiate find peer requests from. | ||
1159 | */ | ||
1160 | static void add_new_connection(struct FindPeerContext *find_peer_context, | ||
1161 | const struct GNUNET_PeerIdentity *first, | ||
1162 | const struct GNUNET_PeerIdentity *second) | ||
1163 | { | ||
1164 | struct PeerCount *first_count; | ||
1165 | struct PeerCount *second_count; | ||
1166 | |||
1167 | if (GNUNET_CONTAINER_multihashmap_contains(find_peer_context->peer_hash, &first->hashPubKey)) | ||
1168 | { | ||
1169 | first_count = GNUNET_CONTAINER_multihashmap_get(find_peer_context->peer_hash, &first->hashPubKey); | ||
1170 | first_count->count++; | ||
1171 | GNUNET_CONTAINER_heap_update_cost(find_peer_context->peer_min_heap, first_count->heap_node, first_count->count); | ||
1172 | } | ||
1173 | else | ||
1174 | { | ||
1175 | first_count = GNUNET_malloc(sizeof(struct PeerCount)); | ||
1176 | first_count->count = 1; | ||
1177 | memcpy(&first_count->peer_id, first, sizeof(struct GNUNET_PeerIdentity)); | ||
1178 | first_count->heap_node = GNUNET_CONTAINER_heap_insert(find_peer_context->peer_min_heap, first_count, first_count->count); | ||
1179 | GNUNET_CONTAINER_multihashmap_put(find_peer_context->peer_hash, &first->hashPubKey, first_count, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1180 | } | ||
1181 | |||
1182 | if (GNUNET_CONTAINER_multihashmap_contains(find_peer_context->peer_hash, &second->hashPubKey)) | ||
1183 | { | ||
1184 | second_count = GNUNET_CONTAINER_multihashmap_get(find_peer_context->peer_hash, &second->hashPubKey); | ||
1185 | second_count->count++; | ||
1186 | GNUNET_CONTAINER_heap_update_cost(find_peer_context->peer_min_heap, second_count->heap_node, second_count->count); | ||
1187 | } | ||
1188 | else | ||
1189 | { | ||
1190 | second_count = GNUNET_malloc(sizeof(struct PeerCount)); | ||
1191 | second_count->count = 1; | ||
1192 | memcpy(&second_count->peer_id, second, sizeof(struct GNUNET_PeerIdentity)); | ||
1193 | second_count->heap_node = GNUNET_CONTAINER_heap_insert(find_peer_context->peer_min_heap, second_count, second_count->count); | ||
1194 | GNUNET_CONTAINER_multihashmap_put(find_peer_context->peer_hash, &second->hashPubKey, second_count, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1195 | } | ||
1196 | } | ||
1197 | 1778 | ||
1198 | /** | 1779 | /** |
1199 | * Callback for iterating over all the peer connections of a peer group. | 1780 | * Callback for iterating over all the peer connections of a peer group. |
@@ -1213,112 +1794,29 @@ void count_peers_cb (void *cls, | |||
1213 | } | 1794 | } |
1214 | else | 1795 | else |
1215 | { | 1796 | { |
1216 | GNUNET_assert(dhtlog_handle != NULL); | 1797 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Peer count finished (%u connections), %u new peers, connection estimate %u (double %u)\n", |
1217 | /*GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Peer count finished (%u connections), %u new peers, connection estimate %u\n", find_peer_context->current_peers, find_peer_context->current_peers - find_peer_context->previous_peers, connection_estimate(num_peers, DEFAULT_BUCKET_SIZE));*/ | 1798 | find_peer_context->current_peers, |
1799 | find_peer_context->current_peers - find_peer_context->previous_peers, | ||
1800 | connection_estimate(num_peers, DEFAULT_BUCKET_SIZE), | ||
1801 | 2 * connection_estimate(num_peers, DEFAULT_BUCKET_SIZE)); | ||
1802 | |||
1218 | if ((find_peer_context->current_peers - find_peer_context->previous_peers > FIND_PEER_THRESHOLD) && | 1803 | if ((find_peer_context->current_peers - find_peer_context->previous_peers > FIND_PEER_THRESHOLD) && |
1219 | (find_peer_context->current_peers < connection_estimate(num_peers, DEFAULT_BUCKET_SIZE)) && | 1804 | (find_peer_context->current_peers < 2 * connection_estimate(num_peers, DEFAULT_BUCKET_SIZE)) && |
1220 | (GNUNET_TIME_absolute_get_remaining(find_peer_context->endtime).value > 0)) | 1805 | (GNUNET_TIME_absolute_get_remaining(find_peer_context->endtime).value > 0)) |
1221 | { | 1806 | { |
1222 | GNUNET_SCHEDULER_add_now(sched, &schedule_find_peer_requests, find_peer_context); | 1807 | GNUNET_SCHEDULER_add_now(sched, &schedule_find_peer_requests, find_peer_context); |
1223 | } | 1808 | } |
1224 | else | 1809 | else |
1225 | { | 1810 | { |
1811 | GNUNET_CONTAINER_multihashmap_iterate(find_peer_context->peer_hash, &remove_peer_count, find_peer_context); | ||
1812 | GNUNET_CONTAINER_multihashmap_destroy(find_peer_context->peer_hash); | ||
1813 | GNUNET_CONTAINER_heap_destroy(find_peer_context->peer_min_heap); | ||
1814 | GNUNET_free(find_peer_context); | ||
1226 | fprintf(stderr, "Not sending any more find peer requests.\n"); | 1815 | fprintf(stderr, "Not sending any more find peer requests.\n"); |
1227 | } | 1816 | } |
1228 | } | 1817 | } |
1229 | } | 1818 | } |
1230 | 1819 | ||
1231 | /** | ||
1232 | * Connect to all peers in the peer group and iterate over their | ||
1233 | * connections. | ||
1234 | */ | ||
1235 | static void | ||
1236 | count_new_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1237 | { | ||
1238 | struct FindPeerContext *find_peer_context = cls; | ||
1239 | find_peer_context->previous_peers = find_peer_context->current_peers; | ||
1240 | find_peer_context->current_peers = 0; | ||
1241 | GNUNET_TESTING_get_topology (pg, &count_peers_cb, find_peer_context); | ||
1242 | } | ||
1243 | |||
1244 | |||
1245 | static void | ||
1246 | decrement_find_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1247 | { | ||
1248 | struct TestFindPeer *test_find_peer = cls; | ||
1249 | GNUNET_assert(test_find_peer->find_peer_context->outstanding > 0); | ||
1250 | test_find_peer->find_peer_context->outstanding--; | ||
1251 | test_find_peer->find_peer_context->total--; | ||
1252 | if ((0 == test_find_peer->find_peer_context->total) && | ||
1253 | (GNUNET_TIME_absolute_get_remaining(test_find_peer->find_peer_context->endtime).value > 0)) | ||
1254 | { | ||
1255 | GNUNET_SCHEDULER_add_now(sched, &count_new_peers, test_find_peer->find_peer_context); | ||
1256 | } | ||
1257 | GNUNET_free(test_find_peer); | ||
1258 | } | ||
1259 | |||
1260 | /** | ||
1261 | * A find peer request has been sent to the server, now we will schedule a task | ||
1262 | * to wait the appropriate time to allow the request to go out and back. | ||
1263 | * | ||
1264 | * @param cls closure - a TestFindPeer struct | ||
1265 | * @param tc context the task is being called with | ||
1266 | */ | ||
1267 | static void | ||
1268 | handle_find_peer_sent (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1269 | { | ||
1270 | struct TestFindPeer *test_find_peer = cls; | ||
1271 | |||
1272 | GNUNET_DHT_disconnect(test_find_peer->dht_handle); | ||
1273 | GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_divide(find_peer_delay, 2), &decrement_find_peers, test_find_peer); | ||
1274 | } | ||
1275 | |||
1276 | static void | ||
1277 | send_find_peer_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1278 | { | ||
1279 | struct TestFindPeer *test_find_peer = cls; | ||
1280 | |||
1281 | if (test_find_peer->find_peer_context->outstanding > max_outstanding_find_peers) | ||
1282 | { | ||
1283 | GNUNET_SCHEDULER_add_delayed(sched, find_peer_offset, &send_find_peer_request, test_find_peer); | ||
1284 | return; | ||
1285 | } | ||
1286 | |||
1287 | test_find_peer->find_peer_context->outstanding++; | ||
1288 | if (GNUNET_TIME_absolute_get_remaining(test_find_peer->find_peer_context->endtime).value == 0) | ||
1289 | { | ||
1290 | GNUNET_SCHEDULER_add_now(sched, &decrement_find_peers, test_find_peer); | ||
1291 | return; | ||
1292 | } | ||
1293 | |||
1294 | test_find_peer->dht_handle = GNUNET_DHT_connect(sched, test_find_peer->daemon->cfg, 1); | ||
1295 | GNUNET_assert(test_find_peer->dht_handle != NULL); | ||
1296 | GNUNET_DHT_find_peers (test_find_peer->dht_handle, | ||
1297 | &handle_find_peer_sent, test_find_peer); | ||
1298 | } | ||
1299 | |||
1300 | /** | ||
1301 | * Iterator over hash map entries. | ||
1302 | * | ||
1303 | * @param cls closure | ||
1304 | * @param key current key code | ||
1305 | * @param value value in the hash map | ||
1306 | * @return GNUNET_YES if we should continue to | ||
1307 | * iterate, | ||
1308 | * GNUNET_NO if not. | ||
1309 | */ | ||
1310 | static int remove_peer_count (void *cls, | ||
1311 | const GNUNET_HashCode * key, | ||
1312 | void *value) | ||
1313 | { | ||
1314 | struct FindPeerContext *find_peer_ctx = cls; | ||
1315 | struct PeerCount *peer_count = value; | ||
1316 | GNUNET_CONTAINER_heap_remove_node(find_peer_ctx->peer_min_heap, peer_count->heap_node); | ||
1317 | GNUNET_free(peer_count); | ||
1318 | |||
1319 | return GNUNET_YES; | ||
1320 | } | ||
1321 | |||
1322 | 1820 | ||
1323 | /** | 1821 | /** |
1324 | * Set up a single find peer request for each peer in the topology. Do this | 1822 | * Set up a single find peer request for each peer in the topology. Do this |
@@ -1352,7 +1850,7 @@ schedule_find_peer_requests (void *cls, const struct GNUNET_SCHEDULER_TaskContex | |||
1352 | find_peer_ctx->total = max_outstanding_find_peers; | 1850 | find_peer_ctx->total = max_outstanding_find_peers; |
1353 | 1851 | ||
1354 | find_peer_ctx->last_sent = find_peer_ctx->total; | 1852 | find_peer_ctx->last_sent = find_peer_ctx->total; |
1355 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending %u find peer messages (goal %u connections)\n", find_peer_ctx->total, connection_estimate(num_peers, DEFAULT_BUCKET_SIZE)); | 1853 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending %u find peer messages (goal at least %u connections)\n", find_peer_ctx->total, connection_estimate(num_peers, DEFAULT_BUCKET_SIZE)); |
1356 | 1854 | ||
1357 | find_peer_offset = GNUNET_TIME_relative_divide(find_peer_delay, find_peer_ctx->total); | 1855 | find_peer_offset = GNUNET_TIME_relative_divide(find_peer_delay, find_peer_ctx->total); |
1358 | for (i = 0; i < find_peer_ctx->total; i++) | 1856 | for (i = 0; i < find_peer_ctx->total; i++) |
@@ -1420,13 +1918,16 @@ setup_puts_and_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
1420 | uint32_t temp_daemon; | 1918 | uint32_t temp_daemon; |
1421 | struct TestPutContext *test_put; | 1919 | struct TestPutContext *test_put; |
1422 | struct TestGetContext *test_get; | 1920 | struct TestGetContext *test_get; |
1921 | #if REMEMBER | ||
1423 | int remember[num_puts][num_peers]; | 1922 | int remember[num_puts][num_peers]; |
1424 | |||
1425 | memset(&remember, 0, sizeof(int) * num_puts * num_peers); | 1923 | memset(&remember, 0, sizeof(int) * num_puts * num_peers); |
1924 | #endif | ||
1925 | known_keys = GNUNET_malloc(sizeof(GNUNET_HashCode) * num_puts); | ||
1426 | for (i = 0; i < num_puts; i++) | 1926 | for (i = 0; i < num_puts; i++) |
1427 | { | 1927 | { |
1428 | test_put = GNUNET_malloc(sizeof(struct TestPutContext)); | 1928 | test_put = GNUNET_malloc(sizeof(struct TestPutContext)); |
1429 | test_put->uid = i; | 1929 | test_put->uid = i; |
1930 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &known_keys[i]); | ||
1430 | temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers); | 1931 | temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers); |
1431 | test_put->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon); | 1932 | test_put->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon); |
1432 | test_put->next = all_puts; | 1933 | test_put->next = all_puts; |
@@ -1437,11 +1938,12 @@ setup_puts_and_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
1437 | { | 1938 | { |
1438 | test_get = GNUNET_malloc(sizeof(struct TestGetContext)); | 1939 | test_get = GNUNET_malloc(sizeof(struct TestGetContext)); |
1439 | test_get->uid = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_puts); | 1940 | test_get->uid = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_puts); |
1440 | temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers); | 1941 | #if REMEMBER |
1441 | while (remember[test_get->uid][temp_daemon] == 1) | 1942 | while (remember[test_get->uid][temp_daemon] == 1) |
1442 | temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers); | 1943 | temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers); |
1443 | test_get->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon); | ||
1444 | remember[test_get->uid][temp_daemon] = 1; | 1944 | remember[test_get->uid][temp_daemon] = 1; |
1945 | #endif | ||
1946 | test_get->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers)); | ||
1445 | test_get->next = all_gets; | 1947 | test_get->next = all_gets; |
1446 | all_gets = test_get; | 1948 | all_gets = test_get; |
1447 | } | 1949 | } |
@@ -1488,6 +1990,7 @@ continue_puts_and_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext * t | |||
1488 | if (GNUNET_YES == do_find_peer) | 1990 | if (GNUNET_YES == do_find_peer) |
1489 | { | 1991 | { |
1490 | find_peer_context = GNUNET_malloc(sizeof(struct FindPeerContext)); | 1992 | find_peer_context = GNUNET_malloc(sizeof(struct FindPeerContext)); |
1993 | find_peer_context->count_peers_cb = &count_peers_cb; | ||
1491 | find_peer_context->endtime = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, settle_time)); | 1994 | find_peer_context->endtime = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, settle_time)); |
1492 | GNUNET_SCHEDULER_add_now(sched, &schedule_find_peer_requests, find_peer_context); | 1995 | GNUNET_SCHEDULER_add_now(sched, &schedule_find_peer_requests, find_peer_context); |
1493 | } | 1996 | } |
@@ -1627,20 +2130,22 @@ setup_malicious_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc | |||
1627 | GNUNET_SCHEDULER_add_now (sched, &set_malicious, ctx); | 2130 | GNUNET_SCHEDULER_add_now (sched, &set_malicious, ctx); |
1628 | } | 2131 | } |
1629 | 2132 | ||
2133 | /** | ||
2134 | * If we have any malicious peers to set up, | ||
2135 | * the malicious callback should call continue_gets_and_puts | ||
2136 | */ | ||
1630 | if (malicious_getters + malicious_putters + malicious_droppers > 0) | 2137 | if (malicious_getters + malicious_putters + malicious_droppers > 0) |
1631 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, (malicious_getters + malicious_putters + malicious_droppers) * 2), | ||
1632 | &end_badly, "from set malicious"); | ||
1633 | else | ||
1634 | { | 2138 | { |
1635 | if (dhtlog_handle != NULL) | 2139 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Giving malicious set tasks some time before starting testing!\n"); |
1636 | GNUNET_SCHEDULER_add_now (sched, | 2140 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, (malicious_getters + malicious_putters + malicious_droppers) * 2), |
1637 | &continue_puts_and_gets, NULL); | 2141 | &end_badly, "from set malicious"); |
1638 | else | 2142 | } |
1639 | GNUNET_SCHEDULER_add_delayed (sched, | 2143 | else /* Otherwise, continue testing */ |
1640 | GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, settle_time), | 2144 | { |
1641 | &continue_puts_and_gets, NULL); | 2145 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Scheduling continue_puts_and_gets now!\n"); |
2146 | GNUNET_SCHEDULER_add_now (sched, | ||
2147 | &continue_puts_and_gets, NULL); | ||
1642 | } | 2148 | } |
1643 | |||
1644 | } | 2149 | } |
1645 | 2150 | ||
1646 | /** | 2151 | /** |
@@ -1674,15 +2179,16 @@ topology_callback (void *cls, | |||
1674 | distance); | 2179 | distance); |
1675 | #endif | 2180 | #endif |
1676 | } | 2181 | } |
1677 | #if VERBOSE | ||
1678 | else | 2182 | else |
1679 | { | 2183 | { |
1680 | failed_connections++; | 2184 | failed_connections++; |
2185 | #if VERBOSE | ||
1681 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer %s with error :\n%s\n", | 2186 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer %s with error :\n%s\n", |
1682 | first_daemon->shortname, | 2187 | first_daemon->shortname, |
1683 | second_daemon->shortname, emsg); | 2188 | second_daemon->shortname, emsg); |
1684 | } | ||
1685 | #endif | 2189 | #endif |
2190 | } | ||
2191 | |||
1686 | GNUNET_assert(peer_connect_meter != NULL); | 2192 | GNUNET_assert(peer_connect_meter != NULL); |
1687 | if (GNUNET_YES == update_meter(peer_connect_meter)) | 2193 | if (GNUNET_YES == update_meter(peer_connect_meter)) |
1688 | { | 2194 | { |
@@ -1855,6 +2361,7 @@ run (void *cls, | |||
1855 | struct GNUNET_DHTLOG_TrialInfo trial_info; | 2361 | struct GNUNET_DHTLOG_TrialInfo trial_info; |
1856 | struct GNUNET_TESTING_Host *hosts; | 2362 | struct GNUNET_TESTING_Host *hosts; |
1857 | struct GNUNET_TESTING_Host *temphost; | 2363 | struct GNUNET_TESTING_Host *temphost; |
2364 | struct GNUNET_TESTING_Host *tempnext; | ||
1858 | char *topology_str; | 2365 | char *topology_str; |
1859 | char *connect_topology_str; | 2366 | char *connect_topology_str; |
1860 | char *blacklist_topology_str; | 2367 | char *blacklist_topology_str; |
@@ -1872,10 +2379,15 @@ run (void *cls, | |||
1872 | int strict_kademlia; | 2379 | int strict_kademlia; |
1873 | char *buf; | 2380 | char *buf; |
1874 | char *data; | 2381 | char *data; |
2382 | char *churn_data; | ||
2383 | char *churn_filename; | ||
1875 | int count; | 2384 | int count; |
2385 | int ret; | ||
2386 | unsigned int line_number; | ||
1876 | 2387 | ||
1877 | sched = s; | 2388 | sched = s; |
1878 | config = cfg; | 2389 | config = cfg; |
2390 | rounds_finished = 0; | ||
1879 | memset(&trial_info, 0, sizeof(struct GNUNET_DHTLOG_TrialInfo)); | 2391 | memset(&trial_info, 0, sizeof(struct GNUNET_DHTLOG_TrialInfo)); |
1880 | /* Get path from configuration file */ | 2392 | /* Get path from configuration file */ |
1881 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", "servicehome", &test_directory)) | 2393 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", "servicehome", &test_directory)) |
@@ -1917,6 +2429,100 @@ run (void *cls, | |||
1917 | &trialmessage)) | 2429 | &trialmessage)) |
1918 | trialmessage = NULL; | 2430 | trialmessage = NULL; |
1919 | 2431 | ||
2432 | churn_data = NULL; | ||
2433 | /** Check for a churn file to do churny simulation */ | ||
2434 | if (GNUNET_OK == | ||
2435 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "churn_file", | ||
2436 | &churn_filename)) | ||
2437 | { | ||
2438 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Reading churn data from %s\n", churn_filename); | ||
2439 | if (GNUNET_OK != GNUNET_DISK_file_test (churn_filename)) | ||
2440 | { | ||
2441 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Error reading churn file!\n"); | ||
2442 | return; | ||
2443 | } | ||
2444 | if ((0 != STAT (churn_filename, &frstat)) || (frstat.st_size == 0)) | ||
2445 | { | ||
2446 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2447 | "Could not open file specified for churn data, ending test!"); | ||
2448 | ok = 1119; | ||
2449 | GNUNET_free_non_null(trialmessage); | ||
2450 | GNUNET_free(churn_filename); | ||
2451 | return; | ||
2452 | } | ||
2453 | |||
2454 | churn_data = GNUNET_malloc_large (frstat.st_size); | ||
2455 | GNUNET_assert(churn_data != NULL); | ||
2456 | if (frstat.st_size != | ||
2457 | GNUNET_DISK_fn_read (churn_filename, churn_data, frstat.st_size)) | ||
2458 | { | ||
2459 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2460 | "Could not read file %s specified for churn, ending test!", churn_filename); | ||
2461 | GNUNET_free (churn_filename); | ||
2462 | GNUNET_free (churn_data); | ||
2463 | GNUNET_free_non_null(trialmessage); | ||
2464 | return; | ||
2465 | } | ||
2466 | |||
2467 | GNUNET_free_non_null(churn_filename); | ||
2468 | |||
2469 | buf = churn_data; | ||
2470 | count = 0; | ||
2471 | /* Read the first line */ | ||
2472 | while (count < frstat.st_size) | ||
2473 | { | ||
2474 | count++; | ||
2475 | if (((churn_data[count] == '\n')) && (buf != &churn_data[count])) | ||
2476 | { | ||
2477 | churn_data[count] = '\0'; | ||
2478 | if (1 != sscanf(buf, "%u", &churn_rounds)) | ||
2479 | { | ||
2480 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to read number of rounds from %s, ending test!\n", churn_filename); | ||
2481 | GNUNET_free_non_null(trialmessage); | ||
2482 | GNUNET_free(churn_filename); | ||
2483 | ret = 4200; | ||
2484 | return; | ||
2485 | } | ||
2486 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Read %u rounds from churn file\n", churn_rounds); | ||
2487 | buf = &churn_data[count + 1]; | ||
2488 | churn_array = GNUNET_malloc(sizeof(unsigned int) * churn_rounds); | ||
2489 | } | ||
2490 | } | ||
2491 | |||
2492 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, "dht_testing", "churns_per_round", &churns_per_round)) | ||
2493 | { | ||
2494 | churns_per_round = (unsigned long long)churn_rounds; | ||
2495 | } | ||
2496 | |||
2497 | line_number = 0; | ||
2498 | while ((count < frstat.st_size) && (line_number < churn_rounds)) | ||
2499 | { | ||
2500 | count++; | ||
2501 | if (((churn_data[count] == '\n')) && (buf != &churn_data[count])) | ||
2502 | { | ||
2503 | churn_data[count] = '\0'; | ||
2504 | |||
2505 | ret = sscanf(buf, "%u", &churn_array[line_number]); | ||
2506 | if (1 == ret) | ||
2507 | { | ||
2508 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Read %u peers in round %u\n", churn_array[line_number], line_number); | ||
2509 | line_number++; | ||
2510 | } | ||
2511 | else | ||
2512 | { | ||
2513 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Error reading line `%s' in hostfile\n", buf); | ||
2514 | buf = &churn_data[count + 1]; | ||
2515 | continue; | ||
2516 | } | ||
2517 | buf = &churn_data[count + 1]; | ||
2518 | } | ||
2519 | else if (churn_data[count] == '\n') /* Blank line */ | ||
2520 | buf = &churn_data[count + 1]; | ||
2521 | } | ||
2522 | } | ||
2523 | GNUNET_free_non_null(churn_data); | ||
2524 | |||
2525 | /** Check for a hostfile containing user@host:port triples */ | ||
1920 | if (GNUNET_OK != | 2526 | if (GNUNET_OK != |
1921 | GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "hostfile", | 2527 | GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "hostfile", |
1922 | &hostfile)) | 2528 | &hostfile)) |
@@ -1959,11 +2565,24 @@ run (void *cls, | |||
1959 | while (count < frstat.st_size) | 2565 | while (count < frstat.st_size) |
1960 | { | 2566 | { |
1961 | count++; | 2567 | count++; |
1962 | if (((data[count] == '\n') || (data[count] == '\0')) && (buf != &data[count])) | 2568 | /* if (((data[count] == '\n') || (data[count] == '\0')) && (buf != &data[count]))*/ |
2569 | if (((data[count] == '\n')) && (buf != &data[count])) | ||
1963 | { | 2570 | { |
1964 | data[count] = '\0'; | 2571 | data[count] = '\0'; |
1965 | temphost = GNUNET_malloc(sizeof(struct GNUNET_TESTING_Host)); | 2572 | temphost = GNUNET_malloc(sizeof(struct GNUNET_TESTING_Host)); |
1966 | temphost->hostname = buf; | 2573 | ret = sscanf(buf, "%a[a-zA-Z0-9]@%a[a-zA-Z0-9.]:%hd", &temphost->username, &temphost->hostname, &temphost->port); |
2574 | if (3 == ret) | ||
2575 | { | ||
2576 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Successfully read host %s, port %d and user %s from file\n", temphost->hostname, temphost->port, temphost->username); | ||
2577 | } | ||
2578 | else | ||
2579 | { | ||
2580 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Error reading line `%s' in hostfile\n", buf); | ||
2581 | GNUNET_free(temphost); | ||
2582 | buf = &data[count + 1]; | ||
2583 | continue; | ||
2584 | } | ||
2585 | /* temphost->hostname = buf; */ | ||
1967 | temphost->next = hosts; | 2586 | temphost->next = hosts; |
1968 | hosts = temphost; | 2587 | hosts = temphost; |
1969 | buf = &data[count + 1]; | 2588 | buf = &data[count + 1]; |
@@ -2043,7 +2662,7 @@ run (void *cls, | |||
2043 | &temp_config_number)) | 2662 | &temp_config_number)) |
2044 | all_get_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, temp_config_number); | 2663 | all_get_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, temp_config_number); |
2045 | else | 2664 | else |
2046 | all_get_timeout.value = get_timeout.value * ((num_gets / max_outstanding_gets) + 1); | 2665 | all_get_timeout.value = get_timeout.value * num_gets; |
2047 | 2666 | ||
2048 | if (GNUNET_OK == | 2667 | if (GNUNET_OK == |
2049 | GNUNET_CONFIGURATION_get_value_number (cfg, "dht_testing", "get_delay", | 2668 | GNUNET_CONFIGURATION_get_value_number (cfg, "dht_testing", "get_delay", |
@@ -2076,6 +2695,10 @@ run (void *cls, | |||
2076 | /** | 2695 | /** |
2077 | * Get testing related options. | 2696 | * Get testing related options. |
2078 | */ | 2697 | */ |
2698 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, "DHT_TESTING", "REPLICATE_SAME")) | ||
2699 | { | ||
2700 | replicate_same = GNUNET_YES; | ||
2701 | } | ||
2079 | 2702 | ||
2080 | if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT_TESTING", | 2703 | if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT_TESTING", |
2081 | "MALICIOUS_GET_FREQUENCY", | 2704 | "MALICIOUS_GET_FREQUENCY", |
@@ -2088,14 +2711,25 @@ run (void *cls, | |||
2088 | &malicious_put_frequency)) | 2711 | &malicious_put_frequency)) |
2089 | malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY; | 2712 | malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY; |
2090 | 2713 | ||
2714 | |||
2715 | /* The normal behavior of the DHT is to do find peer requests | ||
2716 | * on its own. Only if this is explicitly turned off should | ||
2717 | * the testing driver issue find peer requests (even though | ||
2718 | * this is likely the default when testing). | ||
2719 | */ | ||
2091 | if (GNUNET_NO == | 2720 | if (GNUNET_NO == |
2092 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht", | 2721 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht", |
2093 | "find_peers")) | 2722 | "do_find_peer")) |
2094 | { | 2723 | { |
2095 | do_find_peer = GNUNET_NO; | 2724 | do_find_peer = GNUNET_YES; |
2725 | } | ||
2726 | |||
2727 | if (GNUNET_YES == | ||
2728 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht", | ||
2729 | "republish")) | ||
2730 | { | ||
2731 | in_dht_replication = GNUNET_YES; | ||
2096 | } | 2732 | } |
2097 | else | ||
2098 | do_find_peer = GNUNET_YES; | ||
2099 | 2733 | ||
2100 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_number (cfg, "DHT_TESTING", | 2734 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_number (cfg, "DHT_TESTING", |
2101 | "TRIAL_TO_RUN", | 2735 | "TRIAL_TO_RUN", |
@@ -2113,6 +2747,9 @@ run (void *cls, | |||
2113 | else | 2747 | else |
2114 | find_peer_delay = DEFAULT_FIND_PEER_DELAY; | 2748 | find_peer_delay = DEFAULT_FIND_PEER_DELAY; |
2115 | 2749 | ||
2750 | if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_number(cfg, "DHT_TESTING", "ROUND_DELAY", &round_delay)) | ||
2751 | round_delay = 0; | ||
2752 | |||
2116 | if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT_TESTING", | 2753 | if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT_TESTING", |
2117 | "OUTSTANDING_FIND_PEERS", | 2754 | "OUTSTANDING_FIND_PEERS", |
2118 | &max_outstanding_find_peers)) | 2755 | &max_outstanding_find_peers)) |
@@ -2123,6 +2760,13 @@ run (void *cls, | |||
2123 | 2760 | ||
2124 | find_peer_offset = GNUNET_TIME_relative_divide (find_peer_delay, max_outstanding_find_peers); | 2761 | find_peer_offset = GNUNET_TIME_relative_divide (find_peer_delay, max_outstanding_find_peers); |
2125 | 2762 | ||
2763 | if (GNUNET_SYSERR == | ||
2764 | GNUNET_CONFIGURATION_get_value_number (cfg, "dht_testing", "num_rounds", | ||
2765 | &total_rounds)) | ||
2766 | { | ||
2767 | total_rounds = 1; | ||
2768 | } | ||
2769 | |||
2126 | topology_str = NULL; | 2770 | topology_str = NULL; |
2127 | if ((GNUNET_YES == | 2771 | if ((GNUNET_YES == |
2128 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "topology", | 2772 | GNUNET_CONFIGURATION_get_value_string(cfg, "testing", "topology", |
@@ -2214,6 +2858,7 @@ run (void *cls, | |||
2214 | /* Set peers_left so we know when all peers started */ | 2858 | /* Set peers_left so we know when all peers started */ |
2215 | peers_left = num_peers; | 2859 | peers_left = num_peers; |
2216 | 2860 | ||
2861 | |||
2217 | /* Set up a task to end testing if peer start fails */ | 2862 | /* Set up a task to end testing if peer start fails */ |
2218 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 2863 | die_task = GNUNET_SCHEDULER_add_delayed (sched, |
2219 | GNUNET_TIME_relative_multiply(seconds_per_peer_start, num_peers), | 2864 | GNUNET_TIME_relative_multiply(seconds_per_peer_start, num_peers), |
@@ -2268,8 +2913,15 @@ run (void *cls, | |||
2268 | &peers_started_callback, NULL, | 2913 | &peers_started_callback, NULL, |
2269 | &topology_callback, NULL, | 2914 | &topology_callback, NULL, |
2270 | hosts); | 2915 | hosts); |
2271 | 2916 | temphost = hosts; | |
2272 | GNUNET_free_non_null(temphost); | 2917 | while (temphost != NULL) |
2918 | { | ||
2919 | tempnext = temphost->next; | ||
2920 | GNUNET_free (temphost->username); | ||
2921 | GNUNET_free (temphost->hostname); | ||
2922 | GNUNET_free (temphost); | ||
2923 | temphost = tempnext; | ||
2924 | } | ||
2273 | } | 2925 | } |
2274 | 2926 | ||
2275 | 2927 | ||