diff options
-rw-r--r-- | auto_tests/tox_test.c | 30 | ||||
-rw-r--r-- | toxcore/DHT.c | 191 | ||||
-rw-r--r-- | toxcore/DHT.h | 10 |
3 files changed, 111 insertions, 120 deletions
diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c index 501c93dc..72bc27ee 100644 --- a/auto_tests/tox_test.c +++ b/auto_tests/tox_test.c | |||
@@ -286,6 +286,16 @@ void tox_connection_status(Tox *tox, TOX_CONNECTION connection_status, void *use | |||
286 | 286 | ||
287 | START_TEST(test_one) | 287 | START_TEST(test_one) |
288 | { | 288 | { |
289 | { | ||
290 | TOX_ERR_OPTIONS_NEW o_err; | ||
291 | struct Tox_Options *o1 = tox_options_new(&o_err); | ||
292 | struct Tox_Options o2; | ||
293 | tox_options_default(&o2); | ||
294 | ck_assert_msg(o_err == TOX_ERR_OPTIONS_NEW_OK, "tox_options_new wrong error"); | ||
295 | ck_assert_msg(memcmp(o1, &o2, sizeof(struct Tox_Options)) == 0, "tox_options_new error"); | ||
296 | tox_options_free(o1); | ||
297 | } | ||
298 | |||
289 | Tox *tox1 = tox_new(0, 0); | 299 | Tox *tox1 = tox_new(0, 0); |
290 | Tox *tox2 = tox_new(0, 0); | 300 | Tox *tox2 = tox_new(0, 0); |
291 | 301 | ||
@@ -468,6 +478,12 @@ START_TEST(test_few_clients) | |||
468 | 478 | ||
469 | printf("tox clients messaging succeeded\n"); | 479 | printf("tox clients messaging succeeded\n"); |
470 | 480 | ||
481 | unsigned int save_size1 = tox_get_savedata_size(tox2); | ||
482 | ck_assert_msg(save_size1 != 0 && save_size1 < 4096, "save is invalid size %u", save_size1); | ||
483 | printf("%u\n", save_size1); | ||
484 | uint8_t save1[save_size1]; | ||
485 | tox_get_savedata(tox2, save1); | ||
486 | |||
471 | tox_callback_friend_name(tox3, print_nickchange, &to_compare); | 487 | tox_callback_friend_name(tox3, print_nickchange, &to_compare); |
472 | TOX_ERR_SET_INFO err_n; | 488 | TOX_ERR_SET_INFO err_n; |
473 | bool succ = tox_self_set_name(tox2, (uint8_t *)"Gentoo", sizeof("Gentoo"), &err_n); | 489 | bool succ = tox_self_set_name(tox2, (uint8_t *)"Gentoo", sizeof("Gentoo"), &err_n); |
@@ -785,6 +801,14 @@ START_TEST(test_many_clients) | |||
785 | 801 | ||
786 | uint8_t address[TOX_ADDRESS_SIZE]; | 802 | uint8_t address[TOX_ADDRESS_SIZE]; |
787 | 803 | ||
804 | unsigned int num_f = 0; | ||
805 | |||
806 | for (i = 0; i < NUM_TOXES; ++i) { | ||
807 | num_f += tox_self_get_friend_list_size(toxes[i]); | ||
808 | } | ||
809 | |||
810 | ck_assert_msg(num_f == 0, "bad num friends: %u", num_f); | ||
811 | |||
788 | for (i = 0; i < NUM_FRIENDS; ++i) { | 812 | for (i = 0; i < NUM_FRIENDS; ++i) { |
789 | loop_top: | 813 | loop_top: |
790 | pairs[i].tox1 = rand() % NUM_TOXES; | 814 | pairs[i].tox1 = rand() % NUM_TOXES; |
@@ -807,6 +831,12 @@ loop_top: | |||
807 | ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); | 831 | ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); |
808 | } | 832 | } |
809 | 833 | ||
834 | for (i = 0; i < NUM_TOXES; ++i) { | ||
835 | num_f += tox_self_get_friend_list_size(toxes[i]); | ||
836 | } | ||
837 | |||
838 | ck_assert_msg(num_f == NUM_FRIENDS, "bad num friends: %u", num_f); | ||
839 | |||
810 | while (1) { | 840 | while (1) { |
811 | uint16_t counter = 0; | 841 | uint16_t counter = 0; |
812 | 842 | ||
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 8cd8852c..ca87ad90 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -2244,18 +2244,17 @@ DHT *new_DHT(Networking_Core *net) | |||
2244 | 2244 | ||
2245 | void do_DHT(DHT *dht) | 2245 | void do_DHT(DHT *dht) |
2246 | { | 2246 | { |
2247 | // Load friends/clients if first call to do_DHT | ||
2248 | if (dht->has_loaded_friends_clients == 0) { | ||
2249 | dht->has_loaded_friends_clients = 1; | ||
2250 | DHT_connect_after_load(dht); | ||
2251 | } | ||
2252 | |||
2253 | unix_time_update(); | 2247 | unix_time_update(); |
2254 | 2248 | ||
2255 | if (dht->last_run == unix_time()) { | 2249 | if (dht->last_run == unix_time()) { |
2256 | return; | 2250 | return; |
2257 | } | 2251 | } |
2258 | 2252 | ||
2253 | // Load friends/clients if first call to do_DHT | ||
2254 | if (dht->loaded_num_nodes) { | ||
2255 | DHT_connect_after_load(dht); | ||
2256 | } | ||
2257 | |||
2259 | do_Close(dht); | 2258 | do_Close(dht); |
2260 | do_DHT_friends(dht); | 2259 | do_DHT_friends(dht); |
2261 | do_NAT(dht); | 2260 | do_NAT(dht); |
@@ -2282,33 +2281,37 @@ void kill_DHT(DHT *dht) | |||
2282 | ping_array_free_all(&dht->dht_harden_ping_array); | 2281 | ping_array_free_all(&dht->dht_harden_ping_array); |
2283 | kill_ping(dht->ping); | 2282 | kill_ping(dht->ping); |
2284 | free(dht->friends_list); | 2283 | free(dht->friends_list); |
2285 | free(dht->loaded_friends_list); | 2284 | free(dht->loaded_nodes_list); |
2286 | free(dht->loaded_clients_list); | ||
2287 | free(dht); | 2285 | free(dht); |
2288 | } | 2286 | } |
2289 | 2287 | ||
2290 | /* new DHT format for load/save, more robust and forward compatible */ | 2288 | /* new DHT format for load/save, more robust and forward compatible */ |
2291 | 2289 | //TODO: Move this closer to Messenger. | |
2292 | #define DHT_STATE_COOKIE_GLOBAL 0x159000d | 2290 | #define DHT_STATE_COOKIE_GLOBAL 0x159000d |
2293 | 2291 | ||
2294 | #define DHT_STATE_COOKIE_TYPE 0x11ce | 2292 | #define DHT_STATE_COOKIE_TYPE 0x11ce |
2295 | #define DHT_STATE_TYPE_FRIENDS_ASSOC46 3 | 2293 | #define DHT_STATE_TYPE_NODES 4 |
2296 | #define DHT_STATE_TYPE_CLIENTS_ASSOC46 4 | ||
2297 | 2294 | ||
2298 | /* Get the size of the DHT (for saving). */ | 2295 | /* Get the size of the DHT (for saving). */ |
2299 | uint32_t DHT_size(const DHT *dht) | 2296 | uint32_t DHT_size(const DHT *dht) |
2300 | { | 2297 | { |
2301 | uint32_t num = 0, i; | 2298 | uint32_t num = 0, i, j; |
2299 | |||
2300 | for (i = 0; i < LCLIENT_LIST; ++i) { | ||
2301 | num += (dht->close_clientlist[i].assoc4.timestamp != 0) + (dht->close_clientlist[i].assoc6.timestamp != 0); | ||
2302 | } | ||
2302 | 2303 | ||
2303 | for (i = 0; i < LCLIENT_LIST; ++i) | 2304 | for (i = 0; i < DHT_FAKE_FRIEND_NUMBER && i < dht->num_friends; ++i) { |
2304 | if ((dht->close_clientlist[i].assoc4.timestamp != 0) || | 2305 | DHT_Friend *fr = &dht->friends_list[i]; |
2305 | (dht->close_clientlist[i].assoc6.timestamp != 0)) | 2306 | |
2306 | num++; | 2307 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
2308 | num += (fr->client_list[j].assoc4.timestamp != 0) + (fr->client_list[j].assoc6.timestamp != 0); | ||
2309 | } | ||
2310 | } | ||
2307 | 2311 | ||
2308 | uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; | 2312 | uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; |
2309 | return size32 | 2313 | return size32 |
2310 | + sizesubhead + sizeof(DHT_Friend) * dht->num_friends | 2314 | + sizesubhead + sizeof(Node_format) * num; |
2311 | + sizesubhead + sizeof(Client_data) * num; | ||
2312 | } | 2315 | } |
2313 | 2316 | ||
2314 | static uint8_t *z_state_save_subheader(uint8_t *data, uint32_t len, uint16_t type) | 2317 | static uint8_t *z_state_save_subheader(uint8_t *data, uint32_t len, uint16_t type) |
@@ -2328,92 +2331,77 @@ void DHT_save(DHT *dht, uint8_t *data) | |||
2328 | *(uint32_t *)data = DHT_STATE_COOKIE_GLOBAL; | 2331 | *(uint32_t *)data = DHT_STATE_COOKIE_GLOBAL; |
2329 | data += sizeof(uint32_t); | 2332 | data += sizeof(uint32_t); |
2330 | 2333 | ||
2331 | len = sizeof(DHT_Friend) * dht->num_friends; | 2334 | uint32_t num, i, j; |
2332 | type = DHT_STATE_TYPE_FRIENDS_ASSOC46; | ||
2333 | data = z_state_save_subheader(data, len, type); | ||
2334 | memcpy(data, dht->friends_list, len); | ||
2335 | data += len; | ||
2336 | 2335 | ||
2337 | uint32_t num = 0, i; | 2336 | uint8_t *old_data = data; |
2338 | 2337 | ||
2339 | for (i = 0; i < LCLIENT_LIST; ++i) | 2338 | /* get right offset. we write the actual header later. */ |
2340 | if ((dht->close_clientlist[i].assoc4.timestamp != 0) || | 2339 | data = z_state_save_subheader(data, 0, 0); |
2341 | (dht->close_clientlist[i].assoc6.timestamp != 0)) | ||
2342 | num++; | ||
2343 | 2340 | ||
2344 | len = num * sizeof(Client_data); | 2341 | Node_format *clients = (Node_format *)data; |
2345 | type = DHT_STATE_TYPE_CLIENTS_ASSOC46; | ||
2346 | data = z_state_save_subheader(data, len, type); | ||
2347 | 2342 | ||
2348 | if (num) { | 2343 | for (num = 0, i = 0; i < LCLIENT_LIST; ++i) { |
2349 | Client_data *clients = (Client_data *)data; | 2344 | if (dht->close_clientlist[i].assoc4.timestamp != 0) { |
2345 | memcpy(clients[num].public_key, dht->close_clientlist[i].client_id, crypto_box_PUBLICKEYBYTES); | ||
2346 | clients[num].ip_port = dht->close_clientlist[i].assoc4.ip_port; | ||
2347 | ++num; | ||
2348 | } | ||
2350 | 2349 | ||
2351 | for (num = 0, i = 0; i < LCLIENT_LIST; ++i) | 2350 | if (dht->close_clientlist[i].assoc6.timestamp != 0) { |
2352 | if ((dht->close_clientlist[i].assoc4.timestamp != 0) || | 2351 | memcpy(clients[num].public_key, dht->close_clientlist[i].client_id, crypto_box_PUBLICKEYBYTES); |
2353 | (dht->close_clientlist[i].assoc6.timestamp != 0)) | 2352 | clients[num].ip_port = dht->close_clientlist[i].assoc6.ip_port; |
2354 | memcpy(&clients[num++], &dht->close_clientlist[i], sizeof(Client_data)); | 2353 | ++num; |
2354 | } | ||
2355 | } | 2355 | } |
2356 | } | ||
2357 | 2356 | ||
2358 | static void DHT_bootstrap_loaded_clients(DHT *dht) | 2357 | for (i = 0; i < DHT_FAKE_FRIEND_NUMBER && i < dht->num_friends; ++i) { |
2359 | { | 2358 | DHT_Friend *fr = &dht->friends_list[i]; |
2360 | if (!dht->loaded_clients_list) | ||
2361 | return; | ||
2362 | 2359 | ||
2363 | uint32_t i; | ||
2364 | |||
2365 | Client_data *client_list = dht->loaded_clients_list; | ||
2366 | uint32_t client_count = dht->loaded_num_clients; | ||
2367 | |||
2368 | for (i = 0; i < client_count; ++i) { | ||
2369 | if (client_list[i].assoc4.timestamp != 0) | ||
2370 | DHT_bootstrap(dht, client_list[i].assoc4.ip_port, client_list[i].client_id); | ||
2371 | |||
2372 | if (client_list[i].assoc6.timestamp != 0) | ||
2373 | DHT_bootstrap(dht, client_list[i].assoc6.ip_port, client_list[i].client_id); | ||
2374 | } | ||
2375 | } | ||
2376 | |||
2377 | static void getnodes_of_loaded_friend_clients(DHT *dht) | ||
2378 | { | ||
2379 | if (!dht->loaded_friends_list) | ||
2380 | return; | ||
2381 | |||
2382 | uint32_t i, j; | ||
2383 | |||
2384 | DHT_Friend *friend_list = dht->loaded_friends_list; | ||
2385 | uint32_t friend_count = dht->loaded_num_friends; | ||
2386 | |||
2387 | for (i = 0; i < friend_count; ++i) { | ||
2388 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 2360 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
2389 | Client_data *client = &friend_list[i].client_list[j]; | 2361 | if (fr->client_list[j].assoc4.timestamp != 0) { |
2390 | 2362 | memcpy(clients[num].public_key, fr->client_list[j].client_id, crypto_box_PUBLICKEYBYTES); | |
2391 | if (client->assoc4.timestamp != 0) | 2363 | clients[num].ip_port = fr->client_list[j].assoc4.ip_port; |
2392 | getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id, NULL); | 2364 | ++num; |
2365 | } | ||
2393 | 2366 | ||
2394 | if (client->assoc6.timestamp != 0) | 2367 | if (fr->client_list[j].assoc6.timestamp != 0) { |
2395 | getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id, NULL); | 2368 | memcpy(clients[num].public_key, fr->client_list[j].client_id, crypto_box_PUBLICKEYBYTES); |
2369 | clients[num].ip_port = fr->client_list[j].assoc6.ip_port; | ||
2370 | ++num; | ||
2371 | } | ||
2396 | } | 2372 | } |
2397 | } | 2373 | } |
2374 | |||
2375 | z_state_save_subheader(old_data, num * sizeof(Node_format), DHT_STATE_TYPE_NODES); | ||
2398 | } | 2376 | } |
2399 | 2377 | ||
2378 | /* Bootstrap from this number of nodes every time DHT_connect_after_load() is called */ | ||
2379 | #define SAVE_BOOTSTAP_FREQUENCY 8 | ||
2380 | |||
2400 | /* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set */ | 2381 | /* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set */ |
2401 | int DHT_connect_after_load(DHT *dht) | 2382 | int DHT_connect_after_load(DHT *dht) |
2402 | { | 2383 | { |
2403 | if (dht == NULL) | 2384 | if (dht == NULL) |
2404 | return -1; | 2385 | return -1; |
2405 | 2386 | ||
2406 | getnodes_of_loaded_friend_clients(dht); | 2387 | if (!dht->loaded_nodes_list) |
2407 | DHT_bootstrap_loaded_clients(dht); | 2388 | return -1; |
2389 | |||
2390 | /* DHT is connected, stop. */ | ||
2391 | if (DHT_non_lan_connected(dht)) { | ||
2392 | free(dht->loaded_nodes_list); | ||
2393 | dht->loaded_nodes_list = NULL; | ||
2394 | dht->loaded_num_nodes = 0; | ||
2395 | return 0; | ||
2396 | } | ||
2408 | 2397 | ||
2409 | // Loaded lists were allocd, free them | 2398 | unsigned int i; |
2410 | free(dht->loaded_friends_list); | ||
2411 | dht->loaded_friends_list = NULL; | ||
2412 | dht->loaded_num_friends = 0; | ||
2413 | 2399 | ||
2414 | free(dht->loaded_clients_list); | 2400 | for (i = 0; i < dht->loaded_num_nodes && i < SAVE_BOOTSTAP_FREQUENCY; ++i) { |
2415 | dht->loaded_clients_list = NULL; | 2401 | unsigned int index = dht->loaded_nodes_index % dht->loaded_num_nodes; |
2416 | dht->loaded_num_clients = 0; | 2402 | DHT_bootstrap(dht, dht->loaded_nodes_list[index].ip_port, dht->loaded_nodes_list[index].public_key); |
2403 | ++dht->loaded_nodes_index; | ||
2404 | } | ||
2417 | 2405 | ||
2418 | return 0; | 2406 | return 0; |
2419 | } | 2407 | } |
@@ -2424,46 +2412,23 @@ static int dht_load_state_callback(void *outer, const uint8_t *data, uint32_t le | |||
2424 | uint32_t num, i; | 2412 | uint32_t num, i; |
2425 | 2413 | ||
2426 | switch (type) { | 2414 | switch (type) { |
2427 | case DHT_STATE_TYPE_FRIENDS_ASSOC46: | 2415 | case DHT_STATE_TYPE_NODES: |
2428 | if (length % sizeof(DHT_Friend) != 0) | 2416 | if ((length % sizeof(Node_format)) != 0) |
2429 | break; | ||
2430 | |||
2431 | { /* localize declarations */ | ||
2432 | DHT_Friend *friend_list = (DHT_Friend *)data; | ||
2433 | num = length / sizeof(DHT_Friend); | ||
2434 | |||
2435 | free(dht->loaded_friends_list); | ||
2436 | // Copy to loaded_friends_list | ||
2437 | dht->loaded_friends_list = calloc(num, sizeof(DHT_Friend)); | ||
2438 | |||
2439 | for (i = 0; i < num; i++) | ||
2440 | memcpy(&(dht->loaded_friends_list[i]), &(friend_list[i]), sizeof(DHT_Friend)); | ||
2441 | |||
2442 | dht->loaded_num_friends = num; | ||
2443 | |||
2444 | dht->has_loaded_friends_clients = 1; | ||
2445 | } /* localize declarations */ | ||
2446 | |||
2447 | break; | ||
2448 | |||
2449 | case DHT_STATE_TYPE_CLIENTS_ASSOC46: | ||
2450 | if ((length % sizeof(Client_data)) != 0) | ||
2451 | break; | 2417 | break; |
2452 | 2418 | ||
2453 | { /* localize declarations */ | 2419 | { /* localize declarations */ |
2454 | num = length / sizeof(Client_data); | 2420 | num = length / sizeof(Node_format); |
2455 | Client_data *client_list = (Client_data *)data; | 2421 | Node_format *client_list = (Node_format *)data; |
2456 | 2422 | ||
2457 | free(dht->loaded_clients_list); | 2423 | free(dht->loaded_nodes_list); |
2458 | // Copy to loaded_clients_list | 2424 | // Copy to loaded_clients_list |
2459 | dht->loaded_clients_list = calloc(num, sizeof(Client_data)); | 2425 | dht->loaded_nodes_list = calloc(num, sizeof(Node_format)); |
2460 | 2426 | ||
2461 | for (i = 0; i < num; i++) | 2427 | for (i = 0; i < num; i++) |
2462 | memcpy(&(dht->loaded_clients_list[i]), &(client_list[i]), sizeof(Client_data)); | 2428 | memcpy(&(dht->loaded_nodes_list[i]), &(client_list[i]), sizeof(Node_format)); |
2463 | 2429 | ||
2464 | dht->loaded_num_clients = num; | 2430 | dht->loaded_num_nodes = num; |
2465 | 2431 | ||
2466 | dht->has_loaded_friends_clients = 1; | ||
2467 | } /* localize declarations */ | 2432 | } /* localize declarations */ |
2468 | 2433 | ||
2469 | break; | 2434 | break; |
diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 318a6002..c612c287 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h | |||
@@ -211,13 +211,9 @@ typedef struct { | |||
211 | DHT_Friend *friends_list; | 211 | DHT_Friend *friends_list; |
212 | uint16_t num_friends; | 212 | uint16_t num_friends; |
213 | 213 | ||
214 | // Used after loading of file (tox_load), but no longer needed after connect (tox_connect) | 214 | Node_format *loaded_nodes_list; |
215 | // Unsure if friends_list and num_friends could just be used instead? | 215 | uint32_t loaded_num_nodes; |
216 | int has_loaded_friends_clients; // Whether or not we have loaded on the first do_DHT | 216 | unsigned int loaded_nodes_index; |
217 | DHT_Friend *loaded_friends_list; | ||
218 | uint32_t loaded_num_friends; | ||
219 | Client_data *loaded_clients_list; | ||
220 | uint32_t loaded_num_clients; | ||
221 | 217 | ||
222 | Shared_Keys shared_keys_recv; | 218 | Shared_Keys shared_keys_recv; |
223 | Shared_Keys shared_keys_sent; | 219 | Shared_Keys shared_keys_sent; |