summaryrefslogtreecommitdiff
path: root/toxcore/onion_client.c
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2018-08-01 23:02:13 +0000
committeriphydf <iphydf@users.noreply.github.com>2018-08-16 21:01:43 +0000
commitd6d305feeb76735ee4b4e14c6bca737a5482bc19 (patch)
tree99005c635a452245006b3b5de44f1dd80da9f77f /toxcore/onion_client.c
parent54066f338f185f2fbd6694d9a4877f42cbfa21c8 (diff)
Use per-instance `Mono_Time` for Messenger and onion.
Diffstat (limited to 'toxcore/onion_client.c')
-rw-r--r--toxcore/onion_client.c146
1 files changed, 78 insertions, 68 deletions
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 819bd23f..d3b5cefc 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -113,6 +113,8 @@ typedef struct Onion_Data_Handler {
113} Onion_Data_Handler; 113} Onion_Data_Handler;
114 114
115struct Onion_Client { 115struct Onion_Client {
116 Mono_Time *mono_time;
117
116 DHT *dht; 118 DHT *dht;
117 Net_Crypto *c; 119 Net_Crypto *c;
118 Networking_Core *net; 120 Networking_Core *net;
@@ -316,16 +318,16 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
316 * return -1 if nodes are suitable for creating a new path. 318 * return -1 if nodes are suitable for creating a new path.
317 * return path number of already existing similar path if one already exists. 319 * return path number of already existing similar path if one already exists.
318 */ 320 */
319static int is_path_used(const Onion_Client_Paths *onion_paths, const Node_format *nodes) 321static int is_path_used(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, const Node_format *nodes)
320{ 322{
321 unsigned int i; 323 unsigned int i;
322 324
323 for (i = 0; i < NUMBER_ONION_PATHS; ++i) { 325 for (i = 0; i < NUMBER_ONION_PATHS; ++i) {
324 if (is_timeout(onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) { 326 if (mono_time_is_timeout(mono_time, onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
325 continue; 327 continue;
326 } 328 }
327 329
328 if (is_timeout(onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) { 330 if (mono_time_is_timeout(mono_time, onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) {
329 continue; 331 continue;
330 } 332 }
331 333
@@ -339,7 +341,7 @@ static int is_path_used(const Onion_Client_Paths *onion_paths, const Node_format
339} 341}
340 342
341/* is path timed out */ 343/* is path timed out */
342static bool path_timed_out(Onion_Client_Paths *onion_paths, uint32_t pathnum) 344static bool path_timed_out(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t pathnum)
343{ 345{
344 pathnum = pathnum % NUMBER_ONION_PATHS; 346 pathnum = pathnum % NUMBER_ONION_PATHS;
345 347
@@ -347,16 +349,16 @@ static bool path_timed_out(Onion_Client_Paths *onion_paths, uint32_t pathnum)
347 uint64_t timeout = is_new ? ONION_PATH_FIRST_TIMEOUT : ONION_PATH_TIMEOUT; 349 uint64_t timeout = is_new ? ONION_PATH_FIRST_TIMEOUT : ONION_PATH_TIMEOUT;
348 350
349 return ((onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES 351 return ((onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES
350 && is_timeout(onion_paths->last_path_used[pathnum], timeout)) 352 && mono_time_is_timeout(mono_time, onion_paths->last_path_used[pathnum], timeout))
351 || is_timeout(onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME)); 353 || mono_time_is_timeout(mono_time, onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME));
352} 354}
353 355
354/* should node be considered to have timed out */ 356/* should node be considered to have timed out */
355static bool onion_node_timed_out(const Onion_Node *node) 357static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_time)
356{ 358{
357 return (node->timestamp == 0 359 return (node->timestamp == 0
358 || (node->unsuccessful_pings >= ONION_NODE_MAX_PINGS 360 || (node->unsuccessful_pings >= ONION_NODE_MAX_PINGS
359 && is_timeout(node->last_pinged, ONION_NODE_TIMEOUT))); 361 && mono_time_is_timeout(mono_time, node->last_pinged, ONION_NODE_TIMEOUT)));
360} 362}
361 363
362/* Create a new path or use an old suitable one (if pathnum is valid) 364/* Create a new path or use an old suitable one (if pathnum is valid)
@@ -376,21 +378,21 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
376 pathnum = pathnum % NUMBER_ONION_PATHS; 378 pathnum = pathnum % NUMBER_ONION_PATHS;
377 } 379 }
378 380
379 if (path_timed_out(onion_paths, pathnum)) { 381 if (path_timed_out(onion_c->mono_time, onion_paths, pathnum)) {
380 Node_format nodes[ONION_PATH_LENGTH]; 382 Node_format nodes[ONION_PATH_LENGTH];
381 383
382 if (random_nodes_path_onion(onion_c, nodes, ONION_PATH_LENGTH) != ONION_PATH_LENGTH) { 384 if (random_nodes_path_onion(onion_c, nodes, ONION_PATH_LENGTH) != ONION_PATH_LENGTH) {
383 return -1; 385 return -1;
384 } 386 }
385 387
386 int n = is_path_used(onion_paths, nodes); 388 int n = is_path_used(onion_c->mono_time, onion_paths, nodes);
387 389
388 if (n == -1) { 390 if (n == -1) {
389 if (create_onion_path(onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) { 391 if (create_onion_path(onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) {
390 return -1; 392 return -1;
391 } 393 }
392 394
393 onion_paths->path_creation_time[pathnum] = unix_time(); 395 onion_paths->path_creation_time[pathnum] = mono_time_get(onion_c->mono_time);
394 onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum]; 396 onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum];
395 onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2; 397 onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2;
396 398
@@ -406,7 +408,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
406 } 408 }
407 409
408 if (onion_paths->last_path_used_times[pathnum] < ONION_PATH_MAX_NO_RESPONSE_USES) { 410 if (onion_paths->last_path_used_times[pathnum] < ONION_PATH_MAX_NO_RESPONSE_USES) {
409 onion_paths->last_path_used[pathnum] = unix_time(); 411 onion_paths->last_path_used[pathnum] = mono_time_get(onion_c->mono_time);
410 } 412 }
411 413
412 ++onion_paths->last_path_used_times[pathnum]; 414 ++onion_paths->last_path_used_times[pathnum];
@@ -415,9 +417,9 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
415} 417}
416 418
417/* Does path with path_num exist. */ 419/* Does path with path_num exist. */
418static bool path_exists(Onion_Client_Paths *onion_paths, uint32_t path_num) 420static bool path_exists(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t path_num)
419{ 421{
420 if (path_timed_out(onion_paths, path_num)) { 422 if (path_timed_out(mono_time, onion_paths, path_num)) {
421 return 0; 423 return 0;
422 } 424 }
423 425
@@ -442,7 +444,7 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t
442 } 444 }
443 445
444 if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) { 446 if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) {
445 onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = unix_time(); 447 onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = mono_time_get(onion_c->mono_time);
446 onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0; 448 onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0;
447 449
448 Node_format nodes[ONION_PATH_LENGTH]; 450 Node_format nodes[ONION_PATH_LENGTH];
@@ -521,7 +523,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ
521 memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE); 523 memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
522 memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, &ip_port, sizeof(IP_Port)); 524 memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, &ip_port, sizeof(IP_Port));
523 memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t)); 525 memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
524 *sendback = ping_array_add(onion_c->announce_ping_array, data, sizeof(data)); 526 *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data));
525 527
526 if (*sendback == 0) { 528 if (*sendback == 0) {
527 return -1; 529 return -1;
@@ -547,7 +549,7 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u
547 memcpy(&sback, sendback, sizeof(uint64_t)); 549 memcpy(&sback, sendback, sizeof(uint64_t));
548 uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)]; 550 uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
549 551
550 if (ping_array_check(onion_c->announce_ping_array, data, sizeof(data), sback) != sizeof(data)) { 552 if (ping_array_check(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data), sback) != sizeof(data)) {
551 return ~0; 553 return ~0;
552 } 554 }
553 555
@@ -611,6 +613,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
611} 613}
612 614
613typedef struct Onion_Client_Cmp_data { 615typedef struct Onion_Client_Cmp_data {
616 const Mono_Time *mono_time;
614 const uint8_t *base_public_key; 617 const uint8_t *base_public_key;
615 Onion_Node entry; 618 Onion_Node entry;
616} Onion_Client_Cmp_data; 619} Onion_Client_Cmp_data;
@@ -624,8 +627,8 @@ static int onion_client_cmp_entry(const void *a, const void *b)
624 Onion_Node entry2 = cmp2.entry; 627 Onion_Node entry2 = cmp2.entry;
625 const uint8_t *cmp_public_key = cmp1.base_public_key; 628 const uint8_t *cmp_public_key = cmp1.base_public_key;
626 629
627 int t1 = onion_node_timed_out(&entry1); 630 int t1 = onion_node_timed_out(&entry1, cmp1.mono_time);
628 int t2 = onion_node_timed_out(&entry2); 631 int t2 = onion_node_timed_out(&entry2, cmp2.mono_time);
629 632
630 if (t1 && t2) { 633 if (t1 && t2) {
631 return 0; 634 return 0;
@@ -652,13 +655,15 @@ static int onion_client_cmp_entry(const void *a, const void *b)
652 return 0; 655 return 0;
653} 656}
654 657
655static void sort_onion_node_list(Onion_Node *list, unsigned int length, const uint8_t *comp_public_key) 658static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time,
659 const uint8_t *comp_public_key)
656{ 660{
657 // Pass comp_public_key to qsort with each Client_data entry, so the 661 // Pass comp_public_key to qsort with each Client_data entry, so the
658 // comparison function can use it as the base of comparison. 662 // comparison function can use it as the base of comparison.
659 VLA(Onion_Client_Cmp_data, cmp_list, length); 663 VLA(Onion_Client_Cmp_data, cmp_list, length);
660 664
661 for (uint32_t i = 0; i < length; ++i) { 665 for (uint32_t i = 0; i < length; ++i) {
666 cmp_list[i].mono_time = mono_time;
662 cmp_list[i].base_public_key = comp_public_key; 667 cmp_list[i].base_public_key = comp_public_key;
663 cmp_list[i].entry = list[i]; 668 cmp_list[i].entry = list[i];
664 } 669 }
@@ -695,7 +700,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
695 } 700 }
696 701
697 if (is_stored == 1) { 702 if (is_stored == 1) {
698 onion_c->friends_list[num - 1].last_reported_announced = unix_time(); 703 onion_c->friends_list[num - 1].last_reported_announced = mono_time_get(onion_c->mono_time);
699 } 704 }
700 705
701 list_nodes = onion_c->friends_list[num - 1].clients_list; 706 list_nodes = onion_c->friends_list[num - 1].clients_list;
@@ -703,12 +708,12 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
703 list_length = MAX_ONION_CLIENTS; 708 list_length = MAX_ONION_CLIENTS;
704 } 709 }
705 710
706 sort_onion_node_list(list_nodes, list_length, reference_id); 711 sort_onion_node_list(list_nodes, list_length, onion_c->mono_time, reference_id);
707 712
708 int index = -1, stored = 0; 713 int index = -1, stored = 0;
709 unsigned int i; 714 unsigned int i;
710 715
711 if (onion_node_timed_out(&list_nodes[0]) 716 if (onion_node_timed_out(&list_nodes[0], onion_c->mono_time)
712 || id_closest(reference_id, list_nodes[0].public_key, public_key) == 2) { 717 || id_closest(reference_id, list_nodes[0].public_key, public_key) == 2) {
713 index = 0; 718 index = 0;
714 } 719 }
@@ -738,24 +743,25 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
738 } 743 }
739 744
740 list_nodes[index].is_stored = is_stored; 745 list_nodes[index].is_stored = is_stored;
741 list_nodes[index].timestamp = unix_time(); 746 list_nodes[index].timestamp = mono_time_get(onion_c->mono_time);
742 list_nodes[index].unsuccessful_pings = 0; 747 list_nodes[index].unsuccessful_pings = 0;
743 748
744 if (!stored) { 749 if (!stored) {
745 list_nodes[index].last_pinged = 0; 750 list_nodes[index].last_pinged = 0;
746 list_nodes[index].added_time = unix_time(); 751 list_nodes[index].added_time = mono_time_get(onion_c->mono_time);
747 } 752 }
748 753
749 list_nodes[index].path_used = path_used; 754 list_nodes[index].path_used = path_used;
750 return 0; 755 return 0;
751} 756}
752 757
753static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, const uint8_t *public_key) 758static int good_to_ping(Mono_Time *mono_time, Last_Pinged *last_pinged, uint8_t *last_pinged_index,
759 const uint8_t *public_key)
754{ 760{
755 unsigned int i; 761 unsigned int i;
756 762
757 for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) { 763 for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) {
758 if (!is_timeout(last_pinged[i].timestamp, MIN_NODE_PING_TIME)) { 764 if (!mono_time_is_timeout(mono_time, last_pinged[i].timestamp, MIN_NODE_PING_TIME)) {
759 if (public_key_cmp(last_pinged[i].public_key, public_key) == 0) { 765 if (public_key_cmp(last_pinged[i].public_key, public_key) == 0) {
760 return 0; 766 return 0;
761 } 767 }
@@ -763,7 +769,7 @@ static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, co
763 } 769 }
764 770
765 memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); 771 memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
766 last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = unix_time(); 772 last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = mono_time_get(mono_time);
767 ++*last_pinged_index; 773 ++*last_pinged_index;
768 return 1; 774 return 1;
769} 775}
@@ -811,9 +817,9 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
811 } 817 }
812 } 818 }
813 819
814 if (onion_node_timed_out(&list_nodes[0]) 820 if (onion_node_timed_out(&list_nodes[0], onion_c->mono_time)
815 || id_closest(reference_id, list_nodes[0].public_key, nodes[i].public_key) == 2 821 || id_closest(reference_id, list_nodes[0].public_key, nodes[i].public_key) == 2
816 || onion_node_timed_out(&list_nodes[1]) 822 || onion_node_timed_out(&list_nodes[1], onion_c->mono_time)
817 || id_closest(reference_id, list_nodes[1].public_key, nodes[i].public_key) == 2) { 823 || id_closest(reference_id, list_nodes[1].public_key, nodes[i].public_key) == 2) {
818 /* check if node is already in list. */ 824 /* check if node is already in list. */
819 for (j = 0; j < list_length; ++j) { 825 for (j = 0; j < list_length; ++j) {
@@ -822,7 +828,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
822 } 828 }
823 } 829 }
824 830
825 if (j == list_length && good_to_ping(last_pinged, last_pinged_index, nodes[i].public_key)) { 831 if (j == list_length && good_to_ping(onion_c->mono_time, last_pinged, last_pinged_index, nodes[i].public_key)) {
826 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, nullptr, ~0); 832 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, nullptr, ~0);
827 } 833 }
828 } 834 }
@@ -894,7 +900,7 @@ static int handle_announce_response(void *object, IP_Port source, const uint8_t
894 } 900 }
895 901
896 // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline? 902 // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
897 onion_c->last_packet_recv = unix_time(); 903 onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
898 return 0; 904 return 0;
899} 905}
900 906
@@ -975,7 +981,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
975 } 981 }
976 982
977 onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t)); 983 onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
978 onion_c->friends_list[friend_num].last_seen = unix_time(); 984 onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
979 985
980 uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH; 986 uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH;
981 987
@@ -1054,7 +1060,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
1054 Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list; 1060 Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list;
1055 1061
1056 for (i = 0; i < MAX_ONION_CLIENTS; ++i) { 1062 for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
1057 if (onion_node_timed_out(&list_nodes[i])) { 1063 if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
1058 continue; 1064 continue;
1059 } 1065 }
1060 1066
@@ -1196,7 +1202,7 @@ static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8
1196 1202
1197 uint8_t data[DHTPK_DATA_MAX_LENGTH]; 1203 uint8_t data[DHTPK_DATA_MAX_LENGTH];
1198 data[0] = ONION_DATA_DHTPK; 1204 data[0] = ONION_DATA_DHTPK;
1199 uint64_t no_replay = unix_time(); 1205 uint64_t no_replay = mono_time_get(onion_c->mono_time);
1200 host_to_net((uint8_t *)&no_replay, sizeof(no_replay)); 1206 host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
1201 memcpy(data + 1, &no_replay, sizeof(no_replay)); 1207 memcpy(data + 1, &no_replay, sizeof(no_replay));
1202 memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE); 1208 memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE);
@@ -1420,7 +1426,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
1420 onion_c->friends_list[friend_num].know_dht_public_key = 0; 1426 onion_c->friends_list[friend_num].know_dht_public_key = 0;
1421 } 1427 }
1422 1428
1423 onion_c->friends_list[friend_num].last_seen = unix_time(); 1429 onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
1424 onion_c->friends_list[friend_num].know_dht_public_key = 1; 1430 onion_c->friends_list[friend_num].know_dht_public_key = 1;
1425 memcpy(onion_c->friends_list[friend_num].dht_public_key, dht_key, CRYPTO_PUBLIC_KEY_SIZE); 1431 memcpy(onion_c->friends_list[friend_num].dht_public_key, dht_key, CRYPTO_PUBLIC_KEY_SIZE);
1426 1432
@@ -1485,7 +1491,7 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
1485 } 1491 }
1486 1492
1487 if (is_online == 0 && onion_c->friends_list[friend_num].is_online == 1) { 1493 if (is_online == 0 && onion_c->friends_list[friend_num].is_online == 1) {
1488 onion_c->friends_list[friend_num].last_seen = unix_time(); 1494 onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
1489 } 1495 }
1490 1496
1491 onion_c->friends_list[friend_num].is_online = is_online; 1497 onion_c->friends_list[friend_num].is_online = is_online;
@@ -1548,10 +1554,11 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1548 interval = ANNOUNCE_FRIEND_BEGINNING; 1554 interval = ANNOUNCE_FRIEND_BEGINNING;
1549 } else { 1555 } else {
1550 if (onion_c->friends_list[friendnum].last_reported_announced == 0) { 1556 if (onion_c->friends_list[friendnum].last_reported_announced == 0) {
1551 onion_c->friends_list[friendnum].last_reported_announced = unix_time(); 1557 onion_c->friends_list[friendnum].last_reported_announced = mono_time_get(onion_c->mono_time);
1552 } 1558 }
1553 1559
1554 uint64_t backoff_interval = (unix_time() - onion_c->friends_list[friendnum].last_reported_announced) 1560 uint64_t backoff_interval = (mono_time_get(onion_c->mono_time) -
1561 onion_c->friends_list[friendnum].last_reported_announced)
1555 / ONION_FRIEND_BACKOFF_FACTOR; 1562 / ONION_FRIEND_BACKOFF_FACTOR;
1556 1563
1557 if (backoff_interval > ONION_FRIEND_MAX_PING_INTERVAL) { 1564 if (backoff_interval > ONION_FRIEND_MAX_PING_INTERVAL) {
@@ -1572,15 +1579,15 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1572 bool ping_random = true; 1579 bool ping_random = true;
1573 1580
1574 for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) { 1581 for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
1575 if (!(is_timeout(list_nodes[i].timestamp, interval / MAX_ONION_CLIENTS) 1582 if (!(mono_time_is_timeout(onion_c->mono_time, list_nodes[i].timestamp, interval / MAX_ONION_CLIENTS)
1576 && is_timeout(list_nodes[i].last_pinged, ONION_NODE_PING_INTERVAL))) { 1583 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, ONION_NODE_PING_INTERVAL))) {
1577 ping_random = false; 1584 ping_random = false;
1578 break; 1585 break;
1579 } 1586 }
1580 } 1587 }
1581 1588
1582 for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) { 1589 for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
1583 if (onion_node_timed_out(&list_nodes[i])) { 1590 if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
1584 continue; 1591 continue;
1585 } 1592 }
1586 1593
@@ -1588,7 +1595,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1588 1595
1589 1596
1590 if (list_nodes[i].last_pinged == 0) { 1597 if (list_nodes[i].last_pinged == 0) {
1591 list_nodes[i].last_pinged = unix_time(); 1598 list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
1592 continue; 1599 continue;
1593 } 1600 }
1594 1601
@@ -1596,11 +1603,11 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1596 continue; 1603 continue;
1597 } 1604 }
1598 1605
1599 if (is_timeout(list_nodes[i].last_pinged, interval) 1606 if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval)
1600 || (ping_random && random_u32() % (MAX_ONION_CLIENTS - i) == 0)) { 1607 || (ping_random && random_u32() % (MAX_ONION_CLIENTS - i) == 0)) {
1601 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, 1608 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port,
1602 list_nodes[i].public_key, nullptr, ~0) == 0) { 1609 list_nodes[i].public_key, nullptr, ~0) == 0) {
1603 list_nodes[i].last_pinged = unix_time(); 1610 list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
1604 ++list_nodes[i].unsuccessful_pings; 1611 ++list_nodes[i].unsuccessful_pings;
1605 ping_random = false; 1612 ping_random = false;
1606 } 1613 }
@@ -1634,15 +1641,17 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1634 } 1641 }
1635 1642
1636 /* send packets to friend telling them our DHT public key. */ 1643 /* send packets to friend telling them our DHT public key. */
1637 if (is_timeout(onion_c->friends_list[friendnum].last_dht_pk_onion_sent, ONION_DHTPK_SEND_INTERVAL)) { 1644 if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_onion_sent,
1645 ONION_DHTPK_SEND_INTERVAL)) {
1638 if (send_dhtpk_announce(onion_c, friendnum, 0) >= 1) { 1646 if (send_dhtpk_announce(onion_c, friendnum, 0) >= 1) {
1639 onion_c->friends_list[friendnum].last_dht_pk_onion_sent = unix_time(); 1647 onion_c->friends_list[friendnum].last_dht_pk_onion_sent = mono_time_get(onion_c->mono_time);
1640 } 1648 }
1641 } 1649 }
1642 1650
1643 if (is_timeout(onion_c->friends_list[friendnum].last_dht_pk_dht_sent, DHT_DHTPK_SEND_INTERVAL)) { 1651 if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_dht_sent,
1652 DHT_DHTPK_SEND_INTERVAL)) {
1644 if (send_dhtpk_announce(onion_c, friendnum, 1) >= 1) { 1653 if (send_dhtpk_announce(onion_c, friendnum, 1) >= 1) {
1645 onion_c->friends_list[friendnum].last_dht_pk_dht_sent = unix_time(); 1654 onion_c->friends_list[friendnum].last_dht_pk_dht_sent = mono_time_get(onion_c->mono_time);
1646 } 1655 }
1647 } 1656 }
1648 } 1657 }
@@ -1668,7 +1677,7 @@ static void do_announce(Onion_Client *onion_c)
1668 Onion_Node *list_nodes = onion_c->clients_announce_list; 1677 Onion_Node *list_nodes = onion_c->clients_announce_list;
1669 1678
1670 for (i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) { 1679 for (i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
1671 if (onion_node_timed_out(&list_nodes[i])) { 1680 if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
1672 continue; 1681 continue;
1673 } 1682 }
1674 1683
@@ -1687,7 +1696,7 @@ static void do_announce(Onion_Client *onion_c)
1687 1696
1688 unsigned int interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; 1697 unsigned int interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
1689 1698
1690 if (list_nodes[i].is_stored && path_exists(&onion_c->onion_paths_self, list_nodes[i].path_used)) { 1699 if (list_nodes[i].is_stored && path_exists(onion_c->mono_time, &onion_c->onion_paths_self, list_nodes[i].path_used)) {
1691 interval = ANNOUNCE_INTERVAL_ANNOUNCED; 1700 interval = ANNOUNCE_INTERVAL_ANNOUNCED;
1692 1701
1693 uint32_t pathnum = list_nodes[i].path_used % NUMBER_ONION_PATHS; 1702 uint32_t pathnum = list_nodes[i].path_used % NUMBER_ONION_PATHS;
@@ -1696,32 +1705,32 @@ static void do_announce(Onion_Client *onion_c)
1696 * aggressively, if it has survived for at least TIME_TO_STABLE 1705 * aggressively, if it has survived for at least TIME_TO_STABLE
1697 * and the latest packets sent to it are not timing out. 1706 * and the latest packets sent to it are not timing out.
1698 */ 1707 */
1699 if (is_timeout(list_nodes[i].added_time, TIME_TO_STABLE) 1708 if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)
1700 && !(list_nodes[i].unsuccessful_pings > 0 1709 && !(list_nodes[i].unsuccessful_pings > 0
1701 && is_timeout(list_nodes[i].last_pinged, ONION_NODE_TIMEOUT)) 1710 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, ONION_NODE_TIMEOUT))
1702 && is_timeout(onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE) 1711 && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE)
1703 && !(onion_c->onion_paths_self.last_path_used_times[pathnum] > 0 1712 && !(onion_c->onion_paths_self.last_path_used_times[pathnum] > 0
1704 && is_timeout(onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) { 1713 && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) {
1705 interval = ANNOUNCE_INTERVAL_STABLE; 1714 interval = ANNOUNCE_INTERVAL_STABLE;
1706 } 1715 }
1707 } 1716 }
1708 1717
1709 if (is_timeout(list_nodes[i].last_pinged, interval) 1718 if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval)
1710 || (is_timeout(onion_c->last_announce, ONION_NODE_PING_INTERVAL) 1719 || (mono_time_is_timeout(onion_c->mono_time, onion_c->last_announce, ONION_NODE_PING_INTERVAL)
1711 && random_u32() % (MAX_ONION_CLIENTS_ANNOUNCE - i) == 0)) { 1720 && random_u32() % (MAX_ONION_CLIENTS_ANNOUNCE - i) == 0)) {
1712 uint32_t path_to_use = list_nodes[i].path_used; 1721 uint32_t path_to_use = list_nodes[i].path_used;
1713 1722
1714 if (list_nodes[i].unsuccessful_pings == ONION_NODE_MAX_PINGS - 1 1723 if (list_nodes[i].unsuccessful_pings == ONION_NODE_MAX_PINGS - 1
1715 && is_timeout(list_nodes[i].added_time, TIME_TO_STABLE)) { 1724 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)) {
1716 /* Last chance for a long-lived node - try a random path */ 1725 /* Last chance for a long-lived node - try a random path */
1717 path_to_use = ~0; 1726 path_to_use = ~0;
1718 } 1727 }
1719 1728
1720 if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].public_key, 1729 if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].public_key,
1721 list_nodes[i].ping_id, path_to_use) == 0) { 1730 list_nodes[i].ping_id, path_to_use) == 0) {
1722 list_nodes[i].last_pinged = unix_time(); 1731 list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
1723 ++list_nodes[i].unsuccessful_pings; 1732 ++list_nodes[i].unsuccessful_pings;
1724 onion_c->last_announce = unix_time(); 1733 onion_c->last_announce = mono_time_get(onion_c->mono_time);
1725 } 1734 }
1726 } 1735 }
1727 } 1736 }
@@ -1756,7 +1765,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
1756{ 1765{
1757 unsigned int i, num = 0, announced = 0; 1766 unsigned int i, num = 0, announced = 0;
1758 1767
1759 if (is_timeout(onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) { 1768 if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
1760 return 0; 1769 return 0;
1761 } 1770 }
1762 1771
@@ -1765,7 +1774,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
1765 } 1774 }
1766 1775
1767 for (i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) { 1776 for (i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
1768 if (!onion_node_timed_out(&onion_c->clients_announce_list[i])) { 1777 if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) {
1769 ++num; 1778 ++num;
1770 1779
1771 if (onion_c->clients_announce_list[i].is_stored) { 1780 if (onion_c->clients_announce_list[i].is_stored) {
@@ -1812,11 +1821,11 @@ unsigned int onion_connection_status(const Onion_Client *onion_c)
1812 1821
1813void do_onion_client(Onion_Client *onion_c) 1822void do_onion_client(Onion_Client *onion_c)
1814{ 1823{
1815 if (onion_c->last_run == unix_time()) { 1824 if (onion_c->last_run == mono_time_get(onion_c->mono_time)) {
1816 return; 1825 return;
1817 } 1826 }
1818 1827
1819 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) { 1828 if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS)) {
1820 populate_path_nodes(onion_c); 1829 populate_path_nodes(onion_c);
1821 do_announce(onion_c); 1830 do_announce(onion_c);
1822 } 1831 }
@@ -1835,7 +1844,7 @@ void do_onion_client(Onion_Client *onion_c)
1835 1844
1836 bool udp_connected = dht_non_lan_connected(onion_c->dht); 1845 bool udp_connected = dht_non_lan_connected(onion_c->dht);
1837 1846
1838 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) { 1847 if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) {
1839 set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !udp_connected); 1848 set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !udp_connected);
1840 } 1849 }
1841 1850
@@ -1849,13 +1858,13 @@ void do_onion_client(Onion_Client *onion_c)
1849 } 1858 }
1850 1859
1851 if (onion_c->last_run == 0) { 1860 if (onion_c->last_run == 0) {
1852 onion_c->first_run = unix_time(); 1861 onion_c->first_run = mono_time_get(onion_c->mono_time);
1853 } 1862 }
1854 1863
1855 onion_c->last_run = unix_time(); 1864 onion_c->last_run = mono_time_get(onion_c->mono_time);
1856} 1865}
1857 1866
1858Onion_Client *new_onion_client(Net_Crypto *c) 1867Onion_Client *new_onion_client(Mono_Time *mono_time, Net_Crypto *c)
1859{ 1868{
1860 if (c == nullptr) { 1869 if (c == nullptr) {
1861 return nullptr; 1870 return nullptr;
@@ -1874,6 +1883,7 @@ Onion_Client *new_onion_client(Net_Crypto *c)
1874 return nullptr; 1883 return nullptr;
1875 } 1884 }
1876 1885
1886 onion_c->mono_time = mono_time;
1877 onion_c->dht = nc_get_dht(c); 1887 onion_c->dht = nc_get_dht(c);
1878 onion_c->net = dht_get_net(onion_c->dht); 1888 onion_c->net = dht_get_net(onion_c->dht);
1879 onion_c->c = c; 1889 onion_c->c = c;