summaryrefslogtreecommitdiff
path: root/toxcore/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r--toxcore/DHT.c201
1 files changed, 110 insertions, 91 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 94928b75..46db6e76 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -93,6 +93,7 @@ typedef struct Cryptopacket_Handler {
93 93
94struct DHT { 94struct DHT {
95 const Logger *log; 95 const Logger *log;
96 Mono_Time *mono_time;
96 Networking_Core *net; 97 Networking_Core *net;
97 98
98 bool hole_punching_enabled; 99 bool hole_punching_enabled;
@@ -243,7 +244,8 @@ static unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2)
243 * If shared key is already in shared_keys, copy it to shared_key. 244 * If shared key is already in shared_keys, copy it to shared_key.
244 * else generate it into shared_key and copy it to shared_keys 245 * else generate it into shared_key and copy it to shared_keys
245 */ 246 */
246void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t *secret_key, const uint8_t *public_key) 247void get_shared_key(const Mono_Time *mono_time, Shared_Keys *shared_keys, uint8_t *shared_key,
248 const uint8_t *secret_key, const uint8_t *public_key)
247{ 249{
248 uint32_t num = ~0; 250 uint32_t num = ~0;
249 uint32_t curr = 0; 251 uint32_t curr = 0;
@@ -256,12 +258,12 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
256 if (id_equal(public_key, key->public_key)) { 258 if (id_equal(public_key, key->public_key)) {
257 memcpy(shared_key, key->shared_key, CRYPTO_SHARED_KEY_SIZE); 259 memcpy(shared_key, key->shared_key, CRYPTO_SHARED_KEY_SIZE);
258 ++key->times_requested; 260 ++key->times_requested;
259 key->time_last_requested = unix_time(); 261 key->time_last_requested = mono_time_get(mono_time);
260 return; 262 return;
261 } 263 }
262 264
263 if (num != 0) { 265 if (num != 0) {
264 if (is_timeout(key->time_last_requested, KEYS_TIMEOUT)) { 266 if (mono_time_is_timeout(mono_time, key->time_last_requested, KEYS_TIMEOUT)) {
265 num = 0; 267 num = 0;
266 curr = index; 268 curr = index;
267 } else if (num > key->times_requested) { 269 } else if (num > key->times_requested) {
@@ -283,7 +285,7 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
283 key->times_requested = 1; 285 key->times_requested = 1;
284 memcpy(key->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); 286 memcpy(key->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
285 memcpy(key->shared_key, shared_key, CRYPTO_SHARED_KEY_SIZE); 287 memcpy(key->shared_key, shared_key, CRYPTO_SHARED_KEY_SIZE);
286 key->time_last_requested = unix_time(); 288 key->time_last_requested = mono_time_get(mono_time);
287 } 289 }
288} 290}
289 291
@@ -292,7 +294,7 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
292 */ 294 */
293void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key) 295void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key)
294{ 296{
295 get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, public_key); 297 get_shared_key(dht->mono_time, &dht->shared_keys_recv, shared_key, dht->self_secret_key, public_key);
296} 298}
297 299
298/* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key 300/* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
@@ -300,7 +302,7 @@ void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *publi
300 */ 302 */
301void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key) 303void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key)
302{ 304{
303 get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, public_key); 305 get_shared_key(dht->mono_time, &dht->shared_keys_sent, shared_key, dht->self_secret_key, public_key);
304} 306}
305 307
306#define CRYPTO_SIZE 1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE 308#define CRYPTO_SIZE 1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE
@@ -667,7 +669,8 @@ static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size,
667 669
668/* Update ip_port of client if it's needed. 670/* Update ip_port of client if it's needed.
669 */ 671 */
670static void update_client(const Logger *log, int index, Client_data *client, IP_Port ip_port) 672static void update_client(const Logger *log, const Mono_Time *mono_time, int index, Client_data *client,
673 IP_Port ip_port)
671{ 674{
672 IPPTsPng *assoc; 675 IPPTsPng *assoc;
673 int ip_version; 676 int ip_version;
@@ -697,7 +700,7 @@ static void update_client(const Logger *log, int index, Client_data *client, IP_
697 } 700 }
698 701
699 assoc->ip_port = ip_port; 702 assoc->ip_port = ip_port;
700 assoc->timestamp = unix_time(); 703 assoc->timestamp = mono_time_get(mono_time);
701} 704}
702 705
703/* Check if client with public_key is already in list of length length. 706/* Check if client with public_key is already in list of length length.
@@ -707,15 +710,15 @@ static void update_client(const Logger *log, int index, Client_data *client, IP_
707 * 710 *
708 * return True(1) or False(0) 711 * return True(1) or False(0)
709 */ 712 */
710static int client_or_ip_port_in_list(const Logger *log, Client_data *list, uint16_t length, const uint8_t *public_key, 713static int client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_time, Client_data *list, uint16_t length,
711 IP_Port ip_port) 714 const uint8_t *public_key, IP_Port ip_port)
712{ 715{
713 const uint64_t temp_time = unix_time(); 716 const uint64_t temp_time = mono_time_get(mono_time);
714 uint32_t index = index_of_client_pk(list, length, public_key); 717 uint32_t index = index_of_client_pk(list, length, public_key);
715 718
716 /* if public_key is in list, find it and maybe overwrite ip_port */ 719 /* if public_key is in list, find it and maybe overwrite ip_port */
717 if (index != UINT32_MAX) { 720 if (index != UINT32_MAX) {
718 update_client(log, index, &list[index], ip_port); 721 update_client(log, mono_time, index, &list[index], ip_port);
719 return 1; 722 return 1;
720 } 723 }
721 724
@@ -793,7 +796,7 @@ static uint8_t hardening_correct(const Hardening *h)
793/* 796/*
794 * helper for get_close_nodes(). argument list is a monster :D 797 * helper for get_close_nodes(). argument list is a monster :D
795 */ 798 */
796static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_list, 799static void get_close_nodes_inner(const Mono_Time *mono_time, const uint8_t *public_key, Node_format *nodes_list,
797 Family sa_family, const Client_data *client_list, uint32_t client_list_length, 800 Family sa_family, const Client_data *client_list, uint32_t client_list_length,
798 uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good) 801 uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good)
799{ 802{
@@ -824,7 +827,7 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_
824 } 827 }
825 828
826 /* node not in a good condition? */ 829 /* node not in a good condition? */
827 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) { 830 if (mono_time_is_timeout(mono_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) {
828 continue; 831 continue;
829 } 832 }
830 833
@@ -862,14 +865,14 @@ static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, N
862 Family sa_family, uint8_t is_LAN, uint8_t want_good) 865 Family sa_family, uint8_t is_LAN, uint8_t want_good)
863{ 866{
864 uint32_t num_nodes = 0; 867 uint32_t num_nodes = 0;
865 get_close_nodes_inner(public_key, nodes_list, sa_family, 868 get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
866 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, 0); 869 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, 0);
867 870
868 /* TODO(irungentoo): uncomment this when hardening is added to close friend clients */ 871 /* TODO(irungentoo): uncomment this when hardening is added to close friend clients */
869#if 0 872#if 0
870 873
871 for (uint32_t i = 0; i < dht->num_friends; ++i) { 874 for (uint32_t i = 0; i < dht->num_friends; ++i) {
872 get_close_nodes_inner(dht, public_key, nodes_list, sa_family, 875 get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
873 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 876 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
874 &num_nodes, is_LAN, want_good); 877 &num_nodes, is_LAN, want_good);
875 } 878 }
@@ -877,7 +880,7 @@ static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, N
877#endif 880#endif
878 881
879 for (uint32_t i = 0; i < dht->num_friends; ++i) { 882 for (uint32_t i = 0; i < dht->num_friends; ++i) {
880 get_close_nodes_inner(public_key, nodes_list, sa_family, 883 get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
881 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 884 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
882 &num_nodes, is_LAN, 0); 885 &num_nodes, is_LAN, 0);
883 } 886 }
@@ -893,13 +896,14 @@ int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *node
893} 896}
894 897
895typedef struct DHT_Cmp_data { 898typedef struct DHT_Cmp_data {
899 const Mono_Time *mono_time;
896 const uint8_t *base_public_key; 900 const uint8_t *base_public_key;
897 Client_data entry; 901 Client_data entry;
898} DHT_Cmp_data; 902} DHT_Cmp_data;
899 903
900static bool assoc_timeout(const IPPTsPng *assoc) 904static bool assoc_timeout(const Mono_Time *mono_time, const IPPTsPng *assoc)
901{ 905{
902 return is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT); 906 return mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT);
903} 907}
904 908
905static bool incorrect_hardening(const IPPTsPng *assoc) 909static bool incorrect_hardening(const IPPTsPng *assoc)
@@ -916,8 +920,8 @@ static int cmp_dht_entry(const void *a, const void *b)
916 const Client_data entry2 = cmp2.entry; 920 const Client_data entry2 = cmp2.entry;
917 const uint8_t *cmp_public_key = cmp1.base_public_key; 921 const uint8_t *cmp_public_key = cmp1.base_public_key;
918 922
919 bool t1 = assoc_timeout(&entry1.assoc4) && assoc_timeout(&entry1.assoc6); 923 bool t1 = assoc_timeout(cmp1.mono_time, &entry1.assoc4) && assoc_timeout(cmp1.mono_time, &entry1.assoc6);
920 bool t2 = assoc_timeout(&entry2.assoc4) && assoc_timeout(&entry2.assoc6); 924 bool t2 = assoc_timeout(cmp2.mono_time, &entry2.assoc4) && assoc_timeout(cmp2.mono_time, &entry2.assoc6);
921 925
922 if (t1 && t2) { 926 if (t1 && t2) {
923 return 0; 927 return 0;
@@ -960,20 +964,23 @@ static int cmp_dht_entry(const void *a, const void *b)
960 * return 0 if node can't be stored. 964 * return 0 if node can't be stored.
961 * return 1 if it can. 965 * return 1 if it can.
962 */ 966 */
963static unsigned int store_node_ok(const Client_data *client, const uint8_t *public_key, const uint8_t *comp_public_key) 967static unsigned int store_node_ok(const Client_data *client, const Mono_Time *mono_time, const uint8_t *public_key,
968 const uint8_t *comp_public_key)
964{ 969{
965 return (is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) 970 return (mono_time_is_timeout(mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)
966 && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) 971 && mono_time_is_timeout(mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT))
967 || id_closest(comp_public_key, client->public_key, public_key) == 2; 972 || id_closest(comp_public_key, client->public_key, public_key) == 2;
968} 973}
969 974
970static void sort_client_list(Client_data *list, unsigned int length, const uint8_t *comp_public_key) 975static void sort_client_list(Client_data *list, const Mono_Time *mono_time, unsigned int length,
976 const uint8_t *comp_public_key)
971{ 977{
972 // Pass comp_public_key to qsort with each Client_data entry, so the 978 // Pass comp_public_key to qsort with each Client_data entry, so the
973 // comparison function can use it as the base of comparison. 979 // comparison function can use it as the base of comparison.
974 VLA(DHT_Cmp_data, cmp_list, length); 980 VLA(DHT_Cmp_data, cmp_list, length);
975 981
976 for (uint32_t i = 0; i < length; ++i) { 982 for (uint32_t i = 0; i < length; ++i) {
983 cmp_list[i].mono_time = mono_time;
977 cmp_list[i].base_public_key = comp_public_key; 984 cmp_list[i].base_public_key = comp_public_key;
978 cmp_list[i].entry = list[i]; 985 cmp_list[i].entry = list[i];
979 } 986 }
@@ -985,7 +992,7 @@ static void sort_client_list(Client_data *list, unsigned int length, const uint8
985 } 992 }
986} 993}
987 994
988static void update_client_with_reset(Client_data *client, const IP_Port *ip_port) 995static void update_client_with_reset(const Mono_Time *mono_time, Client_data *client, const IP_Port *ip_port)
989{ 996{
990 IPPTsPng *ipptp_write = nullptr; 997 IPPTsPng *ipptp_write = nullptr;
991 IPPTsPng *ipptp_clear = nullptr; 998 IPPTsPng *ipptp_clear = nullptr;
@@ -999,7 +1006,7 @@ static void update_client_with_reset(Client_data *client, const IP_Port *ip_port
999 } 1006 }
1000 1007
1001 ipptp_write->ip_port = *ip_port; 1008 ipptp_write->ip_port = *ip_port;
1002 ipptp_write->timestamp = unix_time(); 1009 ipptp_write->timestamp = mono_time_get(mono_time);
1003 1010
1004 ip_reset(&ipptp_write->ret_ip_port.ip); 1011 ip_reset(&ipptp_write->ret_ip_port.ip);
1005 ipptp_write->ret_ip_port.port = 0; 1012 ipptp_write->ret_ip_port.port = 0;
@@ -1022,7 +1029,8 @@ static void update_client_with_reset(Client_data *client, const IP_Port *ip_port
1022 * than public_key. 1029 * than public_key.
1023 * 1030 *
1024 * returns true when the item was stored, false otherwise */ 1031 * returns true when the item was stored, false otherwise */
1025static bool replace_all(Client_data *list, 1032static bool replace_all(const Mono_Time *mono_time,
1033 Client_data *list,
1026 uint16_t length, 1034 uint16_t length,
1027 const uint8_t *public_key, 1035 const uint8_t *public_key,
1028 IP_Port ip_port, 1036 IP_Port ip_port,
@@ -1032,17 +1040,17 @@ static bool replace_all(Client_data *list,
1032 return false; 1040 return false;
1033 } 1041 }
1034 1042
1035 if (!store_node_ok(&list[1], public_key, comp_public_key) && 1043 if (!store_node_ok(&list[1], mono_time, public_key, comp_public_key) &&
1036 !store_node_ok(&list[0], public_key, comp_public_key)) { 1044 !store_node_ok(&list[0], mono_time, public_key, comp_public_key)) {
1037 return false; 1045 return false;
1038 } 1046 }
1039 1047
1040 sort_client_list(list, length, comp_public_key); 1048 sort_client_list(list, mono_time, length, comp_public_key);
1041 1049
1042 Client_data *const client = &list[0]; 1050 Client_data *const client = &list[0];
1043 id_copy(client->public_key, public_key); 1051 id_copy(client->public_key, public_key);
1044 1052
1045 update_client_with_reset(client, &ip_port); 1053 update_client_with_reset(mono_time, client, &ip_port);
1046 return true; 1054 return true;
1047} 1055}
1048 1056
@@ -1066,8 +1074,8 @@ static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, bo
1066 * index is left as >= LCLIENT_LENGTH */ 1074 * index is left as >= LCLIENT_LENGTH */
1067 Client_data *const client = &dht->close_clientlist[(index * LCLIENT_NODES) + i]; 1075 Client_data *const client = &dht->close_clientlist[(index * LCLIENT_NODES) + i];
1068 1076
1069 if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) || 1077 if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
1070 !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { 1078 !mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) {
1071 continue; 1079 continue;
1072 } 1080 }
1073 1081
@@ -1076,7 +1084,7 @@ static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, bo
1076 } 1084 }
1077 1085
1078 id_copy(client->public_key, public_key); 1086 id_copy(client->public_key, public_key);
1079 update_client_with_reset(client, &ip_port); 1087 update_client_with_reset(dht->mono_time, client, &ip_port);
1080 return 0; 1088 return 0;
1081 } 1089 }
1082 1090
@@ -1090,8 +1098,8 @@ bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
1090 return add_to_close(dht, public_key, ip_port, 1) == 0; 1098 return add_to_close(dht, public_key, ip_port, 1) == 0;
1091} 1099}
1092 1100
1093static bool is_pk_in_client_list(const Client_data *list, unsigned int client_list_length, const uint8_t *public_key, 1101static bool is_pk_in_client_list(const Client_data *list, unsigned int client_list_length, const Mono_Time *mono_time,
1094 IP_Port ip_port) 1102 const uint8_t *public_key, IP_Port ip_port)
1095{ 1103{
1096 const uint32_t index = index_of_client_pk(list, client_list_length, public_key); 1104 const uint32_t index = index_of_client_pk(list, client_list_length, public_key);
1097 1105
@@ -1103,7 +1111,7 @@ static bool is_pk_in_client_list(const Client_data *list, unsigned int client_li
1103 ? &list[index].assoc4 1111 ? &list[index].assoc4
1104 : &list[index].assoc6; 1112 : &list[index].assoc6;
1105 1113
1106 return !is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT); 1114 return !mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT);
1107} 1115}
1108 1116
1109static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port) 1117static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port)
@@ -1114,7 +1122,8 @@ static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
1114 index = LCLIENT_LENGTH - 1; 1122 index = LCLIENT_LENGTH - 1;
1115 } 1123 }
1116 1124
1117 return is_pk_in_client_list(dht->close_clientlist + index * LCLIENT_NODES, LCLIENT_NODES, public_key, ip_port); 1125 return is_pk_in_client_list(dht->close_clientlist + index * LCLIENT_NODES, LCLIENT_NODES, dht->mono_time, public_key,
1126 ip_port);
1118} 1127}
1119 1128
1120/* Check if the node obtained with a get_nodes with public_key should be pinged. 1129/* Check if the node obtained with a get_nodes with public_key should be pinged.
@@ -1153,17 +1162,18 @@ static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, IP_P
1153 1162
1154 bool store_ok = false; 1163 bool store_ok = false;
1155 1164
1156 if (store_node_ok(&dht_friend->client_list[1], public_key, dht_friend->public_key)) { 1165 if (store_node_ok(&dht_friend->client_list[1], dht->mono_time, public_key, dht_friend->public_key)) {
1157 store_ok = true; 1166 store_ok = true;
1158 } 1167 }
1159 1168
1160 if (store_node_ok(&dht_friend->client_list[0], public_key, dht_friend->public_key)) { 1169 if (store_node_ok(&dht_friend->client_list[0], dht->mono_time, public_key, dht_friend->public_key)) {
1161 store_ok = true; 1170 store_ok = true;
1162 } 1171 }
1163 1172
1164 unsigned int *const friend_num = &dht_friend->num_to_bootstrap; 1173 unsigned int *const friend_num = &dht_friend->num_to_bootstrap;
1165 const uint32_t index = index_of_node_pk(dht_friend->to_bootstrap, *friend_num, public_key); 1174 const uint32_t index = index_of_node_pk(dht_friend->to_bootstrap, *friend_num, public_key);
1166 const bool pk_in_list = is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, public_key, ip_port); 1175 const bool pk_in_list = is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, dht->mono_time, public_key,
1176 ip_port);
1167 1177
1168 if (store_ok && index == UINT32_MAX && !pk_in_list) { 1178 if (store_ok && index == UINT32_MAX && !pk_in_list) {
1169 if (*friend_num < MAX_SENT_NODES) { 1179 if (*friend_num < MAX_SENT_NODES) {
@@ -1200,8 +1210,8 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
1200 /* NOTE: Current behavior if there are two clients with the same id is 1210 /* NOTE: Current behavior if there are two clients with the same id is
1201 * to replace the first ip by the second. 1211 * to replace the first ip by the second.
1202 */ 1212 */
1203 const bool in_close_list = client_or_ip_port_in_list(dht->log, dht->close_clientlist, 1213 const bool in_close_list = client_or_ip_port_in_list(dht->log, dht->mono_time, dht->close_clientlist, LCLIENT_LIST,
1204 LCLIENT_LIST, public_key, ip_port); 1214 public_key, ip_port);
1205 1215
1206 /* add_to_close should be called only if !in_list (don't extract to variable) */ 1216 /* add_to_close should be called only if !in_list (don't extract to variable) */
1207 if (in_close_list || add_to_close(dht, public_key, ip_port, 0)) { 1217 if (in_close_list || add_to_close(dht, public_key, ip_port, 0)) {
@@ -1211,12 +1221,13 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
1211 DHT_Friend *friend_foundip = nullptr; 1221 DHT_Friend *friend_foundip = nullptr;
1212 1222
1213 for (uint32_t i = 0; i < dht->num_friends; ++i) { 1223 for (uint32_t i = 0; i < dht->num_friends; ++i) {
1214 const bool in_list = client_or_ip_port_in_list(dht->log, dht->friends_list[i].client_list, 1224 const bool in_list = client_or_ip_port_in_list(dht->log, dht->mono_time, dht->friends_list[i].client_list,
1215 MAX_FRIEND_CLIENTS, public_key, ip_port); 1225 MAX_FRIEND_CLIENTS, public_key, ip_port);
1216 1226
1217 /* replace_all should be called only if !in_list (don't extract to variable) */ 1227 /* replace_all should be called only if !in_list (don't extract to variable) */
1218 if (in_list || replace_all(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, public_key, 1228 if (in_list
1219 ip_port, dht->friends_list[i].public_key)) { 1229 || replace_all(dht->mono_time, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, public_key, ip_port,
1230 dht->friends_list[i].public_key)) {
1220 DHT_Friend *dht_friend = &dht->friends_list[i]; 1231 DHT_Friend *dht_friend = &dht->friends_list[i];
1221 1232
1222 if (id_equal(public_key, dht_friend->public_key)) { 1233 if (id_equal(public_key, dht_friend->public_key)) {
@@ -1241,9 +1252,10 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
1241 return used; 1252 return used;
1242} 1253}
1243 1254
1244static bool update_client_data(Client_data *array, size_t size, IP_Port ip_port, const uint8_t *pk) 1255static bool update_client_data(const Mono_Time *mono_time, Client_data *array, size_t size, IP_Port ip_port,
1256 const uint8_t *pk)
1245{ 1257{
1246 const uint64_t temp_time = unix_time(); 1258 const uint64_t temp_time = mono_time_get(mono_time);
1247 const uint32_t index = index_of_client_pk(array, size, pk); 1259 const uint32_t index = index_of_client_pk(array, size, pk);
1248 1260
1249 if (index == UINT32_MAX) { 1261 if (index == UINT32_MAX) {
@@ -1278,7 +1290,7 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_ke
1278 } 1290 }
1279 1291
1280 if (id_equal(public_key, dht->self_public_key)) { 1292 if (id_equal(public_key, dht->self_public_key)) {
1281 update_client_data(dht->close_clientlist, LCLIENT_LIST, ip_port, nodepublic_key); 1293 update_client_data(dht->mono_time, dht->close_clientlist, LCLIENT_LIST, ip_port, nodepublic_key);
1282 return; 1294 return;
1283 } 1295 }
1284 1296
@@ -1286,7 +1298,7 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_ke
1286 if (id_equal(public_key, dht->friends_list[i].public_key)) { 1298 if (id_equal(public_key, dht->friends_list[i].public_key)) {
1287 Client_data *const client_list = dht->friends_list[i].client_list; 1299 Client_data *const client_list = dht->friends_list[i].client_list;
1288 1300
1289 if (update_client_data(client_list, MAX_FRIEND_CLIENTS, ip_port, nodepublic_key)) { 1301 if (update_client_data(dht->mono_time, client_list, MAX_FRIEND_CLIENTS, ip_port, nodepublic_key)) {
1290 return; 1302 return;
1291 } 1303 }
1292 } 1304 }
@@ -1314,9 +1326,9 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const
1314 1326
1315 if (sendback_node != nullptr) { 1327 if (sendback_node != nullptr) {
1316 memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format)); 1328 memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format));
1317 ping_id = ping_array_add(dht->dht_harden_ping_array, plain_message, sizeof(plain_message)); 1329 ping_id = ping_array_add(dht->dht_harden_ping_array, dht->mono_time, plain_message, sizeof(plain_message));
1318 } else { 1330 } else {
1319 ping_id = ping_array_add(dht->dht_ping_array, plain_message, sizeof(receiver)); 1331 ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
1320 } 1332 }
1321 1333
1322 if (ping_id == 0) { 1334 if (ping_id == 0) {
@@ -1433,9 +1445,9 @@ static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port no
1433{ 1445{
1434 uint8_t data[sizeof(Node_format) * 2]; 1446 uint8_t data[sizeof(Node_format) * 2];
1435 1447
1436 if (ping_array_check(dht->dht_ping_array, data, sizeof(data), ping_id) == sizeof(Node_format)) { 1448 if (ping_array_check(dht->dht_ping_array, dht->mono_time, data, sizeof(data), ping_id) == sizeof(Node_format)) {
1437 memset(sendback_node, 0, sizeof(Node_format)); 1449 memset(sendback_node, 0, sizeof(Node_format));
1438 } else if (ping_array_check(dht->dht_harden_ping_array, data, sizeof(data), ping_id) == sizeof(data)) { 1450 } else if (ping_array_check(dht->dht_harden_ping_array, dht->mono_time, data, sizeof(data), ping_id) == sizeof(data)) {
1439 memcpy(sendback_node, data + sizeof(Node_format), sizeof(Node_format)); 1451 memcpy(sendback_node, data + sizeof(Node_format), sizeof(Node_format));
1440 } else { 1452 } else {
1441 return false; 1453 return false;
@@ -1678,7 +1690,7 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
1678 for (const IPPTsPng * const *it = assocs; *it; ++it) { 1690 for (const IPPTsPng * const *it = assocs; *it; ++it) {
1679 const IPPTsPng *const assoc = *it; 1691 const IPPTsPng *const assoc = *it;
1680 1692
1681 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) { 1693 if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
1682 *ip_port = assoc->ip_port; 1694 *ip_port = assoc->ip_port;
1683 return 1; 1695 return 1;
1684 } 1696 }
@@ -1692,7 +1704,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
1692 Client_data *list, uint32_t list_count, uint32_t *bootstrap_times, bool sortable) 1704 Client_data *list, uint32_t list_count, uint32_t *bootstrap_times, bool sortable)
1693{ 1705{
1694 uint8_t not_kill = 0; 1706 uint8_t not_kill = 0;
1695 const uint64_t temp_time = unix_time(); 1707 const uint64_t temp_time = mono_time_get(dht->mono_time);
1696 1708
1697 uint32_t num_nodes = 0; 1709 uint32_t num_nodes = 0;
1698 VLA(Client_data *, client_list, list_count * 2); 1710 VLA(Client_data *, client_list, list_count * 2);
@@ -1709,17 +1721,17 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
1709 for (uint32_t j = 0; j < sizeof(assocs) / sizeof(assocs[0]); ++j) { 1721 for (uint32_t j = 0; j < sizeof(assocs) / sizeof(assocs[0]); ++j) {
1710 IPPTsPng *const assoc = assocs[j]; 1722 IPPTsPng *const assoc = assocs[j];
1711 1723
1712 if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) { 1724 if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, KILL_NODE_TIMEOUT)) {
1713 sort = 0; 1725 sort = 0;
1714 ++not_kill; 1726 ++not_kill;
1715 1727
1716 if (is_timeout(assoc->last_pinged, PING_INTERVAL)) { 1728 if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
1717 getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr); 1729 getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr);
1718 assoc->last_pinged = temp_time; 1730 assoc->last_pinged = temp_time;
1719 } 1731 }
1720 1732
1721 /* If node is good. */ 1733 /* If node is good. */
1722 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) { 1734 if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
1723 client_list[num_nodes] = client; 1735 client_list[num_nodes] = client;
1724 assoc_list[num_nodes] = assoc; 1736 assoc_list[num_nodes] = assoc;
1725 ++num_nodes; 1737 ++num_nodes;
@@ -1736,10 +1748,11 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
1736 } 1748 }
1737 1749
1738 if (sortable && sort_ok) { 1750 if (sortable && sort_ok) {
1739 sort_client_list(list, list_count, public_key); 1751 sort_client_list(list, dht->mono_time, list_count, public_key);
1740 } 1752 }
1741 1753
1742 if ((num_nodes != 0) && (is_timeout(*lastgetnode, GET_NODE_INTERVAL) || *bootstrap_times < MAX_BOOTSTRAP_TIMES)) { 1754 if ((num_nodes != 0) && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
1755 || *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
1743 uint32_t rand_node = random_u32() % num_nodes; 1756 uint32_t rand_node = random_u32() % num_nodes;
1744 1757
1745 if ((num_nodes - 1) != rand_node) { 1758 if ((num_nodes - 1) != rand_node) {
@@ -1801,7 +1814,7 @@ static void do_Close(DHT *dht)
1801 * 1814 *
1802 * so: reset all nodes to be BAD_NODE_TIMEOUT, but not 1815 * so: reset all nodes to be BAD_NODE_TIMEOUT, but not
1803 * KILL_NODE_TIMEOUT, so we at least keep trying pings */ 1816 * KILL_NODE_TIMEOUT, so we at least keep trying pings */
1804 const uint64_t badonly = unix_time() - BAD_NODE_TIMEOUT; 1817 const uint64_t badonly = mono_time_get(dht->mono_time) - BAD_NODE_TIMEOUT;
1805 1818
1806 for (size_t i = 0; i < LCLIENT_LIST; ++i) { 1819 for (size_t i = 0; i < LCLIENT_LIST; ++i) {
1807 Client_data *const client = &dht->close_clientlist[i]; 1820 Client_data *const client = &dht->close_clientlist[i];
@@ -1906,19 +1919,21 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
1906 const Client_data *const client = &dht_friend->client_list[i]; 1919 const Client_data *const client = &dht_friend->client_list[i];
1907 1920
1908 /* If ip is not zero and node is good. */ 1921 /* If ip is not zero and node is good. */
1909 if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) { 1922 if (ip_isset(&client->assoc4.ret_ip_port.ip)
1923 && !mono_time_is_timeout(dht->mono_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
1910 ipv4s[num_ipv4s] = client->assoc4.ret_ip_port; 1924 ipv4s[num_ipv4s] = client->assoc4.ret_ip_port;
1911 ++num_ipv4s; 1925 ++num_ipv4s;
1912 } 1926 }
1913 1927
1914 if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) { 1928 if (ip_isset(&client->assoc6.ret_ip_port.ip)
1929 && !mono_time_is_timeout(dht->mono_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
1915 ipv6s[num_ipv6s] = client->assoc6.ret_ip_port; 1930 ipv6s[num_ipv6s] = client->assoc6.ret_ip_port;
1916 ++num_ipv6s; 1931 ++num_ipv6s;
1917 } 1932 }
1918 1933
1919 if (id_equal(client->public_key, dht_friend->public_key)) { 1934 if (id_equal(client->public_key, dht_friend->public_key)) {
1920 if (!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT) 1935 if (!mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)
1921 || !is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT)) { 1936 || !mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)) {
1922 return 0; /* direct connectivity */ 1937 return 0; /* direct connectivity */
1923 } 1938 }
1924 } 1939 }
@@ -1997,7 +2012,7 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
1997 const IPPTsPng *const assoc = *it; 2012 const IPPTsPng *const assoc = *it;
1998 2013
1999 /* If ip is not zero and node is good. */ 2014 /* If ip is not zero and node is good. */
2000 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 2015 if (ip_isset(&assoc->ret_ip_port.ip) && !mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
2001 const int retval = sendpacket(dht->net, assoc->ip_port, packet, length); 2016 const int retval = sendpacket(dht->net, assoc->ip_port, packet, length);
2002 2017
2003 if ((unsigned int)retval == length) { 2018 if ((unsigned int)retval == length) {
@@ -2039,7 +2054,7 @@ static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *
2039 const IPPTsPng *const assoc = *it; 2054 const IPPTsPng *const assoc = *it;
2040 2055
2041 /* If ip is not zero and node is good. */ 2056 /* If ip is not zero and node is good. */
2042 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 2057 if (ip_isset(&assoc->ret_ip_port.ip) && !mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
2043 ip_list[n] = assoc->ip_port; 2058 ip_list[n] = assoc->ip_port;
2044 ++n; 2059 ++n;
2045 } 2060 }
@@ -2116,7 +2131,7 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu
2116 if (packet[0] == NAT_PING_REQUEST) { 2131 if (packet[0] == NAT_PING_REQUEST) {
2117 /* 1 is reply */ 2132 /* 1 is reply */
2118 send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE); 2133 send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE);
2119 dht_friend->nat.recv_nat_ping_timestamp = unix_time(); 2134 dht_friend->nat.recv_nat_ping_timestamp = mono_time_get(dht->mono_time);
2120 return 0; 2135 return 0;
2121 } 2136 }
2122 2137
@@ -2243,7 +2258,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
2243 2258
2244static void do_NAT(DHT *dht) 2259static void do_NAT(DHT *dht)
2245{ 2260{
2246 const uint64_t temp_time = unix_time(); 2261 const uint64_t temp_time = mono_time_get(dht->mono_time);
2247 2262
2248 for (uint32_t i = 0; i < dht->num_friends; ++i) { 2263 for (uint32_t i = 0; i < dht->num_friends; ++i) {
2249 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 2264 IP_Port ip_list[MAX_FRIEND_CLIENTS];
@@ -2393,7 +2408,7 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
2393 const IPPTsPng *const temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family); 2408 const IPPTsPng *const temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family);
2394 2409
2395 if (temp) { 2410 if (temp) {
2396 if (!is_timeout(temp->timestamp, BAD_NODE_TIMEOUT)) { 2411 if (!mono_time_is_timeout(dht->mono_time, temp->timestamp, BAD_NODE_TIMEOUT)) {
2397 ++counter; 2412 ++counter;
2398 } 2413 }
2399 } 2414 }
@@ -2464,7 +2479,7 @@ static int handle_hardening(void *object, IP_Port source, const uint8_t *source_
2464 return 1; 2479 return 1;
2465 } 2480 }
2466 2481
2467 if (is_timeout(temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) { 2482 if (mono_time_is_timeout(dht->mono_time, temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
2468 return 1; 2483 return 1;
2469 } 2484 }
2470 2485
@@ -2512,7 +2527,8 @@ static Node_format random_node(DHT *dht, Family sa_family)
2512 * 2527 *
2513 * return the number of nodes. 2528 * return the number of nodes.
2514 */ 2529 */
2515static uint16_t list_nodes(Client_data *list, size_t length, Node_format *nodes, uint16_t max_num) 2530static uint16_t list_nodes(Client_data *list, size_t length, const Mono_Time *mono_time, Node_format *nodes,
2531 uint16_t max_num)
2516{ 2532{
2517 if (max_num == 0) { 2533 if (max_num == 0) {
2518 return 0; 2534 return 0;
@@ -2523,11 +2539,11 @@ static uint16_t list_nodes(Client_data *list, size_t length, Node_format *nodes,
2523 for (size_t i = length; i != 0; --i) { 2539 for (size_t i = length; i != 0; --i) {
2524 const IPPTsPng *assoc = nullptr; 2540 const IPPTsPng *assoc = nullptr;
2525 2541
2526 if (!is_timeout(list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT)) { 2542 if (!mono_time_is_timeout(mono_time, list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT)) {
2527 assoc = &list[i - 1].assoc4; 2543 assoc = &list[i - 1].assoc4;
2528 } 2544 }
2529 2545
2530 if (!is_timeout(list[i - 1].assoc6.timestamp, BAD_NODE_TIMEOUT)) { 2546 if (!mono_time_is_timeout(mono_time, list[i - 1].assoc6.timestamp, BAD_NODE_TIMEOUT)) {
2531 if (assoc == nullptr) { 2547 if (assoc == nullptr) {
2532 assoc = &list[i - 1].assoc6; 2548 assoc = &list[i - 1].assoc6;
2533 } else if (random_u08() % 2) { 2549 } else if (random_u08() % 2) {
@@ -2563,8 +2579,8 @@ uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2563 const uint32_t r = random_u32(); 2579 const uint32_t r = random_u32();
2564 2580
2565 for (size_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) { 2581 for (size_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
2566 count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, nodes + count, 2582 count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, dht->mono_time,
2567 max_num - count); 2583 nodes + count, max_num - count);
2568 2584
2569 if (count >= max_num) { 2585 if (count >= max_num) {
2570 break; 2586 break;
@@ -2580,7 +2596,7 @@ uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2580 */ 2596 */
2581uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num) 2597uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
2582{ 2598{
2583 return list_nodes(dht->close_clientlist, LCLIENT_LIST, nodes, max_num); 2599 return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->mono_time, nodes, max_num);
2584} 2600}
2585 2601
2586#if DHT_HARDENING 2602#if DHT_HARDENING
@@ -2599,12 +2615,12 @@ static void do_hardening(DHT *dht)
2599 sa_family = net_family_ipv6; 2615 sa_family = net_family_ipv6;
2600 } 2616 }
2601 2617
2602 if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) { 2618 if (mono_time_is_timeout(dht->mono_time, cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) {
2603 continue; 2619 continue;
2604 } 2620 }
2605 2621
2606 if (cur_iptspng->hardening.send_nodes_ok == 0) { 2622 if (cur_iptspng->hardening.send_nodes_ok == 0) {
2607 if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) { 2623 if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
2608 Node_format rand_node = random_node(dht, sa_family); 2624 Node_format rand_node = random_node(dht, sa_family);
2609 2625
2610 if (!ipport_isset(&rand_node.ip_port)) { 2626 if (!ipport_isset(&rand_node.ip_port)) {
@@ -2622,11 +2638,11 @@ static void do_hardening(DHT *dht)
2622 // TODO(irungentoo): The search id should maybe not be ours? 2638 // TODO(irungentoo): The search id should maybe not be ours?
2623 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) { 2639 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
2624 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.public_key, CRYPTO_PUBLIC_KEY_SIZE); 2640 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.public_key, CRYPTO_PUBLIC_KEY_SIZE);
2625 cur_iptspng->hardening.send_nodes_timestamp = unix_time(); 2641 cur_iptspng->hardening.send_nodes_timestamp = mono_time_get(dht->mono_time);
2626 } 2642 }
2627 } 2643 }
2628 } else { 2644 } else {
2629 if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) { 2645 if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) {
2630 cur_iptspng->hardening.send_nodes_ok = 0; 2646 cur_iptspng->hardening.send_nodes_ok = 0;
2631 } 2647 }
2632 } 2648 }
@@ -2688,7 +2704,7 @@ static int cryptopacket_handle(void *object, IP_Port source, const uint8_t *pack
2688 2704
2689/*----------------------------------------------------------------------------------*/ 2705/*----------------------------------------------------------------------------------*/
2690 2706
2691DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled) 2707DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool holepunching_enabled)
2692{ 2708{
2693 if (net == nullptr) { 2709 if (net == nullptr) {
2694 return nullptr; 2710 return nullptr;
@@ -2700,12 +2716,13 @@ DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled)
2700 return nullptr; 2716 return nullptr;
2701 } 2717 }
2702 2718
2719 dht->mono_time = mono_time;
2703 dht->log = log; 2720 dht->log = log;
2704 dht->net = net; 2721 dht->net = net;
2705 2722
2706 dht->hole_punching_enabled = holepunching_enabled; 2723 dht->hole_punching_enabled = holepunching_enabled;
2707 2724
2708 dht->ping = ping_new(dht); 2725 dht->ping = ping_new(mono_time, dht);
2709 2726
2710 if (dht->ping == nullptr) { 2727 if (dht->ping == nullptr) {
2711 kill_dht(dht); 2728 kill_dht(dht);
@@ -2738,7 +2755,7 @@ DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled)
2738 2755
2739void do_dht(DHT *dht) 2756void do_dht(DHT *dht)
2740{ 2757{
2741 if (dht->last_run == unix_time()) { 2758 if (dht->last_run == mono_time_get(dht->mono_time)) {
2742 return; 2759 return;
2743 } 2760 }
2744 2761
@@ -2754,7 +2771,7 @@ void do_dht(DHT *dht)
2754#if DHT_HARDENING 2771#if DHT_HARDENING
2755 do_hardening(dht); 2772 do_hardening(dht);
2756#endif 2773#endif
2757 dht->last_run = unix_time(); 2774 dht->last_run = mono_time_get(dht->mono_time);
2758} 2775}
2759 2776
2760void kill_dht(DHT *dht) 2777void kill_dht(DHT *dht)
@@ -2961,8 +2978,8 @@ bool dht_isconnected(const DHT *dht)
2961 for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { 2978 for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
2962 const Client_data *const client = &dht->close_clientlist[i]; 2979 const Client_data *const client = &dht->close_clientlist[i];
2963 2980
2964 if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) || 2981 if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
2965 !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) { 2982 !mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) {
2966 return true; 2983 return true;
2967 } 2984 }
2968 } 2985 }
@@ -2978,11 +2995,13 @@ bool dht_non_lan_connected(const DHT *dht)
2978 for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { 2995 for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
2979 const Client_data *const client = &dht->close_clientlist[i]; 2996 const Client_data *const client = &dht->close_clientlist[i];
2980 2997
2981 if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && ip_is_lan(client->assoc4.ip_port.ip) == -1) { 2998 if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)
2999 && ip_is_lan(client->assoc4.ip_port.ip) == -1) {
2982 return true; 3000 return true;
2983 } 3001 }
2984 3002
2985 if (!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT) && ip_is_lan(client->assoc6.ip_port.ip) == -1) { 3003 if (!mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)
3004 && ip_is_lan(client->assoc6.ip_port.ip) == -1) {
2986 return true; 3005 return true;
2987 } 3006 }
2988 } 3007 }