summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/DHT.c112
-rw-r--r--toxcore/LAN_discovery.c3
-rw-r--r--toxcore/Messenger.c166
-rw-r--r--toxcore/friend_requests.c8
-rw-r--r--toxcore/group_chats.c92
-rw-r--r--toxcore/net_crypto.c5
-rw-r--r--toxcore/network.c2
-rw-r--r--toxcore/network.h5
-rw-r--r--toxcore/ping.c27
-rw-r--r--toxcore/tox.h5
-rw-r--r--toxcore/util.c32
-rw-r--r--toxcore/util.h14
12 files changed, 150 insertions, 321 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 2f468632..5232deed 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -115,26 +115,15 @@ static int client_id_cmp(ClientPair p1, ClientPair p2)
115 return c; 115 return c;
116} 116}
117 117
118static int id_equal(uint8_t *a, uint8_t *b)
119{
120 return memcmp(a, b, CLIENT_ID_SIZE) == 0;
121}
122
123static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
124{
125 return timestamp + timeout <= time_now;
126}
127
128static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id) 118static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id)
129{ 119{
130 uint32_t i; 120 uint32_t i;
131 uint64_t temp_time = unix_time();
132 121
133 for (i = 0; i < length; i++) 122 for (i = 0; i < length; i++)
134 123
135 /* Dead nodes are considered dead (not in the list)*/ 124 /* Dead nodes are considered dead (not in the list)*/
136 if (!is_timeout(temp_time, list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || 125 if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) ||
137 !is_timeout(temp_time, list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) 126 !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT))
138 if (id_equal(list[i].client_id, client_id)) 127 if (id_equal(list[i].client_id, client_id))
139 return 1; 128 return 1;
140 129
@@ -273,7 +262,7 @@ static int friend_number(DHT *dht, uint8_t *client_id)
273 */ 262 */
274static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, 263static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list,
275 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, 264 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
276 time_t timestamp, int *num_nodes_ptr, uint8_t is_LAN) 265 int *num_nodes_ptr, uint8_t is_LAN)
277{ 266{
278 if ((sa_family != AF_INET) && (sa_family != AF_INET6)) 267 if ((sa_family != AF_INET) && (sa_family != AF_INET6))
279 return; 268 return;
@@ -297,7 +286,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
297 ipptp = &client->assoc6; 286 ipptp = &client->assoc6;
298 287
299 /* node not in a good condition? */ 288 /* node not in a good condition? */
300 if (is_timeout(timestamp, ipptp->timestamp, BAD_NODE_TIMEOUT)) 289 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT))
301 continue; 290 continue;
302 291
303 IP *client_ip = &ipptp->ip_port.ip; 292 IP *client_ip = &ipptp->ip_port.ip;
@@ -369,15 +358,14 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
369 */ 358 */
370static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN) 359static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN)
371{ 360{
372 time_t timestamp = unix_time();
373 int num_nodes = 0, i; 361 int num_nodes = 0, i;
374 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 362 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
375 dht->close_clientlist, LCLIENT_LIST, timestamp, &num_nodes, is_LAN); 363 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN);
376 364
377 for (i = 0; i < dht->num_friends; ++i) 365 for (i = 0; i < dht->num_friends; ++i)
378 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 366 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
379 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 367 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
380 timestamp, &num_nodes, is_LAN); 368 &num_nodes, is_LAN);
381 369
382 return num_nodes; 370 return num_nodes;
383} 371}
@@ -396,7 +384,6 @@ static int replace_bad( Client_data *list,
396 return 1; 384 return 1;
397 385
398 uint32_t i; 386 uint32_t i;
399 uint64_t temp_time = unix_time();
400 387
401 for (i = 0; i < length; ++i) { 388 for (i = 0; i < length; ++i) {
402 /* If node is bad */ 389 /* If node is bad */
@@ -408,10 +395,10 @@ static int replace_bad( Client_data *list,
408 else 395 else
409 ipptp = &client->assoc6; 396 ipptp = &client->assoc6;
410 397
411 if (is_timeout(temp_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) { 398 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) {
412 memcpy(client->client_id, client_id, CLIENT_ID_SIZE); 399 memcpy(client->client_id, client_id, CLIENT_ID_SIZE);
413 ipptp->ip_port = ip_port; 400 ipptp->ip_port = ip_port;
414 ipptp->timestamp = temp_time; 401 ipptp->timestamp = unix_time();
415 402
416 ip_reset(&ipptp->ret_ip_port.ip); 403 ip_reset(&ipptp->ret_ip_port.ip);
417 ipptp->ret_ip_port.port = 0; 404 ipptp->ret_ip_port.port = 0;
@@ -943,7 +930,6 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
943 */ 930 */
944static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) 931static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
945{ 932{
946 uint64_t temp_time = unix_time();
947 uint32_t i, num = 0; 933 uint32_t i, num = 0;
948 934
949 for (i = 0; i < length; ++i) { 935 for (i = 0; i < length; ++i) {
@@ -952,7 +938,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
952 938
953 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) 939 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4)
954 if (ipport_isset(&(assoc->ip_port)) && 940 if (ipport_isset(&(assoc->ip_port)) &&
955 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 941 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
956 getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL); 942 getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL);
957 ++num; 943 ++num;
958 944
@@ -1022,7 +1008,6 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id)
1022int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) 1008int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
1023{ 1009{
1024 uint32_t i, j; 1010 uint32_t i, j;
1025 uint64_t temp_time = unix_time();
1026 1011
1027 ip_reset(&ip_port->ip); 1012 ip_reset(&ip_port->ip);
1028 ip_port->port = 0; 1013 ip_port->port = 0;
@@ -1038,7 +1023,7 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port)
1038 uint32_t a; 1023 uint32_t a;
1039 1024
1040 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) 1025 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
1041 if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { 1026 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
1042 *ip_port = assoc->ip_port; 1027 *ip_port = assoc->ip_port;
1043 return 1; 1028 return 1;
1044 } 1029 }
@@ -1069,14 +1054,14 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
1069 uint32_t a; 1054 uint32_t a;
1070 1055
1071 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4) 1056 for (a = 0, assoc = &client->assoc6; a < 2; a++, assoc = &client->assoc4)
1072 if (!is_timeout(temp_time, assoc->timestamp, KILL_NODE_TIMEOUT)) { 1057 if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) {
1073 if (is_timeout(temp_time, assoc->last_pinged, PING_INTERVAL)) { 1058 if (is_timeout(assoc->last_pinged, PING_INTERVAL)) {
1074 send_ping_request(dht->ping, assoc->ip_port, client->client_id ); 1059 send_ping_request(dht->ping, assoc->ip_port, client->client_id );
1075 assoc->last_pinged = temp_time; 1060 assoc->last_pinged = temp_time;
1076 } 1061 }
1077 1062
1078 /* If node is good. */ 1063 /* If node is good. */
1079 if (!is_timeout(temp_time, assoc->timestamp, BAD_NODE_TIMEOUT)) { 1064 if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
1080 client_list[num_nodes] = client; 1065 client_list[num_nodes] = client;
1081 assoc_list[num_nodes] = assoc; 1066 assoc_list[num_nodes] = assoc;
1082 ++num_nodes; 1067 ++num_nodes;
@@ -1084,8 +1069,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
1084 } 1069 }
1085 } 1070 }
1086 1071
1087 if ((num_nodes != 0) && 1072 if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) {
1088 is_timeout(temp_time, *lastgetnode, GET_NODE_INTERVAL)) {
1089 uint32_t rand_node = rand() % num_nodes; 1073 uint32_t rand_node = rand() % num_nodes;
1090 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, 1074 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
1091 client_id, NULL); 1075 client_id, NULL);
@@ -1180,9 +1164,6 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
1180 */ 1164 */
1181static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) 1165static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1182{ 1166{
1183 int i;
1184 uint64_t temp_time = unix_time();
1185
1186 if (friend_num >= dht->num_friends) 1167 if (friend_num >= dht->num_friends)
1187 return -1; 1168 return -1;
1188 1169
@@ -1193,22 +1174,21 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1193 IP_Port ipv6s[MAX_FRIEND_CLIENTS]; 1174 IP_Port ipv6s[MAX_FRIEND_CLIENTS];
1194 int num_ipv6s = 0; 1175 int num_ipv6s = 0;
1195 uint8_t connected; 1176 uint8_t connected;
1177 int i;
1196 1178
1197 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 1179 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1198 client = &(friend->client_list[i]); 1180 client = &(friend->client_list[i]);
1199 connected = 0; 1181 connected = 0;
1200 1182
1201 /* If ip is not zero and node is good. */ 1183 /* If ip is not zero and node is good. */
1202 if (ip_isset(&client->assoc4.ret_ip_port.ip) 1184 if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
1203 && !is_timeout(temp_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
1204 ipv4s[num_ipv4s] = client->assoc4.ret_ip_port; 1185 ipv4s[num_ipv4s] = client->assoc4.ret_ip_port;
1205 ++num_ipv4s; 1186 ++num_ipv4s;
1206 1187
1207 connected = 1; 1188 connected = 1;
1208 } 1189 }
1209 1190
1210 if (ip_isset(&client->assoc6.ret_ip_port.ip) 1191 if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
1211 && !is_timeout(temp_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
1212 ipv6s[num_ipv6s] = client->assoc6.ret_ip_port; 1192 ipv6s[num_ipv6s] = client->assoc6.ret_ip_port;
1213 ++num_ipv6s; 1193 ++num_ipv6s;
1214 1194
@@ -1271,7 +1251,6 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1271 if (ip_num < (MAX_FRIEND_CLIENTS / 2)) 1251 if (ip_num < (MAX_FRIEND_CLIENTS / 2))
1272 return 0; /* Reason for that? */ 1252 return 0; /* Reason for that? */
1273 1253
1274 uint64_t temp_time = unix_time();
1275 DHT_Friend *friend = &dht->friends_list[num]; 1254 DHT_Friend *friend = &dht->friends_list[num];
1276 Client_data *client; 1255 Client_data *client;
1277 1256
@@ -1294,7 +1273,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1294 1273
1295 /* If ip is not zero and node is good. */ 1274 /* If ip is not zero and node is good. */
1296 if (ip_isset(&assoc->ret_ip_port.ip) && 1275 if (ip_isset(&assoc->ret_ip_port.ip) &&
1297 !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 1276 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1298 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length); 1277 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length);
1299 1278
1300 if ((unsigned int)retval == length) { 1279 if ((unsigned int)retval == length) {
@@ -1324,7 +1303,6 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1324 IP_Port ip_list[MAX_FRIEND_CLIENTS * 2]; 1303 IP_Port ip_list[MAX_FRIEND_CLIENTS * 2];
1325 int n = 0; 1304 int n = 0;
1326 uint32_t i; 1305 uint32_t i;
1327 uint64_t temp_time = unix_time();
1328 1306
1329 /* extra legwork, because having the outside allocating the space for us 1307 /* extra legwork, because having the outside allocating the space for us
1330 * is *usually* good(tm) (bites us in the behind in this case though) */ 1308 * is *usually* good(tm) (bites us in the behind in this case though) */
@@ -1341,7 +1319,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1341 assoc = &client->assoc6; 1319 assoc = &client->assoc6;
1342 1320
1343 /* If ip is not zero and node is good. */ 1321 /* If ip is not zero and node is good. */
1344 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(temp_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 1322 if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1345 ip_list[n] = assoc->ip_port; 1323 ip_list[n] = assoc->ip_port;
1346 ++n; 1324 ++n;
1347 } 1325 }
@@ -1665,6 +1643,9 @@ static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey
1665 1643
1666DHT *new_DHT(Net_Crypto *c) 1644DHT *new_DHT(Net_Crypto *c)
1667{ 1645{
1646 /* init time */
1647 unix_time_update();
1648
1668 if (c == NULL) 1649 if (c == NULL)
1669 return NULL; 1650 return NULL;
1670 1651
@@ -1694,6 +1675,8 @@ DHT *new_DHT(Net_Crypto *c)
1694 1675
1695void do_DHT(DHT *dht) 1676void do_DHT(DHT *dht)
1696{ 1677{
1678 unix_time_update();
1679
1697 do_Close(dht); 1680 do_Close(dht);
1698 do_DHT_friends(dht); 1681 do_DHT_friends(dht);
1699 do_NAT(dht); 1682 do_NAT(dht);
@@ -1711,8 +1694,6 @@ void kill_DHT(DHT *dht)
1711#define DHT_STATE_COOKIE_GLOBAL 0x159000d 1694#define DHT_STATE_COOKIE_GLOBAL 0x159000d
1712 1695
1713#define DHT_STATE_COOKIE_TYPE 0x11ce 1696#define DHT_STATE_COOKIE_TYPE 0x11ce
1714#define DHT_STATE_TYPE_FRIENDS 1
1715#define DHT_STATE_TYPE_CLIENTS 2
1716#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3 1697#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3
1717#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4 1698#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4
1718 1699
@@ -1784,43 +1765,6 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1784 uint32_t num, i, j; 1765 uint32_t num, i, j;
1785 1766
1786 switch (type) { 1767 switch (type) {
1787 case DHT_STATE_TYPE_FRIENDS:
1788 if (length % sizeof(DHT_Friend_old) != 0)
1789 break;
1790
1791 { /* localize declarations */
1792 DHT_Friend_old *friend_list = (DHT_Friend_old *)data;
1793 num = length / sizeof(DHT_Friend_old);
1794
1795 for (i = 0; i < num; ++i) {
1796 DHT_addfriend(dht, friend_list[i].client_id);
1797
1798 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1799 Client_data_old *client = &friend_list[i].client_list[j];
1800
1801 if (client->assoc.timestamp != 0)
1802 getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id, NULL);
1803 }
1804 }
1805 } /* localize declarations */
1806
1807 break;
1808
1809 case DHT_STATE_TYPE_CLIENTS:
1810 if ((length % sizeof(Client_data_old)) != 0)
1811 break;
1812
1813 { /* localize declarations */
1814 num = length / sizeof(Client_data_old);
1815 Client_data_old *client_list = (Client_data_old *)data;
1816
1817 for (i = 0; i < num; ++i)
1818 if (client_list[i].assoc.timestamp != 0)
1819 DHT_bootstrap(dht, client_list[i].assoc.ip_port, client_list[i].client_id);
1820 } /* localize declarations */
1821
1822 break;
1823
1824 case DHT_STATE_TYPE_FRIENDS_ASSOC46: 1768 case DHT_STATE_TYPE_FRIENDS_ASSOC46:
1825 if (length % sizeof(DHT_Friend) != 0) 1769 if (length % sizeof(DHT_Friend) != 0)
1826 break; 1770 break;
@@ -1894,7 +1838,7 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1894 length - cookie_len, DHT_STATE_COOKIE_TYPE); 1838 length - cookie_len, DHT_STATE_COOKIE_TYPE);
1895 } 1839 }
1896 1840
1897 return DHT_load_old(dht, data, length); 1841 return -1;
1898} 1842}
1899/* return 0 if we are not connected to the DHT. 1843/* return 0 if we are not connected to the DHT.
1900 * return 1 if we are. 1844 * return 1 if we are.
@@ -1902,13 +1846,13 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1902int DHT_isconnected(DHT *dht) 1846int DHT_isconnected(DHT *dht)
1903{ 1847{
1904 uint32_t i; 1848 uint32_t i;
1905 uint64_t temp_time = unix_time(); 1849 unix_time_update();
1906 1850
1907 for (i = 0; i < LCLIENT_LIST; ++i) { 1851 for (i = 0; i < LCLIENT_LIST; ++i) {
1908 Client_data *client = &dht->close_clientlist[i]; 1852 Client_data *client = &dht->close_clientlist[i];
1909 1853
1910 if (!is_timeout(temp_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) || 1854 if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
1911 !is_timeout(temp_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) 1855 !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT))
1912 return 1; 1856 return 1;
1913 } 1857 }
1914 1858
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index a4f1ccc2..eb0b95a1 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#include "LAN_discovery.h" 28#include "LAN_discovery.h"
29#include "util.h"
29 30
30#define MAX_INTERFACES 16 31#define MAX_INTERFACES 16
31 32
@@ -214,7 +215,7 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
214{ 215{
215 uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; 216 uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
216 data[0] = NET_PACKET_LAN_DISCOVERY; 217 data[0] = NET_PACKET_LAN_DISCOVERY;
217 memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); 218 id_copy(data + 1, c->self_public_key);
218 219
219#ifdef __linux 220#ifdef __linux
220 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); 221 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index ff64a072..be3d82e0 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -92,7 +92,7 @@ int getfriend_id(Messenger *m, uint8_t *client_id)
92 92
93 for (i = 0; i < m->numfriends; ++i) { 93 for (i = 0; i < m->numfriends; ++i) {
94 if (m->friendlist[i].status > 0) 94 if (m->friendlist[i].status > 0)
95 if (memcmp(client_id, m->friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) 95 if (id_equal(client_id, m->friendlist[i].client_id))
96 return i; 96 return i;
97 } 97 }
98 98
@@ -140,7 +140,7 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
140 */ 140 */
141void getaddress(Messenger *m, uint8_t *address) 141void getaddress(Messenger *m, uint8_t *address)
142{ 142{
143 memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES); 143 id_copy(address, m->net_crypto->self_public_key);
144 uint32_t nospam = get_nospam(&(m->fr)); 144 uint32_t nospam = get_nospam(&(m->fr));
145 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); 145 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
146 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); 146 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
@@ -173,7 +173,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
173 return FAERR_TOOLONG; 173 return FAERR_TOOLONG;
174 174
175 uint8_t client_id[crypto_box_PUBLICKEYBYTES]; 175 uint8_t client_id[crypto_box_PUBLICKEYBYTES];
176 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES); 176 id_copy(client_id, address);
177 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); 177 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
178 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check)); 178 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
179 179
@@ -183,7 +183,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
183 if (length < 1) 183 if (length < 1)
184 return FAERR_NOMESSAGE; 184 return FAERR_NOMESSAGE;
185 185
186 if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 186 if (id_equal(client_id, m->net_crypto->self_public_key))
187 return FAERR_OWNKEY; 187 return FAERR_OWNKEY;
188 188
189 int friend_id = getfriend_id(m, client_id); 189 int friend_id = getfriend_id(m, client_id);
@@ -214,7 +214,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
214 m->friendlist[i].crypt_connection_id = -1; 214 m->friendlist[i].crypt_connection_id = -1;
215 m->friendlist[i].friendrequest_lastsent = 0; 215 m->friendlist[i].friendrequest_lastsent = 0;
216 m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT; 216 m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT;
217 memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 217 id_copy(m->friendlist[i].client_id, client_id);
218 m->friendlist[i].statusmessage = calloc(1, 1); 218 m->friendlist[i].statusmessage = calloc(1, 1);
219 m->friendlist[i].statusmessage_length = 1; 219 m->friendlist[i].statusmessage_length = 1;
220 m->friendlist[i].userstatus = USERSTATUS_NONE; 220 m->friendlist[i].userstatus = USERSTATUS_NONE;
@@ -243,7 +243,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
243 if (realloc_friendlist(m, m->numfriends + 1) != 0) 243 if (realloc_friendlist(m, m->numfriends + 1) != 0)
244 return FAERR_NOMEM; 244 return FAERR_NOMEM;
245 245
246 if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 246 if (id_equal(client_id, m->net_crypto->self_public_key))
247 return FAERR_OWNKEY; 247 return FAERR_OWNKEY;
248 248
249 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); 249 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
@@ -256,7 +256,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
256 m->friendlist[i].status = FRIEND_CONFIRMED; 256 m->friendlist[i].status = FRIEND_CONFIRMED;
257 m->friendlist[i].crypt_connection_id = -1; 257 m->friendlist[i].crypt_connection_id = -1;
258 m->friendlist[i].friendrequest_lastsent = 0; 258 m->friendlist[i].friendrequest_lastsent = 0;
259 memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 259 id_copy(m->friendlist[i].client_id, client_id);
260 m->friendlist[i].statusmessage = calloc(1, 1); 260 m->friendlist[i].statusmessage = calloc(1, 1);
261 m->friendlist[i].statusmessage_length = 1; 261 m->friendlist[i].statusmessage_length = 1;
262 m->friendlist[i].userstatus = USERSTATUS_NONE; 262 m->friendlist[i].userstatus = USERSTATUS_NONE;
@@ -728,7 +728,7 @@ static int group_num(Messenger *m, uint8_t *group_public_key)
728 uint32_t i; 728 uint32_t i;
729 729
730 for (i = 0; i < m->numchats; ++i) { 730 for (i = 0; i < m->numchats; ++i) {
731 if (memcmp(m->chats[i]->self_public_key, group_public_key, crypto_box_PUBLICKEYBYTES) == 0) 731 if (id_equal(m->chats[i]->self_public_key, group_public_key))
732 return i; 732 return i;
733 } 733 }
734 734
@@ -917,8 +917,8 @@ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_
917 if (groupnum == -1) 917 if (groupnum == -1)
918 return -1; 918 return -1;
919 919
920 memcpy(data, friend_group_public_key, crypto_box_PUBLICKEYBYTES); 920 id_copy(data, friend_group_public_key);
921 memcpy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key, crypto_box_PUBLICKEYBYTES); 921 id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key);
922 922
923 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) { 923 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) {
924 chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber), 924 chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber),
@@ -965,7 +965,7 @@ static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t
965 if (m->chats[i] == NULL) 965 if (m->chats[i] == NULL)
966 continue; 966 continue;
967 967
968 if (memcmp(packet + 1, m->chats[i]->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 968 if (id_equal(packet + 1, m->chats[i]->self_public_key))
969 return handle_groupchatpacket(m->chats[i], source, packet, length); 969 return handle_groupchatpacket(m->chats[i], source, packet, length);
970 } 970 }
971 971
@@ -1769,6 +1769,8 @@ static char *ID2String(uint8_t *client_id)
1769/* The main loop that needs to be run at least 20 times per second. */ 1769/* The main loop that needs to be run at least 20 times per second. */
1770void do_messenger(Messenger *m) 1770void do_messenger(Messenger *m)
1771{ 1771{
1772 unix_time_update();
1773
1772 networking_poll(m->net); 1774 networking_poll(m->net);
1773 1775
1774 do_DHT(m->dht); 1776 do_DHT(m->dht);
@@ -1888,144 +1890,6 @@ void wait_cleanup_messenger(Messenger *m, uint8_t *data, uint16_t len)
1888 networking_wait_cleanup(m->net, data, len); 1890 networking_wait_cleanup(m->net, data, len);
1889} 1891}
1890 1892
1891/* return size of the messenger data (for saving) */
1892uint32_t Messenger_size_old(Messenger *m)
1893{
1894 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES
1895 + sizeof(uint32_t) // nospam.
1896 + sizeof(uint32_t) // DHT size.
1897 + DHT_size(m->dht) // DHT itself.
1898 + sizeof(uint32_t) // Friendlist size.
1899 + sizeof(Friend) * m->numfriends // Friendlist itself.
1900 + sizeof(uint16_t) // Own nickname length.
1901 + m->name_length // Own nickname.
1902 ;
1903}
1904
1905/* Save the messenger in data of size Messenger_size(). Old version without cookies. */
1906static void Messenger_save_old(Messenger *m, uint8_t *data)
1907{
1908 save_keys(m->net_crypto, data);
1909 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
1910
1911 uint32_t nospam = get_nospam(&(m->fr));
1912 memcpy(data, &nospam, sizeof(nospam));
1913 data += sizeof(nospam);
1914
1915 uint32_t size = DHT_size(m->dht);
1916 memcpy(data, &size, sizeof(size));
1917 data += sizeof(size);
1918 DHT_save(m->dht, data);
1919 data += size;
1920
1921 size = sizeof(Friend) * m->numfriends;
1922 memcpy(data, &size, sizeof(size));
1923 data += sizeof(size);
1924 memcpy(data, m->friendlist, sizeof(Friend) * m->numfriends);
1925 data += size;
1926
1927 uint16_t small_size = m->name_length;
1928 memcpy(data, &small_size, sizeof(small_size));
1929 data += sizeof(small_size);
1930 memcpy(data, m->name, small_size);
1931}
1932
1933/* Load the messenger from data of size length. Old version without cookies. */
1934static int Messenger_load_old(Messenger *m, uint8_t *data, uint32_t length)
1935{
1936 if (length == ~((uint32_t)0))
1937 return -1;
1938
1939 /* BLOCK1: PUBKEY, SECKEY, NOSPAM, SIZE */
1940 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2)
1941 return -1;
1942
1943 load_keys(m->net_crypto, data);
1944 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
1945 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
1946
1947 uint32_t nospam;
1948 memcpy(&nospam, data, sizeof(nospam));
1949 set_nospam(&(m->fr), nospam);
1950 data += sizeof(nospam);
1951 length -= sizeof(nospam);
1952
1953 uint32_t size;
1954
1955 if (length < sizeof(size))
1956 return -1;
1957
1958 memcpy(&size, data, sizeof(size));
1959 data += sizeof(size);
1960 length -= sizeof(size);
1961
1962 if (length < size)
1963 return -1;
1964
1965 if (DHT_load_old(m->dht, data, size) == -1) {
1966#ifdef DEBUG
1967 fprintf(stderr, "Data file: Something wicked happened to the stored connections...\n");
1968 /* DO go on, friends/name still might be intact */
1969#endif
1970 }
1971
1972 data += size;
1973 length -= size;
1974
1975 if (length < sizeof(size))
1976 return -1;
1977
1978 memcpy(&size, data, sizeof(size));
1979 data += sizeof(size);
1980 length -= sizeof(size);
1981
1982 if (length < size)
1983 return -1;
1984
1985 if (!(size % sizeof(Friend))) {
1986 uint16_t num = size / sizeof(Friend);
1987 Friend *friend_list = (Friend *)data;
1988
1989 uint32_t i;
1990
1991 for (i = 0; i < num; ++i) {
1992 if (friend_list[i].status >= 3) {
1993 int fnum = m_addfriend_norequest(m, friend_list[i].client_id);
1994 setfriendname(m, fnum, friend_list[i].name, friend_list[i].name_length);
1995 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
1996 } else if (friend_list[i].status != 0) {
1997 /* TODO: This is not a good way to do this. */
1998 uint8_t address[FRIEND_ADDRESS_SIZE];
1999 memcpy(address, friend_list[i].client_id, crypto_box_PUBLICKEYBYTES);
2000 memcpy(address + crypto_box_PUBLICKEYBYTES, &(friend_list[i].friendrequest_nospam), sizeof(uint32_t));
2001 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
2002 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
2003 m_addfriend(m, address, friend_list[i].info, friend_list[i].info_size);
2004 }
2005 }
2006 }
2007
2008 data += size;
2009 length -= size;
2010
2011 uint16_t small_size;
2012
2013 if (length < sizeof(small_size))
2014 return -1;
2015
2016 memcpy(&small_size, data, sizeof(small_size));
2017 data += sizeof(small_size);
2018 length -= sizeof(small_size);
2019
2020 if (length < small_size)
2021 return -1;
2022
2023 setname(m, data, small_size);
2024
2025 return 0;
2026}
2027
2028
2029/* new messenger format for load/save, more robust and forward compatible */ 1893/* new messenger format for load/save, more robust and forward compatible */
2030 1894
2031#define MESSENGER_STATE_COOKIE_GLOBAL 0x15ed1b1e 1895#define MESSENGER_STATE_COOKIE_GLOBAL 0x15ed1b1e
@@ -2130,7 +1994,7 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
2130 } else if (friends[i].status != 0) { 1994 } else if (friends[i].status != 0) {
2131 /* TODO: This is not a good way to do this. */ 1995 /* TODO: This is not a good way to do this. */
2132 uint8_t address[FRIEND_ADDRESS_SIZE]; 1996 uint8_t address[FRIEND_ADDRESS_SIZE];
2133 memcpy(address, friends[i].client_id, crypto_box_PUBLICKEYBYTES); 1997 id_copy(address, friends[i].client_id);
2134 memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t)); 1998 memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t));
2135 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); 1999 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
2136 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); 2000 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
@@ -2174,7 +2038,7 @@ int messenger_load(Messenger *m, uint8_t *data, uint32_t length)
2174 return load_state(messenger_load_state_callback, m, data + cookie_len, 2038 return load_state(messenger_load_state_callback, m, data + cookie_len,
2175 length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); 2039 length - cookie_len, MESSENGER_STATE_COOKIE_TYPE);
2176 else /* old state file */ 2040 else /* old state file */
2177 return Messenger_load_old(m, data, length); 2041 return -1;
2178} 2042}
2179 2043
2180/* Return the number of friends in the instance m. 2044/* Return the number of friends in the instance m.
diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c
index c821d998..67977c23 100644
--- a/toxcore/friend_requests.c
+++ b/toxcore/friend_requests.c
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#include "friend_requests.h" 28#include "friend_requests.h"
29#include "util.h"
29 30
30/* Try to send a friend request to peer with public_key. 31/* Try to send a friend request to peer with public_key.
31 * data is the data in the request and length is the length. 32 * data is the data in the request and length is the length.
@@ -102,7 +103,7 @@ static void addto_receivedlist(Friend_Requests *fr, uint8_t *client_id)
102 if (fr->received_requests_index >= MAX_RECEIVED_STORED) 103 if (fr->received_requests_index >= MAX_RECEIVED_STORED)
103 fr->received_requests_index = 0; 104 fr->received_requests_index = 0;
104 105
105 memcpy(fr->received_requests[fr->received_requests_index], client_id, crypto_box_PUBLICKEYBYTES); 106 id_copy(fr->received_requests[fr->received_requests_index], client_id);
106 ++fr->received_requests_index; 107 ++fr->received_requests_index;
107} 108}
108 109
@@ -115,10 +116,9 @@ static int request_received(Friend_Requests *fr, uint8_t *client_id)
115{ 116{
116 uint32_t i; 117 uint32_t i;
117 118
118 for (i = 0; i < MAX_RECEIVED_STORED; ++i) { 119 for (i = 0; i < MAX_RECEIVED_STORED; ++i)
119 if (memcmp(fr->received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) 120 if (id_equal(fr->received_requests[i], client_id))
120 return 1; 121 return 1;
121 }
122 122
123 return 0; 123 return 0;
124} 124}
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c
index 0d6d6972..fdf6e834 100644
--- a/toxcore/group_chats.c
+++ b/toxcore/group_chats.c
@@ -27,7 +27,7 @@
27#endif 27#endif
28 28
29#include "group_chats.h" 29#include "group_chats.h"
30 30#include "util.h"
31 31
32#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES)) 32#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES))
33#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES) 33#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES)
@@ -67,16 +67,14 @@ static int peer_in_chat(Group_Chat *chat, uint8_t *client_id)
67{ 67{
68 uint32_t i; 68 uint32_t i;
69 69
70 for (i = 0; i < chat->numpeers; ++i) { 70 for (i = 0; i < chat->numpeers; ++i)
71 /* Equal */ 71 if (id_equal(chat->group[i].client_id, client_id))
72 if (memcmp(chat->group[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0)
73 return i; 72 return i;
74 }
75 73
76 return -1; 74 return -1;
77} 75}
78 76
79#define BAD_NODE_TIMEOUT 30 77#define BAD_GROUPNODE_TIMEOUT 30
80 78
81/* 79/*
82 * Check if peer is closer to us that the other peers in the list and if the peer is in the list. 80 * Check if peer is closer to us that the other peers in the list and if the peer is in the list.
@@ -87,19 +85,18 @@ static int peer_in_chat(Group_Chat *chat, uint8_t *client_id)
87static int peer_okping(Group_Chat *chat, uint8_t *client_id) 85static int peer_okping(Group_Chat *chat, uint8_t *client_id)
88{ 86{
89 uint32_t i, j = 0; 87 uint32_t i, j = 0;
90 uint64_t temp_time = unix_time();
91 88
92 if (memcmp(chat->self_public_key, client_id, crypto_box_PUBLICKEYBYTES) == 0) 89 if (id_equal(chat->self_public_key, client_id))
93 return -1; 90 return -1;
94 91
95 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { 92 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
96 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT < temp_time) { 93 if (is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
97 ++j; 94 ++j;
98 continue; 95 continue;
99 } 96 }
100 97
101 /* Equal */ 98 /* Equal */
102 if (memcmp(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) 99 if (id_equal(chat->close[i].client_id, client_id))
103 return -1; 100 return -1;
104 101
105 if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2) 102 if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2)
@@ -121,29 +118,28 @@ static int peer_okping(Group_Chat *chat, uint8_t *client_id)
121static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port) 118static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port)
122{ 119{
123 uint32_t i; 120 uint32_t i;
124 uint64_t temp_time = unix_time();
125 121
126 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Check if node is already in list, if it is update its last_recv */ 122 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Check if node is already in list, if it is update its last_recv */
127 if (memcmp(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) { 123 if (id_equal(chat->close[i].client_id, client_id)) {
128 chat->close[i].last_recv = temp_time; 124 chat->close[i].last_recv = unix_time();
129 return 0; 125 return 0;
130 } 126 }
131 } 127 }
132 128
133 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Try replacing bad nodes first */ 129 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Try replacing bad nodes first */
134 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT < temp_time) { 130 if (is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
135 memcpy(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES); 131 id_copy(chat->close[i].client_id, client_id);
136 chat->close[i].ip_port = ip_port; 132 chat->close[i].ip_port = ip_port;
137 chat->close[i].last_recv = temp_time; 133 chat->close[i].last_recv = unix_time();
138 return 0; 134 return 0;
139 } 135 }
140 } 136 }
141 137
142 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Replace nodes if given one is closer. */ 138 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { /* Replace nodes if given one is closer. */
143 if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2) { 139 if (id_closest(chat->self_public_key, chat->close[i].client_id, client_id) == 2) {
144 memcpy(chat->close[i].client_id, client_id, crypto_box_PUBLICKEYBYTES); 140 id_copy(chat->close[i].client_id, client_id);
145 chat->close[i].ip_port = ip_port; 141 chat->close[i].ip_port = ip_port;
146 chat->close[i].last_recv = temp_time; 142 chat->close[i].last_recv = unix_time();
147 return 0; 143 return 0;
148 } 144 }
149 } 145 }
@@ -154,7 +150,7 @@ static int add_closepeer(Group_Chat *chat, uint8_t *client_id, IP_Port ip_port)
154static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *public_key, uint8_t *data, uint32_t length, 150static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *public_key, uint8_t *data, uint32_t length,
155 uint8_t request_id) 151 uint8_t request_id)
156{ 152{
157 if (memcmp(chat->self_public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) 153 if (id_equal(chat->self_public_key, public_key))
158 return -1; 154 return -1;
159 155
160 uint8_t packet[MAX_DATA_SIZE]; 156 uint8_t packet[MAX_DATA_SIZE];
@@ -180,11 +176,12 @@ static uint8_t sendto_allpeers(Group_Chat *chat, uint8_t *data, uint16_t length,
180{ 176{
181 uint16_t sent = 0; 177 uint16_t sent = 0;
182 uint32_t i; 178 uint32_t i;
183 uint64_t temp_time = unix_time();
184 179
185 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { 180 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
186 if (ip_isset(&chat->close[i].ip_port.ip) && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { 181 if (ip_isset(&chat->close[i].ip_port.ip) &&
187 if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0) 182 !is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
183 if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id,
184 data, length, request_id) == 0)
188 ++sent; 185 ++sent;
189 } 186 }
190 } 187 }
@@ -214,7 +211,7 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id)
214 return -1; 211 return -1;
215 212
216 chat->group = temp; 213 chat->group = temp;
217 memcpy(chat->group[chat->numpeers].client_id, client_id, crypto_box_PUBLICKEYBYTES); 214 id_copy(chat->group[chat->numpeers].client_id, client_id);
218 ++chat->numpeers; 215 ++chat->numpeers;
219 return (chat->numpeers - 1); 216 return (chat->numpeers - 1);
220} 217}
@@ -232,14 +229,11 @@ static int delpeer(Group_Chat *chat, uint8_t *client_id)
232 229
233 for (i = 0; i < chat->numpeers; ++i) { 230 for (i = 0; i < chat->numpeers; ++i) {
234 /* Equal */ 231 /* Equal */
235 if (memcmp(chat->group[i].client_id, client_id, crypto_box_PUBLICKEYBYTES) == 0) { 232 if (id_equal(chat->group[i].client_id, client_id)) {
236 --chat->numpeers; 233 --chat->numpeers;
237 234
238 if (chat->numpeers != i) { 235 if (chat->numpeers != i)
239 memcpy( chat->group[i].client_id, 236 id_copy(chat->group[i].client_id, chat->group[chat->numpeers].client_id);
240 chat->group[chat->numpeers].client_id,
241 crypto_box_PUBLICKEYBYTES );
242 }
243 237
244 temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers)); 238 temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers));
245 239
@@ -276,22 +270,23 @@ int group_peername(Group_Chat *chat, int peernum, uint8_t *name)
276 270
277 271
278/* min time between pings sent to one peer in seconds */ 272/* min time between pings sent to one peer in seconds */
273/* TODO: move this to global section */
279#define PING_TIMEOUT 5 274#define PING_TIMEOUT 5
275
280static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum) 276static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum)
281{ 277{
282 if ((uint32_t)peernum >= chat->numpeers) 278 if ((uint32_t)peernum >= chat->numpeers)
283 return -1; 279 return -1;
284 280
285 uint64_t temp_time = unix_time(); 281 if (!is_timeout(chat->group[peernum].last_pinged, PING_TIMEOUT))
286
287 getnodes_data contents;
288
289 if (chat->group[peernum].last_pinged + PING_TIMEOUT > temp_time)
290 return -1; 282 return -1;
291 283
284 getnodes_data contents;
292 contents.pingid = ((uint64_t)random_int() << 32) + random_int(); 285 contents.pingid = ((uint64_t)random_int() << 32) + random_int();
293 chat->group[peernum].last_pinged = temp_time; 286
287 chat->group[peernum].last_pinged = unix_time();
294 chat->group[peernum].pingid = contents.pingid; 288 chat->group[peernum].pingid = contents.pingid;
289
295 return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), 48); 290 return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), 48);
296} 291}
297 292
@@ -303,11 +298,10 @@ static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64
303 sendnodes_data contents; 298 sendnodes_data contents;
304 contents.pingid = pingid; 299 contents.pingid = pingid;
305 uint32_t i, j = 0; 300 uint32_t i, j = 0;
306 uint64_t temp_time = unix_time();
307 301
308 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { 302 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
309 if (chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { 303 if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
310 memcpy(contents.nodes[j].client_id, chat->close[i].client_id, crypto_box_PUBLICKEYBYTES); 304 id_copy(contents.nodes[j].client_id, chat->close[i].client_id);
311 contents.nodes[j].ip_port = chat->close[i].ip_port; 305 contents.nodes[j].ip_port = chat->close[i].ip_port;
312 ++j; 306 ++j;
313 } 307 }
@@ -346,7 +340,7 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
346 if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0) 340 if ((len - sizeof(uint64_t)) % sizeof(groupchat_nodes) != 0)
347 return 1; 341 return 1;
348 342
349 if (chat->group[peernum].last_pinged + PING_TIMEOUT < unix_time()) 343 if (is_timeout(chat->group[peernum].last_pinged, PING_TIMEOUT))
350 return 1; 344 return 1;
351 345
352 sendnodes_data contents; 346 sendnodes_data contents;
@@ -376,7 +370,9 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, uint8
376 add_closepeer(chat, chat->group[peernum].client_id, source); 370 add_closepeer(chat, chat->group[peernum].client_id, source);
377 return 0; 371 return 0;
378} 372}
373
379#define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1) 374#define GROUP_DATA_MIN_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + 1)
375
380static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) 376static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
381{ 377{
382 if (len < GROUP_DATA_MIN_SIZE) 378 if (len < GROUP_DATA_MIN_SIZE)
@@ -392,7 +388,6 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
392 if (peernum == -1) 388 if (peernum == -1)
393 return 1; 389 return 1;
394 390
395 uint64_t temp_time = unix_time();
396 /* Spam prevention (1 message per peer per second limit.) 391 /* Spam prevention (1 message per peer per second limit.)
397 392
398 if (chat->group[peernum].last_recv == temp_time) 393 if (chat->group[peernum].last_recv == temp_time)
@@ -421,7 +416,8 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
421 if (contents_len != 0) 416 if (contents_len != 0)
422 return 1; 417 return 1;
423 418
424 chat->group[peernum].last_recv_msgping = temp_time; 419 chat->group[peernum].last_recv_msgping = unix_time();
420 break;
425 421
426 case 16: /* If message is new peer */ 422 case 16: /* If message is new peer */
427 if (contents_len != crypto_box_PUBLICKEYBYTES) 423 if (contents_len != crypto_box_PUBLICKEYBYTES)
@@ -463,7 +459,7 @@ static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t
463 459
464 uint32_t message_num = htonl(chat->message_number); 460 uint32_t message_num = htonl(chat->message_number);
465//TODO 461//TODO
466 memcpy(packet, chat->self_public_key, crypto_box_PUBLICKEYBYTES); 462 id_copy(packet, chat->self_public_key);
467 memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num)); 463 memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num));
468 memcpy(packet + GROUP_DATA_MIN_SIZE, data, len); 464 memcpy(packet + GROUP_DATA_MIN_SIZE, data, len);
469 packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id; 465 packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id;
@@ -489,7 +485,7 @@ int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, ui
489 if (len <= 0) 485 if (len <= 0)
490 return 1; 486 return 1;
491 487
492 if (memcmp(chat->self_public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) 488 if (id_equal(chat->self_public_key, public_key))
493 return 1; 489 return 1;
494 490
495 int peernum = peer_in_chat(chat, public_key); 491 int peernum = peer_in_chat(chat, public_key);
@@ -534,6 +530,8 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat,
534 530
535Group_Chat *new_groupchat(Networking_Core *net) 531Group_Chat *new_groupchat(Networking_Core *net)
536{ 532{
533 unix_time_update();
534
537 if (net == 0) 535 if (net == 0)
538 return 0; 536 return 0;
539 537
@@ -548,16 +546,16 @@ Group_Chat *new_groupchat(Networking_Core *net)
548static void ping_close(Group_Chat *chat) 546static void ping_close(Group_Chat *chat)
549{ 547{
550 uint32_t i; 548 uint32_t i;
551 uint64_t temp_time = unix_time();
552 549
553 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { 550 for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) {
554 if (chat->close[i].last_recv < temp_time + BAD_NODE_TIMEOUT) { 551 /* previous condition was always true, assuming this is the wanted one: */
552 if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) {
555 int peernum = peer_in_chat(chat, chat->close[i].client_id); 553 int peernum = peer_in_chat(chat, chat->close[i].client_id);
556 554
557 if (peernum == -1) 555 if (peernum == -1)
558 continue; 556 continue;
559 557
560 if (chat->group[peernum].last_pinged + NODE_PING_INTERVAL < temp_time) 558 if (is_timeout(chat->group[peernum].last_pinged, NODE_PING_INTERVAL))
561 send_getnodes(chat, chat->close[i].ip_port, peernum); 559 send_getnodes(chat, chat->close[i].ip_port, peernum);
562 } 560 }
563 } 561 }
@@ -565,6 +563,7 @@ static void ping_close(Group_Chat *chat)
565 563
566void do_groupchat(Group_Chat *chat) 564void do_groupchat(Group_Chat *chat)
567{ 565{
566 unix_time_update();
568 ping_close(chat); 567 ping_close(chat);
569} 568}
570 569
@@ -584,4 +583,3 @@ void chat_bootstrap_nonlazy(Group_Chat *chat, IP_Port ip_port, uint8_t *client_i
584 send_getnodes(chat, ip_port, addpeer(chat, client_id)); 583 send_getnodes(chat, ip_port, addpeer(chat, client_id));
585 add_closepeer(chat, client_id, ip_port); 584 add_closepeer(chat, client_id, ip_port);
586} 585}
587
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 14cee200..d58f4c27 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -29,7 +29,7 @@
29#endif 29#endif
30 30
31#include "net_crypto.h" 31#include "net_crypto.h"
32 32#include "util.h"
33static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection_id) 33static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection_id)
34{ 34{
35 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 35 return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
@@ -799,6 +799,8 @@ static void receive_crypto(Net_Crypto *c)
799 */ 799 */
800Net_Crypto *new_net_crypto(Networking_Core *net) 800Net_Crypto *new_net_crypto(Networking_Core *net)
801{ 801{
802 unix_time_update();
803
802 if (net == NULL) 804 if (net == NULL)
803 return NULL; 805 return NULL;
804 806
@@ -837,6 +839,7 @@ static void kill_timedout(Net_Crypto *c)
837/* Main loop. */ 839/* Main loop. */
838void do_net_crypto(Net_Crypto *c) 840void do_net_crypto(Net_Crypto *c)
839{ 841{
842 unix_time_update();
840 do_lossless_udp(c->lossless_udp); 843 do_lossless_udp(c->lossless_udp);
841 kill_timedout(c); 844 kill_timedout(c);
842 receive_crypto(c); 845 receive_crypto(c);
diff --git a/toxcore/network.c b/toxcore/network.c
index 640311b3..d163c0eb 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -277,6 +277,8 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl
277 277
278void networking_poll(Networking_Core *net) 278void networking_poll(Networking_Core *net)
279{ 279{
280 unix_time_update();
281
280 IP_Port ip_port; 282 IP_Port ip_port;
281 uint8_t data[MAX_UDP_PACKET_SIZE]; 283 uint8_t data[MAX_UDP_PACKET_SIZE];
282 uint32_t length; 284 uint32_t length;
diff --git a/toxcore/network.h b/toxcore/network.h
index c1418c4c..bb851dcb 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -99,12 +99,9 @@ typedef int sock_t;
99#define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */ 99#define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */
100 100
101#define TOX_PORTRANGE_FROM 33445 101#define TOX_PORTRANGE_FROM 33445
102#define TOX_PORTRANGE_TO 33455 102#define TOX_PORTRANGE_TO 33545
103#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM 103#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
104 104
105/* Current time, unix format */
106#define unix_time() ((uint64_t)time(NULL))
107
108typedef union { 105typedef union {
109 uint8_t uint8[4]; 106 uint8_t uint8[4];
110 uint16_t uint16[2]; 107 uint16_t uint16[2];
diff --git a/toxcore/ping.c b/toxcore/ping.c
index 240bd713..3f237836 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -64,7 +64,7 @@ typedef struct {
64 64
65static bool is_ping_timeout(uint64_t time) 65static bool is_ping_timeout(uint64_t time)
66{ 66{
67 return (time + PING_TIMEOUT) < now(); 67 return is_timeout(time, PING_TIMEOUT);
68} 68}
69 69
70static void remove_timeouts(PING *ping) // O(n) 70static void remove_timeouts(PING *ping) // O(n)
@@ -107,7 +107,7 @@ static uint64_t add_ping(PING *ping, IP_Port ipp) // O(n)
107 p = (ping->pos_pings + ping->num_pings) % PING_NUM_MAX; 107 p = (ping->pos_pings + ping->num_pings) % PING_NUM_MAX;
108 108
109 ping->pings[p].ip_port = ipp; 109 ping->pings[p].ip_port = ipp;
110 ping->pings[p].timestamp = now(); 110 ping->pings[p].timestamp = unix_time();
111 ping->pings[p].id = random_64b(); 111 ping->pings[p].id = random_64b();
112 112
113 ping->num_pings++; 113 ping->num_pings++;
@@ -146,14 +146,14 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
146 int rc; 146 int rc;
147 uint64_t ping_id; 147 uint64_t ping_id;
148 148
149 if (is_pinging(ping, ipp, 0) || id_eq(client_id, ping->c->self_public_key)) 149 if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->c->self_public_key))
150 return 1; 150 return 1;
151 151
152 // Generate random ping_id. 152 // Generate random ping_id.
153 ping_id = add_ping(ping, ipp); 153 ping_id = add_ping(ping, ipp);
154 154
155 pk[0] = NET_PACKET_PING_REQUEST; 155 pk[0] = NET_PACKET_PING_REQUEST;
156 id_cpy(pk + 1, ping->c->self_public_key); // Our pubkey 156 id_copy(pk + 1, ping->c->self_public_key); // Our pubkey
157 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 157 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
158 158
159 // Encrypt ping_id using recipient privkey 159 // Encrypt ping_id using recipient privkey
@@ -174,11 +174,11 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
174 uint8_t pk[DHT_PING_SIZE]; 174 uint8_t pk[DHT_PING_SIZE];
175 int rc; 175 int rc;
176 176
177 if (id_eq(client_id, ping->c->self_public_key)) 177 if (id_equal(client_id, ping->c->self_public_key))
178 return 1; 178 return 1;
179 179
180 pk[0] = NET_PACKET_PING_RESPONSE; 180 pk[0] = NET_PACKET_PING_RESPONSE;
181 id_cpy(pk + 1, ping->c->self_public_key); // Our pubkey 181 id_copy(pk + 1, ping->c->self_public_key); // Our pubkey
182 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 182 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
183 183
184 // Encrypt ping_id using recipient privkey 184 // Encrypt ping_id using recipient privkey
@@ -205,7 +205,7 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
205 205
206 PING *ping = dht->ping; 206 PING *ping = dht->ping;
207 207
208 if (id_eq(packet + 1, ping->c->self_public_key)) 208 if (id_equal(packet + 1, ping->c->self_public_key))
209 return 1; 209 return 1;
210 210
211 // Decrypt ping_id 211 // Decrypt ping_id
@@ -237,7 +237,7 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
237 237
238 PING *ping = dht->ping; 238 PING *ping = dht->ping;
239 239
240 if (id_eq(packet + 1, ping->c->self_public_key)) 240 if (id_equal(packet + 1, ping->c->self_public_key))
241 return 1; 241 return 1;
242 242
243 // Decrypt ping_id 243 // Decrypt ping_id
@@ -301,19 +301,12 @@ int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port)
301/* Ping all the valid nodes in the toping list every TIME_TOPING seconds. 301/* Ping all the valid nodes in the toping list every TIME_TOPING seconds.
302 * This function must be run at least once every TIME_TOPING seconds. 302 * This function must be run at least once every TIME_TOPING seconds.
303 */ 303 */
304static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
305{
306 return timestamp + timeout <= time_now;
307}
308
309void do_toping(PING *ping) 304void do_toping(PING *ping)
310{ 305{
311 uint64_t temp_time = unix_time(); 306 if (!is_timeout(ping->last_toping, TIME_TOPING))
312
313 if (!is_timeout(temp_time, ping->last_toping, TIME_TOPING))
314 return; 307 return;
315 308
316 ping->last_toping = temp_time; 309 ping->last_toping = unix_time();
317 uint32_t i; 310 uint32_t i;
318 311
319 for (i = 0; i < MAX_TOPING; ++i) { 312 for (i = 0; i < MAX_TOPING; ++i) {
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 2a26e7a6..5d3916b4 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -62,7 +62,7 @@ extern "C" {
62#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) 62#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
63 63
64#define TOX_PORTRANGE_FROM 33445 64#define TOX_PORTRANGE_FROM 33445
65#define TOX_PORTRANGE_TO 33455 65#define TOX_PORTRANGE_TO 33545
66#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM 66#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
67 67
68typedef union { 68typedef union {
@@ -521,7 +521,8 @@ uint64_t tox_file_dataremaining(Tox *tox, int friendnumber, uint8_t filenumber,
521void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); 521void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key);
522 522
523/* Resolves address into an IP address. If successful, sends a "get nodes" 523/* Resolves address into an IP address. If successful, sends a "get nodes"
524 * request to the given node with ip, port and public_key to setup connections 524 * request to the given node with ip, port (in network byte order, HINT: use htons())
525 * and public_key to setup connections
525 * 526 *
526 * address can be a hostname or an IP address (IPv4 or IPv6). 527 * address can be a hostname or an IP address (IPv4 or IPv6).
527 * if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses 528 * if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses
diff --git a/toxcore/util.c b/toxcore/util.c
index 620d1f4f..fab9f660 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -33,11 +33,6 @@
33 33
34#include "util.h" 34#include "util.h"
35 35
36uint64_t now()
37{
38 return time(NULL);
39}
40
41uint64_t random_64b() 36uint64_t random_64b()
42{ 37{
43 uint64_t r; 38 uint64_t r;
@@ -50,16 +45,39 @@ uint64_t random_64b()
50 return r; 45 return r;
51} 46}
52 47
53bool id_eq(uint8_t *dest, uint8_t *src) 48/* don't call into system billions of times for no reason */
49static uint64_t unix_time_value;
50
51void unix_time_update()
52{
53 unix_time_value = (uint64_t)time(NULL);
54}
55
56uint64_t unix_time()
57{
58 return unix_time_value;
59}
60
61int is_timeout(uint64_t timestamp, uint64_t timeout)
62{
63 return timestamp + timeout <= unix_time_value;
64}
65
66
67/* id functions */
68bool id_equal(uint8_t *dest, uint8_t *src)
54{ 69{
55 return memcmp(dest, src, CLIENT_ID_SIZE) == 0; 70 return memcmp(dest, src, CLIENT_ID_SIZE) == 0;
56} 71}
57 72
58void id_cpy(uint8_t *dest, uint8_t *src) 73uint32_t id_copy(uint8_t *dest, uint8_t *src)
59{ 74{
60 memcpy(dest, src, CLIENT_ID_SIZE); 75 memcpy(dest, src, CLIENT_ID_SIZE);
76 return CLIENT_ID_SIZE;
61} 77}
62 78
79
80/* state load/save */
63int load_state(load_state_callback_func load_state_callback, void *outer, 81int load_state(load_state_callback_func load_state_callback, void *outer,
64 uint8_t *data, uint32_t length, uint16_t cookie_inner) 82 uint8_t *data, uint32_t length, uint16_t cookie_inner)
65{ 83{
diff --git a/toxcore/util.h b/toxcore/util.h
index 97f82f60..20dcb2de 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -28,11 +28,19 @@
28#include <stdbool.h> 28#include <stdbool.h>
29#include <stdint.h> 29#include <stdint.h>
30 30
31uint64_t now();
32uint64_t random_64b(); 31uint64_t random_64b();
33bool id_eq(uint8_t *dest, uint8_t *src);
34void id_cpy(uint8_t *dest, uint8_t *src);
35 32
33void unix_time_update();
34uint64_t unix_time();
35int is_timeout(uint64_t timestamp, uint64_t timeout);
36
37
38/* id functions */
39bool id_equal(uint8_t *dest, uint8_t *src);
40uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */
41
42
43/* state load/save */
36typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type); 44typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type);
37int load_state(load_state_callback_func load_state_callback, void *outer, 45int load_state(load_state_callback_func load_state_callback, void *outer,
38 uint8_t *data, uint32_t length, uint16_t cookie_inner); 46 uint8_t *data, uint32_t length, uint16_t cookie_inner);