summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/Makefile.inc1
-rw-r--r--configure.ac11
-rw-r--r--other/DHT_bootstrap.c44
-rw-r--r--other/DHTnodes2
-rw-r--r--testing/DHT_test.c6
-rw-r--r--testing/Lossless_UDP_testclient.c260
-rw-r--r--testing/Lossless_UDP_testserver.c237
-rw-r--r--testing/Makefile.inc36
-rw-r--r--testing/crypto_speed_test.c4
-rw-r--r--toxav/Makefile.inc3
-rw-r--r--toxav/event.c7
-rw-r--r--toxav/media.h2
-rwxr-xr-xtoxav/msi.c22
-rwxr-xr-xtoxav/msi.h6
-rwxr-xr-xtoxav/rtp.c45
-rw-r--r--toxcore/DHT.c587
-rw-r--r--toxcore/DHT.h64
-rw-r--r--toxcore/LAN_discovery.c4
-rw-r--r--toxcore/Lossless_UDP.c1168
-rw-r--r--toxcore/Lossless_UDP.h261
-rw-r--r--toxcore/Makefile.inc7
-rw-r--r--toxcore/Messenger.c855
-rw-r--r--toxcore/Messenger.h41
-rw-r--r--toxcore/TCP_client.c398
-rw-r--r--toxcore/TCP_client.h71
-rw-r--r--toxcore/TCP_server.c216
-rw-r--r--toxcore/TCP_server.h19
-rw-r--r--toxcore/assoc.c2
-rw-r--r--toxcore/crypto_core.c262
-rw-r--r--toxcore/crypto_core.h142
-rw-r--r--toxcore/friend_requests.c22
-rw-r--r--toxcore/friend_requests.h5
-rw-r--r--toxcore/group_chats.c15
-rw-r--r--toxcore/group_chats.h2
-rw-r--r--toxcore/net_crypto.c2531
-rw-r--r--toxcore/net_crypto.h332
-rw-r--r--toxcore/network.c128
-rw-r--r--toxcore/network.h80
-rw-r--r--toxcore/onion.c174
-rw-r--r--toxcore/onion.h17
-rw-r--r--toxcore/onion_announce.c54
-rw-r--r--toxcore/onion_announce.h13
-rw-r--r--toxcore/onion_client.c356
-rw-r--r--toxcore/onion_client.h56
-rw-r--r--toxcore/ping.c247
-rw-r--r--toxcore/ping_array.c162
-rw-r--r--toxcore/ping_array.h75
-rw-r--r--toxcore/tox.c65
-rw-r--r--toxcore/tox.h73
-rw-r--r--toxcore/util.c37
50 files changed, 5123 insertions, 4104 deletions
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc
index 1f0f6697..5e101f60 100644
--- a/auto_tests/Makefile.inc
+++ b/auto_tests/Makefile.inc
@@ -15,6 +15,7 @@ AUTOTEST_LDADD = \
15 $(NACL_LDFLAGS) \ 15 $(NACL_LDFLAGS) \
16 libtoxcore.la \ 16 libtoxcore.la \
17 $(LIBSODIUM_LIBS) \ 17 $(LIBSODIUM_LIBS) \
18 $(NACL_OBJECTS) \
18 $(NACL_LIBS) \ 19 $(NACL_LIBS) \
19 $(CHECK_LIBS) 20 $(CHECK_LIBS)
20 21
diff --git a/configure.ac b/configure.ac
index 8650e197..7456617a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -427,6 +427,17 @@ AC_C_BIGENDIAN
427# Checks for library functions. 427# Checks for library functions.
428AC_FUNC_FORK 428AC_FUNC_FORK
429AC_CHECK_FUNCS([gettimeofday memset socket strchr malloc]) 429AC_CHECK_FUNCS([gettimeofday memset socket strchr malloc])
430if test "x$WIN32" != "xyes"; then
431 AC_CHECK_LIB(rt, clock_gettime,
432 [
433 RT_LIBS="-lrt"
434 AC_SUBST(RT_LIBS)
435 ],
436 [
437 AC_MSG_ERROR([required library rt was not found on your system])
438 ]
439 )
440fi
430 441
431if test "x$BUILD_AV" = "xyes"; then 442if test "x$BUILD_AV" = "xyes"; then
432 AX_PTHREAD( 443 AX_PTHREAD(
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c
index 291d6589..462360c3 100644
--- a/other/DHT_bootstrap.c
+++ b/other/DHT_bootstrap.c
@@ -31,6 +31,12 @@
31#include "../toxcore/friend_requests.h" 31#include "../toxcore/friend_requests.h"
32#include "../toxcore/util.h" 32#include "../toxcore/util.h"
33 33
34#define TCP_RELAY_ENABLED
35
36#ifdef TCP_RELAY_ENABLED
37#include "../toxcore/TCP_server.h"
38#endif
39
34#include "../testing/misc_tools.c" 40#include "../testing/misc_tools.c"
35 41
36#ifdef DHT_NODE_EXTRA_PACKETS 42#ifdef DHT_NODE_EXTRA_PACKETS
@@ -69,11 +75,12 @@ void manage_keys(DHT *dht)
69 exit(1); 75 exit(1);
70 } 76 }
71 77
72 load_keys(dht->c, keys); 78 memcpy(dht->self_public_key, keys, crypto_box_PUBLICKEYBYTES);
79 memcpy(dht->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
73 printf("Keys loaded successfully.\n"); 80 printf("Keys loaded successfully.\n");
74 } else { 81 } else {
75 new_keys(dht->c); 82 memcpy(keys, dht->self_public_key, crypto_box_PUBLICKEYBYTES);
76 save_keys(dht->c, keys); 83 memcpy(keys + crypto_box_PUBLICKEYBYTES, dht->self_secret_key, crypto_box_SECRETKEYBYTES);
77 keys_file = fopen("key", "w"); 84 keys_file = fopen("key", "w");
78 85
79 if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) { 86 if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) {
@@ -107,7 +114,7 @@ int main(int argc, char *argv[])
107 IP ip; 114 IP ip;
108 ip_init(&ip, ipv6enabled); 115 ip_init(&ip, ipv6enabled);
109 116
110 DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); 117 DHT *dht = new_DHT(new_networking(ip, PORT));
111 Onion *onion = new_onion(dht); 118 Onion *onion = new_onion(dht);
112 Onion_Announce *onion_a = new_onion_announce(dht); 119 Onion_Announce *onion_a = new_onion_announce(dht);
113 120
@@ -123,27 +130,33 @@ int main(int argc, char *argv[])
123 perror("Initialization"); 130 perror("Initialization");
124 131
125 manage_keys(dht); 132 manage_keys(dht);
126 /* We want our DHT public key to be the same as our internal one since this is a bootstrap node */
127 memcpy(dht->self_public_key, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
128 memcpy(dht->self_secret_key, dht->c->self_secret_key, crypto_box_SECRETKEYBYTES);
129 printf("Public key: "); 133 printf("Public key: ");
130 uint32_t i; 134 uint32_t i;
131 135
136#ifdef TCP_RELAY_ENABLED
137#define NUM_PORTS 3
138 uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
139 TCP_Server *tcp_s = new_TCP_server(ipv6enabled, NUM_PORTS, ports, dht->self_public_key, dht->self_secret_key, onion);
140
141 if (tcp_s == NULL) {
142 printf("TCP server failed to initialize.\n");
143 exit(1);
144 }
145
146#endif
147
132 FILE *file; 148 FILE *file;
133 file = fopen("PUBLIC_ID.txt", "w"); 149 file = fopen("PUBLIC_ID.txt", "w");
134 150
135 for (i = 0; i < 32; i++) { 151 for (i = 0; i < 32; i++) {
136 if (dht->c->self_public_key[i] < 16) 152 printf("%02hhX", dht->self_public_key[i]);
137 printf("0"); 153 fprintf(file, "%02hhX", dht->self_public_key[i]);
138
139 printf("%hhX", dht->c->self_public_key[i]);
140 fprintf(file, "%hhX", dht->c->self_public_key[i]);
141 } 154 }
142 155
143 fclose(file); 156 fclose(file);
144 157
145 printf("\n"); 158 printf("\n");
146 printf("Port: %u\n", ntohs(dht->c->lossless_udp->net->port)); 159 printf("Port: %u\n", ntohs(dht->net->port));
147 160
148 if (argc > argvoffset + 3) { 161 if (argc > argvoffset + 3) {
149 printf("Trying to bootstrap into the network...\n"); 162 printf("Trying to bootstrap into the network...\n");
@@ -177,7 +190,10 @@ int main(int argc, char *argv[])
177 last_LANdiscovery = unix_time(); 190 last_LANdiscovery = unix_time();
178 } 191 }
179 192
180 networking_poll(dht->c->lossless_udp->net); 193#ifdef TCP_RELAY_ENABLED
194 do_TCP_server(tcp_s);
195#endif
196 networking_poll(dht->net);
181 197
182 c_sleep(1); 198 c_sleep(1);
183 } 199 }
diff --git a/other/DHTnodes b/other/DHTnodes
index 35509931..0abdbbd9 100644
--- a/other/DHTnodes
+++ b/other/DHTnodes
@@ -1,3 +1,3 @@
1As maintaining 2 seperate lists of the same information seemed redundant, this list has been phased out. 1As maintaining 2 separate lists of the same information seemed redundant, this list has been phased out.
2 2
3For a current DHT node list please visit http://wiki.tox.im/nodes 3For a current DHT node list please visit http://wiki.tox.im/nodes
diff --git a/testing/DHT_test.c b/testing/DHT_test.c
index 3f8b58bd..2636ed02 100644
--- a/testing/DHT_test.c
+++ b/testing/DHT_test.c
@@ -187,9 +187,7 @@ int main(int argc, char *argv[])
187 IP ip; 187 IP ip;
188 ip_init(&ip, ipv6enabled); 188 ip_init(&ip, ipv6enabled);
189 189
190 DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); 190 DHT *dht = new_DHT(new_networking(ip, PORT));
191
192 new_keys(dht->c);
193 printf("OUR ID: "); 191 printf("OUR ID: ");
194 uint32_t i; 192 uint32_t i;
195 193
@@ -245,7 +243,7 @@ int main(int argc, char *argv[])
245 } 243 }
246 } 244 }
247 */ 245 */
248 networking_poll(dht->c->lossless_udp->net); 246 networking_poll(dht->net);
249 247
250 print_clientlist(dht); 248 print_clientlist(dht);
251 print_friendlist(dht); 249 print_friendlist(dht);
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c
deleted file mode 100644
index 535509e0..00000000
--- a/testing/Lossless_UDP_testclient.c
+++ /dev/null
@@ -1,260 +0,0 @@
1/* Lossless_UDP testclient
2 * A program that connects and sends a file using our lossless UDP algorithm.
3 * NOTE: this program simulates a 33% packet loss.
4 *
5 * Best used in combination with Lossless_UDP_testserver
6 *
7 * Compile with: gcc -O2 -Wall -lsodium -o testclient ../toxcore/network.c ../toxcore/Lossless_UDP.c ../toxcore/util.c Lossless_UDP_testclient.c
8 *
9 * Command line arguments are the ip and port to connect and send the file to.
10 * EX: ./testclient --ipv4 127.0.0.1 33445 filename.txt
11 *
12 * Copyright (C) 2013 Tox project All Rights Reserved.
13 *
14 * This file is part of Tox.
15 *
16 * Tox is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * Tox is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
28 *
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "../toxcore/network.h"
36#include "../toxcore/Lossless_UDP.h"
37#include "../toxcore/util.h"
38#include "misc_tools.c"
39
40#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
41
42#define c_sleep(x) Sleep(1*x)
43
44#else
45#include <unistd.h>
46#include <arpa/inet.h>
47#define c_sleep(x) usleep(1000*x)
48
49#endif
50
51#define PORT 33446
52
53void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
54{
55 uint32_t i;
56 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
57 printf("--------------------BEGIN-----------------------------\n");
58
59 for (i = 0; i < length; i++) {
60 if (data[i] < 16)
61 printf("0");
62
63 printf("%hhX", data[i]);
64 }
65
66 printf("\n--------------------END-----------------------------\n\n\n");
67}
68
69void printip(IP_Port ip_port)
70{
71 printf("\nIP: %s Port: %u", ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
72}
73/*
74void printpackets(Data test)
75{
76 int i;
77 if(test.size == 0)
78 return;
79 printf("SIZE: %u\n", test.size);
80 for(i =0; i < test.size; i++)
81 {
82 printf("%hhX", test.data[i]);
83 }
84 printf("\n");
85}
86
87void printconnection(int connection_id)
88{
89 printf("--------------------BEGIN---------------------\n");
90 IP_Port ip_port = connections[connection_id].ip_port;
91 printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
92 printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status,
93 connections[connection_id].inbound, connections[connection_id].SYNC_rate);
94 printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate,
95 connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv);
96 int i;
97 for(i =0; i < MAX_QUEUE_NUM; i++)
98 {
99 printf(" %u ",i);
100 printpackets(connections[connection_id].sendbuffer[i]);
101 }
102 for(i =0; i < MAX_QUEUE_NUM; i++)
103 {
104 printf(" %u ",i);
105 printpackets(connections[connection_id].recvbuffer[i]);
106 }
107 Data sendbuffer[MAX_QUEUE_NUM];
108 Data recvbuffer[MAX_QUEUE_NUM];
109 printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
110 connections[connection_id].recv_packetnum,
111 connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
112 connections[connection_id].successful_sent,
113 connections[connection_id].successful_read);
114
115 printf("req packets: \n");
116 for(i = 0; i < BUFFER_PACKET_NUM; i++)
117 {
118 printf(" %u ", connections[connection_id].req_packets[i]);
119 }
120 printf("\nNumber: %u recv_counter: %u, send_counter: %u\n", connections[connection_id].num_req_paquets,
121 connections[connection_id].recv_counter, connections[connection_id].send_counter);
122
123 printf("--------------------END---------------------\n");
124
125}
126*/
127
128/*( receive packets and send them to the packethandler */
129/*run doLossless_UDP(); */
130//void Lossless_UDP()
131//{
132/* IP_Port ip_port;
133 uint8_t data[MAX_UDP_PACKET_SIZE];
134 uint32_t length;
135 while (receivepacket(&ip_port, data, &length) != -1) {
136 printf("packet with length: %u\n", length); */
137/* if(rand() % 3 != 1)//add packet loss
138 { */
139/*
140 if (LosslessUDP_handlepacket(data, length, ip_port))
141 printpacket(data, length, ip_port);
142 else
143 printf("Received handled packet with length: %u\n", length); //printconnection(0); */
144
145/* } */
146/* }*/
147
148//networking_poll();
149
150//doLossless_UDP();
151
152//}
153
154int main(int argc, char *argv[])
155{
156 /* let user override default by cmdline */
157 uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
158 int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
159
160 if (argvoffset < 0)
161 exit(1);
162
163 if (argc < argvoffset + 4) {
164 printf("Usage: %s [--ipv4|--ipv6] ip port filename\n", argv[0]);
165 exit(0);
166 }
167
168 uint8_t buffer[MAX_DATA_SIZE];
169 int read;
170
171 FILE *file = fopen(argv[argvoffset + 3], "rb");
172
173 if (file == NULL) {
174 printf("Failed to open file \"%s\".\n", argv[argvoffset + 3]);
175 return 1;
176 }
177
178
179 /* initialize networking */
180 /* bind to ip 0.0.0.0:PORT */
181 IP ip;
182 ip_init(&ip, ipv6enabled);
183
184 Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
185 perror("Initialization");
186
187 IP_Port serverip;
188 ip_init(&serverip.ip, ipv6enabled);
189
190 if (!addr_resolve(argv[argvoffset + 1], &serverip.ip, NULL)) {
191 printf("Failed to convert \"%s\" into an IP address.\n", argv[argvoffset + 1]);
192 return 1;
193 }
194
195 serverip.port = htons(atoi(argv[argvoffset + 2]));
196 printip(serverip);
197
198 int connection = new_connection(ludp, serverip);
199 uint64_t timer = current_time();
200
201 while (1) {
202 /* printconnection(connection); */
203 networking_poll(ludp->net);
204 do_lossless_udp(ludp);
205
206 if (is_connected(ludp, connection) == LUDP_ESTABLISHED) {
207 printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer));
208 break;
209 }
210
211 if (is_connected(ludp, connection) == LUDP_NO_CONNECTION) {
212 printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
213 return 1;
214 }
215
216 c_sleep(1);
217 }
218
219 timer = current_time();
220 unsigned long long bytes_sent = 0;
221
222 /*read first part of file */
223 read = fread(buffer, 1, MAX_DATA_SIZE, file);
224
225 while (1) {
226 /* printconnection(connection); */
227 networking_poll(ludp->net);
228 do_lossless_udp(ludp);
229
230 if (is_connected(ludp, connection) == LUDP_ESTABLISHED) {
231
232 while (write_packet(ludp, connection, buffer, read)) {
233 bytes_sent += read;
234 /* printf("Wrote data.\n"); */
235 read = fread(buffer, 1, MAX_DATA_SIZE, file);
236
237 }
238
239 /* printf("%u\n", sendqueue(connection)); */
240 if (sendqueue(ludp, connection) == 0) {
241 if (read == 0) {
242 unsigned long long us = (unsigned long long)(current_time() - timer);
243 printf("Sent file successfully in: %llu us = %llu seconds. Average speed: %llu KB/s\n", us, us / 1000000UL,
244 bytes_sent / (us / 1024UL));
245 //printf("Total bytes sent: %llu B, Total data sent: %llu B, overhead: %llu B\n", total_bytes_sent, bytes_sent, total_bytes_sent-bytes_sent);
246 break;
247 }
248 }
249 } else {
250 printf("%u Client Connecting Lost after: %llu us\n", is_connected(ludp, connection),
251 (unsigned long long)(current_time() - timer));
252 return 0;
253 }
254
255 }
256
257 c_sleep(25);
258
259 return 0;
260}
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c
deleted file mode 100644
index dd4612f5..00000000
--- a/testing/Lossless_UDP_testserver.c
+++ /dev/null
@@ -1,237 +0,0 @@
1/* Lossless_UDP testserver
2 * A program that waits for a lossless UDP connection and then saves all the data received to a file.
3 * NOTE: this program simulates a 33% packet loss.
4 *
5 * Best used in combination with Lossless_UDP_testclient
6 *
7 * Compile with: gcc -O2 -Wall -lsodium -o testserver ../toxcore/network.c ../toxcore/Lossless_UDP.c ../toxcore/util.c Lossless_UDP_testserver.c
8 *
9 * Command line argument is the name of the file to save what we receive to.
10 * EX: ./testserver filename1.txt
11 *
12 * Copyright (C) 2013 Tox project All Rights Reserved.
13 *
14 * This file is part of Tox.
15 *
16 * Tox is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * Tox is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
28 *
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "../toxcore/network.h"
36#include "../toxcore/Lossless_UDP.h"
37#include "../toxcore/util.h"
38#include "misc_tools.c"
39
40//Sleep function (x = milliseconds)
41#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
42
43#define c_sleep(x) Sleep(1*x)
44
45#else
46#include <unistd.h>
47#include <arpa/inet.h>
48#define c_sleep(x) usleep(1000*x)
49
50#endif
51
52#define PORT 33445
53
54void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
55{
56 uint32_t i;
57 printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
58 printf("--------------------BEGIN-----------------------------\n");
59
60 for (i = 0; i < length; i++) {
61 if (data[i] < 16)
62 printf("0");
63
64 printf("%hhX", data[i]);
65 }
66
67 printf("\n--------------------END-----------------------------\n\n\n");
68}
69
70/*
71void printpackets(Data test)
72{
73 int i;
74 if(test.size == 0)
75 return;
76 printf("SIZE: %u\n", test.size);
77 for(i =0; i < test.size; i++)
78 {
79 printf("%hhX", test.data[i]);
80 }
81 printf("\n");
82}
83
84void printconnection(int connection_id)
85{
86 printf("--------------------BEGIN---------------------\n");
87 IP_Port ip_port = connections[connection_id].ip_port;
88 printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
89 printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status,
90 connections[connection_id].inbound, connections[connection_id].SYNC_rate);
91 printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate,
92 connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv);
93 int i;
94 for(i =0; i < MAX_QUEUE_NUM; i++)
95 {
96 printf(" %u ",i);
97 printpackets(connections[connection_id].sendbuffer[i]);
98 }
99 for(i =0; i < MAX_QUEUE_NUM; i++)
100 {
101 printf(" %u ",i);
102 printpackets(connections[connection_id].recvbuffer[i]);
103 }
104 Data sendbuffer[MAX_QUEUE_NUM];
105 Data recvbuffer[MAX_QUEUE_NUM];
106 printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
107 connections[connection_id].recv_packetnum,
108 connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
109 connections[connection_id].successful_sent,
110 connections[connection_id].successful_read);
111
112 printf("req packets: \n");
113 for(i = 0; i < BUFFER_PACKET_NUM; i++)
114 {
115 printf(" %u ", connections[connection_id].req_packets[i]);
116 }
117 printf("\nNumber: %u recv_counter: %u, send_counter: %u\n", connections[connection_id].num_req_paquets,
118 connections[connection_id].recv_counter, connections[connection_id].send_counter);
119
120 printf("--------------------END---------------------\n");
121
122}
123*/
124
125/* receive packets and send them to the packethandler
126 * run doLossless_UDP(); */
127//void Lossless_UDP()
128//{
129// IP_Port ip_port;
130// uint8_t data[MAX_UDP_PACKET_SIZE];
131// uint32_t length;
132// while (receivepacket(&ip_port, data, &length) != -1) {
133//if(rand() % 3 != 1)//add packet loss
134//{
135// if (LosslessUDP_handlepacket(data, length, ip_port)) {
136// printpacket(data, length, ip_port);
137// } else {
138//printconnection(0);
139// printf("Received handled packet with length: %u\n", length);
140// }
141//}
142// }
143
144// networking_poll();
145
146//doLossless_UDP();
147//}
148
149
150int main(int argc, char *argv[])
151{
152 /* let user override default by cmdline */
153 uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
154 int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
155
156 if (argvoffset < 0)
157 exit(1);
158
159 if (argc < argvoffset + 2) {
160 printf("Usage: %s [--ipv4|--ipv6] filename\n", argv[0]);
161 exit(0);
162 }
163
164 uint8_t buffer[MAX_DATA_SIZE];
165 int read;
166
167 FILE *file = fopen(argv[argvoffset + 1], "wb");
168
169 if (file == NULL) {
170 printf("Failed to open file \"%s\".\n", argv[argvoffset + 1]);
171 return 1;
172 }
173
174
175 //initialize networking
176 //bind to ip 0.0.0.0:PORT
177 IP ip;
178 ip_init(&ip, ipv6enabled);
179
180 Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT));
181 perror("Initialization");
182
183 int connection;
184 uint64_t timer = current_time();
185
186 while (1) {
187 networking_poll(ludp->net);
188 do_lossless_udp(ludp);
189 connection = incoming_connection(ludp, 0);
190
191 if (connection != -1) {
192 if (is_connected(ludp, connection) == LUDP_NOT_CONFIRMED) {
193 printf("Received the connection.\n");
194
195 }
196
197 break;
198 }
199
200 c_sleep(1);
201 }
202
203 timer = current_time();
204
205 while (1) {
206 //printconnection(0);
207 networking_poll(ludp->net);
208
209 if (is_connected(ludp, connection) >= LUDP_NOT_CONFIRMED) {
210 confirm_connection(ludp, connection);
211
212 while (1) {
213 read = read_packet(ludp, connection, buffer);
214
215 if (read != 0) {
216 // printf("Received data.\n");
217 if (!fwrite(buffer, read, 1, file))
218 printf("file write error\n");
219 } else {
220 break;
221 }
222 }
223 }
224
225 do_lossless_udp(ludp);
226
227 if (is_connected(ludp, connection) == LUDP_TIMED_OUT) {
228 printf("Server Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
229 fclose(file);
230 return 1;
231 }
232
233 c_sleep(25);
234 }
235
236 return 0;
237}
diff --git a/testing/Makefile.inc b/testing/Makefile.inc
index 812a5be1..b3912033 100644
--- a/testing/Makefile.inc
+++ b/testing/Makefile.inc
@@ -22,8 +22,6 @@ endif
22if BUILD_TESTING 22if BUILD_TESTING
23 23
24noinst_PROGRAMS += DHT_test \ 24noinst_PROGRAMS += DHT_test \
25 Lossless_UDP_testclient \
26 Lossless_UDP_testserver \
27 Messenger_test \ 25 Messenger_test \
28 crypto_speed_test 26 crypto_speed_test
29 27
@@ -41,40 +39,6 @@ DHT_test_LDADD = $(LIBSODIUM_LDFLAGS) \
41 $(WINSOCK2_LIBS) 39 $(WINSOCK2_LIBS)
42 40
43 41
44Lossless_UDP_testclient_SOURCES = \
45 ../testing/Lossless_UDP_testclient.c
46
47Lossless_UDP_testclient_CFLAGS = \
48 $(LIBSODIUM_CFLAGS) \
49 $(NACL_CFLAGS)
50
51Lossless_UDP_testclient_LDADD = \
52 $(LIBSODIUM_LDFLAGS) \
53 $(NACL_LDFLAGS) \
54 libtoxcore.la \
55 $(LIBSODIUM_LIBS) \
56 $(NACL_OBJECTS) \
57 $(NACL_LIBS) \
58 $(WINSOCK2_LIBS)
59
60
61Lossless_UDP_testserver_SOURCES = \
62 ../testing/Lossless_UDP_testserver.c
63
64Lossless_UDP_testserver_CFLAGS = \
65 $(LIBSODIUM_CFLAGS) \
66 $(NACL_CFLAGS)
67
68Lossless_UDP_testserver_LDADD = \
69 $(LIBSODIUM_LDFLAGS) \
70 $(NACL_LDFLAGS) \
71 libtoxcore.la \
72 $(LIBSODIUM_LIBS) \
73 $(NACL_OBJECTS) \
74 $(NACL_LIBS) \
75 $(WINSOCK2_LIBS)
76
77
78Messenger_test_SOURCES = \ 42Messenger_test_SOURCES = \
79 ../testing/Messenger_test.c 43 ../testing/Messenger_test.c
80 44
diff --git a/testing/crypto_speed_test.c b/testing/crypto_speed_test.c
index 60ff1937..3e81a46b 100644
--- a/testing/crypto_speed_test.c
+++ b/testing/crypto_speed_test.c
@@ -97,8 +97,8 @@ int main(int argc, char *argv[])
97 starttime = get_time(); 97 starttime = get_time();
98 98
99 for (trialno = 0; trialno < numtrials; trialno++) { 99 for (trialno = 0; trialno < numtrials; trialno++) {
100 encrypt_data_fast(k1, n, m, sizeof(m), c); 100 encrypt_data_symmetric(k1, n, m, sizeof(m), c);
101 decrypt_data_fast(k2, n, c, sizeof(c), m); 101 decrypt_data_symmetric(k2, n, c, sizeof(c), m);
102 } 102 }
103 103
104 endtime = get_time(); 104 endtime = get_time();
diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc
index 060a760c..2d48d210 100644
--- a/toxav/Makefile.inc
+++ b/toxav/Makefile.inc
@@ -18,15 +18,18 @@ libtoxav_la_SOURCES = ../toxav/event.h \
18 18
19libtoxav_la_CFLAGS = -I../toxcore \ 19libtoxav_la_CFLAGS = -I../toxcore \
20 -I../toxav \ 20 -I../toxav \
21 $(LIBSODIUM_CFLAGS) \
21 $(NACL_CFLAGS) \ 22 $(NACL_CFLAGS) \
22 $(AV_CFLAGS) \ 23 $(AV_CFLAGS) \
23 $(PTHREAD_CFLAGS) 24 $(PTHREAD_CFLAGS)
24 25
25libtoxav_la_LDFLAGS = $(TOXAV_LT_LDFLAGS) \ 26libtoxav_la_LDFLAGS = $(TOXAV_LT_LDFLAGS) \
27 $(LIBSODIUM_LDFLAGS) \
26 $(NACL_LDFLAGS) \ 28 $(NACL_LDFLAGS) \
27 $(EXTRA_LT_LDFLAGS) 29 $(EXTRA_LT_LDFLAGS)
28 30
29libtoxav_la_LIBADD = libtoxcore.la \ 31libtoxav_la_LIBADD = libtoxcore.la \
32 $(LIBSODIUM_LIBS) \
30 $(NACL_LIBS) \ 33 $(NACL_LIBS) \
31 $(PTHREAD_LIBS) \ 34 $(PTHREAD_LIBS) \
32 $(AV_LIBS) 35 $(AV_LIBS)
diff --git a/toxav/event.c b/toxav/event.c
index ffda35ec..35af98bb 100644
--- a/toxav/event.c
+++ b/toxav/event.c
@@ -27,6 +27,7 @@
27#endif /* HAVE_CONFIG_H */ 27#endif /* HAVE_CONFIG_H */
28 28
29#include <stdlib.h> 29#include <stdlib.h>
30#include "../toxcore/network.h" /* current_time_monotonic() */
30#include "event.h" 31#include "event.h"
31 32
32#define _GNU_SOURCE 33#define _GNU_SOURCE
@@ -199,7 +200,7 @@ void *event_poll( void *arg )
199 200
200 if ( _event_handler->timed_events ) { 201 if ( _event_handler->timed_events ) {
201 202
202 uint32_t _time = ((uint32_t)(current_time() / 1000)); 203 uint32_t _time = ((uint32_t)current_time_monotonic());
203 204
204 if ( _event_handler->timed_events[0].timeout < _time ) { 205 if ( _event_handler->timed_events[0].timeout < _time ) {
205 206
@@ -249,7 +250,7 @@ int throw_timer_event ( void * (func)(void *), void *arg, unsigned timeout)
249 250
250 size_t _counter = event_handler.timed_events_count; 251 size_t _counter = event_handler.timed_events_count;
251 252
252 event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)(current_time() / 1000)); 253 event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)current_time_monotonic());
253 event_handler.timed_events[_counter - 1].id = _unique_id; 254 event_handler.timed_events[_counter - 1].id = _unique_id;
254 ++_unique_id; 255 ++_unique_id;
255 256
@@ -330,7 +331,7 @@ int reset_timer_event ( int id, uint32_t timeout )
330 /* Find it and change */ 331 /* Find it and change */
331 for ( ; _i; _i-- ) { 332 for ( ; _i; _i-- ) {
332 if ( _it->id == id ) { 333 if ( _it->id == id ) {
333 _it->timeout = timeout + ((uint32_t)(current_time() / 1000)); 334 _it->timeout = timeout + ((uint32_t)current_time_monotonic());
334 break; 335 break;
335 } 336 }
336 337
diff --git a/toxav/media.h b/toxav/media.h
index a1193aae..8dc495ed 100644
--- a/toxav/media.h
+++ b/toxav/media.h
@@ -36,7 +36,7 @@
36#define VIDEO_CODEC_ENCODER_INTERFACE (vpx_codec_vp8_cx()) 36#define VIDEO_CODEC_ENCODER_INTERFACE (vpx_codec_vp8_cx())
37 37
38/* Audio encoding/decoding */ 38/* Audio encoding/decoding */
39#include <opus/opus.h> 39#include <opus.h>
40 40
41typedef enum _Capabilities 41typedef enum _Capabilities
42{ 42{
diff --git a/toxav/msi.c b/toxav/msi.c
index c2d50302..aab13471 100755
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -28,8 +28,6 @@
28 28
29#include "../toxcore/logger.h" 29#include "../toxcore/logger.h"
30 30
31/*#define _BSD_SOURCE*/
32
33#include "msi.h" 31#include "msi.h"
34#include "event.h" 32#include "event.h"
35 33
@@ -219,7 +217,7 @@ static inline__ const uint8_t *stringify_response ( MSIResponse response )
219 * @param msg Container. 217 * @param msg Container.
220 * @param data The data. 218 * @param data The data.
221 * @return int 219 * @return int
222 * @retval -1 Error occured. 220 * @retval -1 Error occurred.
223 * @retval 0 Success. 221 * @retval 0 Success.
224 */ 222 */
225int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) 223int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
@@ -354,7 +352,7 @@ void free_message ( MSIMessage *msg )
354 * @param type Request or response. 352 * @param type Request or response.
355 * @param type_id Type of request/response. 353 * @param type_id Type of request/response.
356 * @return MSIMessage* Created message. 354 * @return MSIMessage* Created message.
357 * @retval NULL Error occured. 355 * @retval NULL Error occurred.
358 */ 356 */
359MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id ) 357MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id )
360{ 358{
@@ -387,7 +385,7 @@ MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id )
387 * 385 *
388 * @param data The data. 386 * @param data The data.
389 * @return MSIMessage* Parsed message. 387 * @return MSIMessage* Parsed message.
390 * @retval NULL Error occured. 388 * @retval NULL Error occurred.
391 */ 389 */
392MSIMessage *parse_message ( const uint8_t *data, uint16_t length ) 390MSIMessage *parse_message ( const uint8_t *data, uint16_t length )
393{ 391{
@@ -495,7 +493,7 @@ uint8_t *append_header_to_string (
495 493
496 *dest = field_byte; /* Set the first byte */ 494 *dest = field_byte; /* Set the first byte */
497 495
498 uint8_t *_getback_byte = dest + 1; /* remeber the byte we were on */ 496 uint8_t *_getback_byte = dest + 1; /* remember the byte we were on */
499 dest += 3; /* swith to 4th byte where field value starts */ 497 dest += 3; /* swith to 4th byte where field value starts */
500 498
501 /* Now set the field value and calculate it's length */ 499 /* Now set the field value and calculate it's length */
@@ -685,7 +683,7 @@ static inline__ const uint8_t *stringify_error_code ( MSICallError error_code )
685 * @param msg The message. 683 * @param msg The message.
686 * @param to Where to. 684 * @param to Where to.
687 * @return int 685 * @return int
688 * @retval -1 Error occured. 686 * @retval -1 Error occurred.
689 * @retval 0 Success. 687 * @retval 0 Success.
690 */ 688 */
691int send_message ( MSISession *session, MSICall* call, MSIMessage *msg, uint32_t to ) 689int send_message ( MSISession *session, MSICall* call, MSIMessage *msg, uint32_t to )
@@ -838,7 +836,7 @@ int handle_error ( MSISession *session, MSICall* call, MSICallError errid, uint3
838 * @param msg The message. 836 * @param msg The message.
839 * @return int 837 * @return int
840 * @retval -1 No error. 838 * @retval -1 No error.
841 * @retval 0 Error occured and response sent. 839 * @retval 0 Error occurred and response sent.
842 */ 840 */
843int has_call_error ( MSISession *session, MSICall* call, MSIMessage *msg ) 841int has_call_error ( MSISession *session, MSICall* call, MSIMessage *msg )
844{ 842{
@@ -951,7 +949,7 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
951 * 949 *
952 * @param session Control session. 950 * @param session Control session.
953 * @return int 951 * @return int
954 * @retval -1 Error occured. 952 * @retval -1 Error occurred.
955 * @retval 0 Success. 953 * @retval 0 Success.
956 */ 954 */
957int terminate_call ( MSISession *session, MSICall *call ) 955int terminate_call ( MSISession *session, MSICall *call )
@@ -1031,7 +1029,7 @@ int handle_recv_invite ( MSISession *session, MSICall* call, MSIMessage *msg )
1031 * B calls A. Who has advantage is set bey calculating 1029 * B calls A. Who has advantage is set bey calculating
1032 * 'bigger' Call id and then that call id is being used in 1030 * 'bigger' Call id and then that call id is being used in
1033 * future. User with 'bigger' Call id has the advantage 1031 * future. User with 'bigger' Call id has the advantage
1034 * as in he will wait the reponse from the other. 1032 * as in he will wait the response from the other.
1035 */ 1033 */
1036 1034
1037 if ( call_id_bigger (call->id, msg->callid.header_value) == 1 ) { /* Peer has advantage */ 1035 if ( call_id_bigger (call->id, msg->callid.header_value) == 1 ) { /* Peer has advantage */
@@ -1408,7 +1406,7 @@ void msi_register_callback ( MSICallback callback, MSICallbackID id, void* userd
1408 * @param messenger Tox* object. 1406 * @param messenger Tox* object.
1409 * @param max_calls Amount of calls possible 1407 * @param max_calls Amount of calls possible
1410 * @return MSISession* The created session. 1408 * @return MSISession* The created session.
1411 * @retval NULL Error occured. 1409 * @retval NULL Error occurred.
1412 */ 1410 */
1413MSISession *msi_init_session ( Messenger* messenger, int32_t max_calls ) 1411MSISession *msi_init_session ( Messenger* messenger, int32_t max_calls )
1414{ 1412{
@@ -1530,7 +1528,7 @@ int msi_invite ( MSISession* session, int32_t* call_index, MSICallType call_type
1530 * @param session Control session. 1528 * @param session Control session.
1531 * @param call_id To which call is this action handled. 1529 * @param call_id To which call is this action handled.
1532 * @return int 1530 * @return int
1533 * @retval -1 Error occured. 1531 * @retval -1 Error occurred.
1534 * @retval 0 Success. 1532 * @retval 0 Success.
1535 */ 1533 */
1536int msi_hangup ( MSISession* session, int32_t call_index ) 1534int msi_hangup ( MSISession* session, int32_t call_index )
diff --git a/toxav/msi.h b/toxav/msi.h
index 2a7c5ba8..e9e1b4d7 100755
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -84,7 +84,7 @@ typedef struct _MSICall { /* Call info structure */
84 int ringing_timer_id; /* Timer id for ringing timeout */ 84 int ringing_timer_id; /* Timer id for ringing timeout */
85 85
86 pthread_mutex_t mutex; /* It's to be assumed that call will have 86 pthread_mutex_t mutex; /* It's to be assumed that call will have
87 * seperate thread so add mutex 87 * separate thread so add mutex
88 */ 88 */
89 uint32_t *peers; 89 uint32_t *peers;
90 uint16_t peer_count; 90 uint16_t peer_count;
@@ -156,7 +156,7 @@ void msi_register_callback(MSICallback callback, MSICallbackID id, void* userdat
156 * @param messenger Tox* object. 156 * @param messenger Tox* object.
157 * @param max_calls Amount of calls possible 157 * @param max_calls Amount of calls possible
158 * @return MSISession* The created session. 158 * @return MSISession* The created session.
159 * @retval NULL Error occured. 159 * @retval NULL Error occurred.
160 */ 160 */
161MSISession *msi_init_session ( Messenger *messenger, int32_t max_calls ); 161MSISession *msi_init_session ( Messenger *messenger, int32_t max_calls );
162 162
@@ -189,7 +189,7 @@ int msi_invite ( MSISession *session, int32_t* call_index, MSICallType call_type
189 * @param session Control session. 189 * @param session Control session.
190 * @param call_index To which call is this action handled. 190 * @param call_index To which call is this action handled.
191 * @return int 191 * @return int
192 * @retval -1 Error occured. 192 * @retval -1 Error occurred.
193 * @retval 0 Success. 193 * @retval 0 Success.
194 */ 194 */
195int msi_hangup ( MSISession *session, int32_t call_index ); 195int msi_hangup ( MSISession *session, int32_t call_index );
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 8b2768f1..cdaabd3a 100755
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -170,8 +170,8 @@ inline__ void increase_nonce(uint8_t *nonce, uint16_t target)
170 uint16_t _nonce_counter; 170 uint16_t _nonce_counter;
171 171
172 uint8_t _reverse_bytes[2]; 172 uint8_t _reverse_bytes[2];
173 _reverse_bytes[0] = nonce[crypto_secretbox_NONCEBYTES - 1]; 173 _reverse_bytes[0] = nonce[crypto_box_NONCEBYTES - 1];
174 _reverse_bytes[1] = nonce[crypto_secretbox_NONCEBYTES - 2]; 174 _reverse_bytes[1] = nonce[crypto_box_NONCEBYTES - 2];
175 175
176 bytes_to_U16(&_nonce_counter, _reverse_bytes ); 176 bytes_to_U16(&_nonce_counter, _reverse_bytes );
177 177
@@ -179,8 +179,8 @@ inline__ void increase_nonce(uint8_t *nonce, uint16_t target)
179 if (_nonce_counter > UINT16_MAX - target ) { /* 2 bytes are not long enough */ 179 if (_nonce_counter > UINT16_MAX - target ) { /* 2 bytes are not long enough */
180 uint8_t _it = 3; 180 uint8_t _it = 3;
181 181
182 while ( _it <= crypto_secretbox_NONCEBYTES ) _it += ++nonce[crypto_secretbox_NONCEBYTES - _it] ? 182 while ( _it <= crypto_box_NONCEBYTES ) _it += ++nonce[crypto_box_NONCEBYTES - _it] ?
183 crypto_secretbox_NONCEBYTES : 1; 183 crypto_box_NONCEBYTES : 1;
184 184
185 _nonce_counter = _nonce_counter - (UINT16_MAX - target ); /* Assign the rest of it */ 185 _nonce_counter = _nonce_counter - (UINT16_MAX - target ); /* Assign the rest of it */
186 } else { /* Increase nonce */ 186 } else { /* Increase nonce */
@@ -191,8 +191,8 @@ inline__ void increase_nonce(uint8_t *nonce, uint16_t target)
191 /* Assign the last bytes */ 191 /* Assign the last bytes */
192 192
193 U16_to_bytes( _reverse_bytes, _nonce_counter); 193 U16_to_bytes( _reverse_bytes, _nonce_counter);
194 nonce [crypto_secretbox_NONCEBYTES - 1] = _reverse_bytes[0]; 194 nonce [crypto_box_NONCEBYTES - 1] = _reverse_bytes[0];
195 nonce [crypto_secretbox_NONCEBYTES - 2] = _reverse_bytes[1]; 195 nonce [crypto_box_NONCEBYTES - 2] = _reverse_bytes[1];
196 196
197} 197}
198 198
@@ -416,7 +416,7 @@ RTPHeader *build_header ( RTPSession *session )
416 ADD_SETTING_PAYLOAD ( _retu, session->payload_type ); 416 ADD_SETTING_PAYLOAD ( _retu, session->payload_type );
417 417
418 _retu->sequnum = session->sequnum; 418 _retu->sequnum = session->sequnum;
419 _retu->timestamp = ((uint32_t)(current_time() / 1000)); /* micro to milli */ 419 _retu->timestamp = current_time_monotonic(); /* milliseconds */
420 _retu->ssrc = session->ssrc; 420 _retu->ssrc = session->ssrc;
421 421
422 int i; 422 int i;
@@ -505,7 +505,7 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
505 RTPSession *_session = object; 505 RTPSession *_session = object;
506 RTPMessage *_msg; 506 RTPMessage *_msg;
507 507
508 if ( !_session || length < 13 + crypto_secretbox_MACBYTES) { /* 12 is the minimum length for rtp + desc. byte */ 508 if ( !_session || length < 13 + crypto_box_MACBYTES) { /* 12 is the minimum length for rtp + desc. byte */
509 LOGGER_WARNING("No session or invalid length of received buffer!"); 509 LOGGER_WARNING("No session or invalid length of received buffer!");
510 return -1; 510 return -1;
511 } 511 }
@@ -521,12 +521,13 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
521 bytes_to_U16(&_sequnum, data + 1); 521 bytes_to_U16(&_sequnum, data + 1);
522 522
523 /* Clculate the right nonce */ 523 /* Clculate the right nonce */
524 uint8_t _calculated[crypto_secretbox_NONCEBYTES]; 524 uint8_t _calculated[crypto_box_NONCEBYTES];
525 memcpy(_calculated, _session->decrypt_nonce, crypto_secretbox_NONCEBYTES); 525 memcpy(_calculated, _session->decrypt_nonce, crypto_box_NONCEBYTES);
526 increase_nonce ( _calculated, _sequnum ); 526 increase_nonce ( _calculated, _sequnum );
527 527
528 /* Decrypt message */ 528 /* Decrypt message */
529 int _decrypted_length = decrypt_data_symmetric((uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain ); 529 int _decrypted_length = decrypt_data_symmetric(
530 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
530 531
531 /* This packet is either not encrypted properly or late 532 /* This packet is either not encrypted properly or late
532 */ 533 */
@@ -557,8 +558,8 @@ int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t l
557 } 558 }
558 559
559 /* A new cycle setting. */ 560 /* A new cycle setting. */
560 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_secretbox_NONCEBYTES); 561 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_box_NONCEBYTES);
561 memcpy(_session->decrypt_nonce, _calculated, crypto_secretbox_NONCEBYTES); 562 memcpy(_session->decrypt_nonce, _calculated, crypto_box_NONCEBYTES);
562 } 563 }
563 } 564 }
564 565
@@ -774,8 +775,8 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
774 _send_data[0] = session->prefix; 775 _send_data[0] = session->prefix;
775 776
776 /* Generate the right nonce */ 777 /* Generate the right nonce */
777 uint8_t _calculated[crypto_secretbox_NONCEBYTES]; 778 uint8_t _calculated[crypto_box_NONCEBYTES];
778 memcpy(_calculated, session->encrypt_nonce, crypto_secretbox_NONCEBYTES); 779 memcpy(_calculated, session->encrypt_nonce, crypto_box_NONCEBYTES);
779 increase_nonce ( _calculated, msg->header->sequnum ); 780 increase_nonce ( _calculated, msg->header->sequnum );
780 781
781 /* Need to skip 2 bytes that are for sequnum */ 782 /* Need to skip 2 bytes that are for sequnum */
@@ -798,7 +799,7 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
798 /* Set sequ number */ 799 /* Set sequ number */
799 if ( session->sequnum >= MAX_SEQU_NUM ) { 800 if ( session->sequnum >= MAX_SEQU_NUM ) {
800 session->sequnum = 0; 801 session->sequnum = 0;
801 memcpy(session->encrypt_nonce, _calculated, crypto_secretbox_NONCEBYTES); 802 memcpy(session->encrypt_nonce, _calculated, crypto_box_NONCEBYTES);
802 } else { 803 } else {
803 session->sequnum++; 804 session->sequnum++;
804 } 805 }
@@ -888,16 +889,16 @@ RTPSession *rtp_init_session ( int payload_type,
888 _retu->decrypt_key = decrypt_key; 889 _retu->decrypt_key = decrypt_key;
889 890
890 /* Need to allocate new memory */ 891 /* Need to allocate new memory */
891 _retu->encrypt_nonce = calloc ( crypto_secretbox_NONCEBYTES, sizeof (uint8_t) ); 892 _retu->encrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
892 assert(_retu->encrypt_nonce); 893 assert(_retu->encrypt_nonce);
893 _retu->decrypt_nonce = calloc ( crypto_secretbox_NONCEBYTES, sizeof (uint8_t) ); 894 _retu->decrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
894 assert(_retu->decrypt_nonce); 895 assert(_retu->decrypt_nonce);
895 _retu->nonce_cycle = calloc ( crypto_secretbox_NONCEBYTES, sizeof (uint8_t) ); 896 _retu->nonce_cycle = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
896 assert(_retu->nonce_cycle); 897 assert(_retu->nonce_cycle);
897 898
898 memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_secretbox_NONCEBYTES); 899 memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_box_NONCEBYTES);
899 memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_secretbox_NONCEBYTES); 900 memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_box_NONCEBYTES);
900 memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_secretbox_NONCEBYTES); 901 memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_box_NONCEBYTES);
901 902
902 _retu->csrc = calloc(1, sizeof (uint32_t)); 903 _retu->csrc = calloc(1, sizeof (uint32_t));
903 assert(_retu->csrc); 904 assert(_retu->csrc);
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 870e6ca2..7534387a 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -165,15 +165,15 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, uint8_t *secr
165 } 165 }
166} 166}
167 167
168/* Copy shared_key to decrypt DHT packet from client_id into shared_key 168/* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
169 * for packets that we recieve. 169 * for packets that we receive.
170 */ 170 */
171void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id) 171void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
172{ 172{
173 return get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id); 173 return get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id);
174} 174}
175 175
176/* Copy shared_key to decrypt DHT packet from client_id into shared_key 176/* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
177 * for packets that we send. 177 * for packets that we send.
178 */ 178 */
179void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id) 179void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
@@ -181,6 +181,155 @@ void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id)
181 return get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id); 181 return get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id);
182} 182}
183 183
184void to_net_family(IP *ip)
185{
186 if (ip->family == AF_INET)
187 ip->family = TOX_AF_INET;
188 else if (ip->family == AF_INET6)
189 ip->family = TOX_AF_INET6;
190}
191
192void to_host_family(IP *ip)
193{
194 if (ip->family == TOX_AF_INET)
195 ip->family = AF_INET;
196 else if (ip->family == TOX_AF_INET6)
197 ip->family = AF_INET6;
198}
199
200/* Pack number of nodes into data of maxlength length.
201 *
202 * return length of packed nodes on success.
203 * return -1 on failure.
204 */
205int pack_nodes(uint8_t *data, uint16_t length, Node_format *nodes, uint16_t number)
206{
207 uint32_t i, packed_length = 0;
208
209 for (i = 0; i < number; ++i) {
210 int ipv6 = -1;
211 uint8_t net_family;
212
213 if (nodes[i].ip_port.ip.family == AF_INET) {
214 ipv6 = 0;
215 net_family = TOX_AF_INET;
216 } else if (nodes[i].ip_port.ip.family == TCP_INET) {
217 ipv6 = 0;
218 net_family = TOX_TCP_INET;
219 } else if (nodes[i].ip_port.ip.family == AF_INET6) {
220 ipv6 = 1;
221 net_family = TOX_AF_INET6;
222 } else if (nodes[i].ip_port.ip.family == TCP_INET6) {
223 ipv6 = 1;
224 net_family = TOX_TCP_INET6;
225 } else {
226 return -1;
227 }
228
229 if (ipv6 == 0) {
230 uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE;
231
232 if (packed_length + size > length)
233 return -1;
234
235 data[packed_length] = net_family;
236 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, sizeof(IP4));
237 memcpy(data + packed_length + 1 + sizeof(IP4), &nodes[i].ip_port.port, sizeof(uint16_t));
238 memcpy(data + packed_length + 1 + sizeof(IP4) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE);
239 packed_length += size;
240 } else if (ipv6 == 1) {
241 uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE;
242
243 if (packed_length + size > length)
244 return -1;
245
246 data[packed_length] = net_family;
247 memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, sizeof(IP6));
248 memcpy(data + packed_length + 1 + sizeof(IP6), &nodes[i].ip_port.port, sizeof(uint16_t));
249 memcpy(data + packed_length + 1 + sizeof(IP6) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE);
250 packed_length += size;
251 } else {
252 return -1;
253 }
254 }
255
256 return packed_length;
257}
258
259/* Unpack data of length into nodes of size max_num_nodes.
260 * Put the length of the data processed in processed_data_len.
261 * tcp_enabled sets if TCP nodes are expected (true) or not (false).
262 *
263 * return number of unpacked nodes on success.
264 * return -1 on failure.
265 */
266int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, uint8_t *data,
267 uint16_t length, uint8_t tcp_enabled)
268{
269 uint32_t num = 0, len_processed = 0;
270
271 while (num < max_num_nodes && len_processed < length) {
272 int ipv6 = -1;
273 uint8_t host_family;
274
275 if (data[len_processed] == TOX_AF_INET) {
276 ipv6 = 0;
277 host_family = AF_INET;
278 } else if (data[len_processed] == TOX_TCP_INET) {
279 if (!tcp_enabled)
280 return -1;
281
282 ipv6 = 0;
283 host_family = TCP_INET;
284 } else if (data[len_processed] == TOX_AF_INET6) {
285 ipv6 = 1;
286 host_family = AF_INET6;
287 } else if (data[len_processed] == TOX_TCP_INET6) {
288 if (!tcp_enabled)
289 return -1;
290
291 ipv6 = 1;
292 host_family = TCP_INET6;
293 } else {
294 return -1;
295 }
296
297 if (ipv6 == 0) {
298 uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE;
299
300 if (len_processed + size > length)
301 return -1;
302
303 nodes[num].ip_port.ip.family = host_family;
304 memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, sizeof(IP4));
305 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP4), sizeof(uint16_t));
306 memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP4) + sizeof(uint16_t), CLIENT_ID_SIZE);
307 len_processed += size;
308 ++num;
309 } else if (ipv6 == 1) {
310 uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE;
311
312 if (len_processed + size > length)
313 return -1;
314
315 nodes[num].ip_port.ip.family = host_family;
316 memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, sizeof(IP6));
317 memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP6), sizeof(uint16_t));
318 memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP6) + sizeof(uint16_t), CLIENT_ID_SIZE);
319 len_processed += size;
320 ++num;
321 } else {
322 return -1;
323 }
324 }
325
326 if (processed_data_len)
327 *processed_data_len = len_processed;
328
329 return num;
330}
331
332
184 333
185/* Check if client with client_id is already in list of length length. 334/* Check if client with client_id is already in list of length length.
186 * If it is then set its corresponding timestamp to current time. 335 * If it is then set its corresponding timestamp to current time.
@@ -266,7 +415,7 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
266/* Check if client with client_id is already in node format list of length length. 415/* Check if client with client_id is already in node format list of length length.
267 * 416 *
268 * return 1 if true. 417 * return 1 if true.
269 * return 2 if false. 418 * return 0 if false.
270 */ 419 */
271static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) 420static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id)
272{ 421{
@@ -310,15 +459,15 @@ static uint8_t hardening_correct(Hardening *h)
310/* 459/*
311 * helper for get_close_nodes(). argument list is a monster :D 460 * helper for get_close_nodes(). argument list is a monster :D
312 */ 461 */
313static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, 462static void get_close_nodes_inner(uint8_t *client_id, Node_format *nodes_list,
314 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, 463 sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length,
315 uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good) 464 uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good)
316{ 465{
317 if ((sa_family != AF_INET) && (sa_family != AF_INET6)) 466 if ((sa_family != AF_INET) && (sa_family != AF_INET6) && (sa_family != 0))
318 return; 467 return;
319 468
320 uint32_t num_nodes = *num_nodes_ptr; 469 uint32_t num_nodes = *num_nodes_ptr;
321 int ipv46x, j, closest; 470 int j, closest;
322 uint32_t i; 471 uint32_t i;
323 472
324 for (i = 0; i < client_list_length; i++) { 473 for (i = 0; i < client_list_length; i++) {
@@ -330,39 +479,22 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
330 479
331 IPPTsPng *ipptp = NULL; 480 IPPTsPng *ipptp = NULL;
332 481
333 if (sa_family == AF_INET) 482 if (sa_family == AF_INET) {
334 ipptp = &client->assoc4; 483 ipptp = &client->assoc4;
335 else 484 } else if (sa_family == AF_INET6) {
336 ipptp = &client->assoc6; 485 ipptp = &client->assoc6;
486 } else {
487 if (client->assoc4.timestamp >= client->assoc6.timestamp) {
488 ipptp = &client->assoc4;
489 } else {
490 ipptp = &client->assoc6;
491 }
492 }
337 493
338 /* node not in a good condition? */ 494 /* node not in a good condition? */
339 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) 495 if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT))
340 continue; 496 continue;
341 497
342 IP *client_ip = &ipptp->ip_port.ip;
343
344 /*
345 * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for
346 * our connections, instead we have to look if it is an embedded
347 * IPv4-in-IPv6 here and convert it down in sendnodes().
348 */
349 sa_family_t ip_treat_as_family = client_ip->family;
350
351 if ((dht->net->family == AF_INET6) &&
352 (client_ip->family == AF_INET6)) {
353 /* socket is AF_INET6, address claims AF_INET6:
354 * check for embedded IPv4-in-IPv6 (shouldn't happen anymore,
355 * all storing functions should already convert down to IPv4) */
356 if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6.in6_addr))
357 ip_treat_as_family = AF_INET;
358 }
359
360 ipv46x = !(sa_family == ip_treat_as_family);
361
362 /* node address of the wrong family? */
363 if (ipv46x)
364 continue;
365
366 /* don't send LAN ips to non LAN peers */ 498 /* don't send LAN ips to non LAN peers */
367 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN) 499 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN)
368 continue; 500 continue;
@@ -416,7 +548,7 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
416 uint8_t is_LAN, uint8_t want_good) 548 uint8_t is_LAN, uint8_t want_good)
417{ 549{
418 uint32_t num_nodes = 0, i; 550 uint32_t num_nodes = 0, i;
419 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 551 get_close_nodes_inner(client_id, nodes_list, sa_family,
420 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good); 552 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good);
421 553
422 /*TODO uncomment this when hardening is added to close friend clients 554 /*TODO uncomment this when hardening is added to close friend clients
@@ -426,7 +558,7 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
426 &num_nodes, is_LAN, want_good); 558 &num_nodes, is_LAN, want_good);
427 */ 559 */
428 for (i = 0; i < dht->num_friends; ++i) 560 for (i = 0; i < dht->num_friends; ++i)
429 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 561 get_close_nodes_inner(client_id, nodes_list, sa_family,
430 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 562 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
431 &num_nodes, is_LAN, 0); 563 &num_nodes, is_LAN, 0);
432 564
@@ -444,6 +576,7 @@ int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_fa
444 return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); 576 return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good);
445 577
446#ifdef ENABLE_ASSOC_DHT 578#ifdef ENABLE_ASSOC_DHT
579 //TODO: assoc, sa_family 0 (don't care if ipv4 or ipv6) support.
447 Client_data *result[MAX_SENT_NODES]; 580 Client_data *result[MAX_SENT_NODES];
448 581
449 Assoc_close_entries request; 582 Assoc_close_entries request;
@@ -581,7 +714,7 @@ static int replace_possible_bad( Client_data *list,
581 714
582 sort_list(list, length, comp_client_id); 715 sort_list(list, length, comp_client_id);
583 716
584 /* TODO: decide if the folowing lines should stay commented or not. 717 /* TODO: decide if the following lines should stay commented or not.
585 if (id_closest(comp_client_id, list[0].client_id, client_id) == 1) 718 if (id_closest(comp_client_id, list[0].client_id, client_id) == 1)
586 return 0;*/ 719 return 0;*/
587 720
@@ -823,7 +956,7 @@ end:
823 return 0; 956 return 0;
824} 957}
825 958
826#define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_secretbox_MACBYTES) 959#define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_box_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_box_MACBYTES)
827 960
828/* Send a getnodes request. 961/* Send a getnodes request.
829 sendback_node is the node that it will send back the response to (set to NULL to disable this) */ 962 sendback_node is the node that it will send back the response to (set to NULL to disable this) */
@@ -842,23 +975,23 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
842 975
843 uint64_t temp_time = unix_time(); 976 uint64_t temp_time = unix_time();
844 memcpy(plain_message, &temp_time, sizeof(temp_time)); 977 memcpy(plain_message, &temp_time, sizeof(temp_time));
845 Node_format reciever; 978 Node_format receiver;
846 memcpy(reciever.client_id, public_key, CLIENT_ID_SIZE); 979 memcpy(receiver.client_id, public_key, CLIENT_ID_SIZE);
847 reciever.ip_port = ip_port; 980 receiver.ip_port = ip_port;
848 memcpy(plain_message + sizeof(temp_time), &reciever, sizeof(reciever)); 981 memcpy(plain_message + sizeof(temp_time), &receiver, sizeof(receiver));
849 982
850 if (sendback_node != NULL) 983 if (sendback_node != NULL)
851 memcpy(plain_message + sizeof(temp_time) + sizeof(reciever), sendback_node, sizeof(Node_format)); 984 memcpy(plain_message + sizeof(temp_time) + sizeof(receiver), sendback_node, sizeof(Node_format));
852 else 985 else
853 memset(plain_message + sizeof(temp_time) + sizeof(reciever), 0, sizeof(Node_format)); 986 memset(plain_message + sizeof(temp_time) + sizeof(receiver), 0, sizeof(Node_format));
854 987
855 int len_m = encrypt_data_symmetric(dht->secret_symmetric_key, 988 int len_m = encrypt_data_symmetric(dht->secret_symmetric_key,
856 nonce, 989 nonce,
857 plain_message, 990 plain_message,
858 sizeof(temp_time) + sizeof(reciever) + sizeof(Node_format), 991 sizeof(temp_time) + sizeof(receiver) + sizeof(Node_format),
859 encrypted_message + crypto_secretbox_NONCEBYTES); 992 encrypted_message + crypto_box_NONCEBYTES);
860 993
861 if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES) 994 if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_box_NONCEBYTES)
862 return -1; 995 return -1;
863 996
864 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; 997 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
@@ -871,11 +1004,11 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
871 1004
872 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 1005 uint8_t shared_key[crypto_box_BEFORENMBYTES];
873 DHT_get_shared_key_sent(dht, shared_key, public_key); 1006 DHT_get_shared_key_sent(dht, shared_key, public_key);
874 int len = encrypt_data_fast( shared_key, 1007 int len = encrypt_data_symmetric( shared_key,
875 nonce, 1008 nonce,
876 plain, 1009 plain,
877 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH, 1010 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
878 encrypt ); 1011 encrypt );
879 1012
880 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES) 1013 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES)
881 return -1; 1014 return -1;
@@ -888,132 +1021,46 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
888 return sendpacket(dht->net, ip_port, data, sizeof(data)); 1021 return sendpacket(dht->net, ip_port, data, sizeof(data));
889} 1022}
890 1023
891/* Send a send nodes response. */ 1024/* Send a send nodes response: message for IPv6 nodes */
892/* because of BINARY compatibility, the Node_format MUST BE Node4_format, 1025static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *sendback_data,
893 * IPv6 nodes are sent in a different message 1026 uint16_t length, uint8_t *shared_encryption_key)
894 * encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH */
895static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data,
896 uint8_t *shared_encryption_key)
897{ 1027{
898 /* Check if packet is going to be sent to ourself. */ 1028 /* Check if packet is going to be sent to ourself. */
899 if (id_equal(public_key, dht->self_public_key)) 1029 if (id_equal(public_key, dht->self_public_key))
900 return -1; 1030 return -1;
901 1031
902 size_t Node4_format_size = sizeof(Node4_format); 1032 if (length > NODES_ENCRYPTED_MESSAGE_LENGTH || length == 0)
903 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
904 + Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
905
906 Node_format nodes_list[MAX_SENT_NODES];
907 uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET, LAN_ip(ip_port.ip) == 0, 1);
908
909 if (num_nodes == 0)
910 return 0;
911
912 uint8_t plain[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
913 uint8_t encrypt[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
914 uint8_t nonce[crypto_box_NONCEBYTES];
915 new_nonce(nonce);
916
917 Node4_format *nodes4_list = (Node4_format *)(plain);
918 uint32_t i, num_nodes_ok = 0;
919
920 for (i = 0; i < num_nodes; i++) {
921 memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE);
922 nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port;
923
924 IP *node_ip = &nodes_list[i].ip_port.ip;
925
926 if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6.in6_addr))
927 /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */
928 nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.uint32[3];
929 else if (node_ip->family == AF_INET)
930 nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip4.uint32;
931 else /* shouldn't happen */
932 continue;
933
934 num_nodes_ok++;
935 }
936
937 if (num_nodes_ok < num_nodes) {
938 /* shouldn't happen */
939 num_nodes = num_nodes_ok;
940 }
941
942 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
943 int len = encrypt_data_fast( shared_encryption_key,
944 nonce,
945 plain,
946 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
947 encrypt );
948
949 if ((unsigned int)len != num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH +
950 crypto_box_MACBYTES)
951 return -1;
952
953 data[0] = NET_PACKET_SEND_NODES;
954 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
955 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
956 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
957
958 return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
959}
960
961void to_net_family(IP *ip)
962{
963 ip->padding[0] = 0;
964 ip->padding[1] = 0;
965 ip->padding[2] = 0;
966
967 if (ip->family == AF_INET)
968 ip->family = TOX_AF_INET;
969 else if (ip->family == AF_INET6)
970 ip->family = TOX_AF_INET6;
971}
972
973void to_host_family(IP *ip)
974{
975 if (ip->family == TOX_AF_INET)
976 ip->family = AF_INET;
977 else if (ip->family == TOX_AF_INET6)
978 ip->family = AF_INET6;
979}
980/* Send a send nodes response: message for IPv6 nodes */
981static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data,
982 uint8_t *shared_encryption_key)
983{
984 /* Check if packet is going to be sent to ourself. */
985 if (id_equal(public_key, dht->self_public_key))
986 return -1; 1033 return -1;
987 1034
988 size_t Node_format_size = sizeof(Node_format); 1035 size_t Node_format_size = sizeof(Node_format);
989 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 1036 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
990 + Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; 1037 + Node_format_size * MAX_SENT_NODES + length + crypto_box_MACBYTES];
991 1038
992 Node_format nodes_list[MAX_SENT_NODES]; 1039 Node_format nodes_list[MAX_SENT_NODES];
993 uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6, LAN_ip(ip_port.ip) == 0, 1); 1040 uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, LAN_ip(ip_port.ip) == 0, 1);
994 1041
995 if (num_nodes == 0) 1042 if (num_nodes == 0)
996 return 0; 1043 return 0;
997 1044
998 uint8_t plain[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; 1045 uint8_t plain[1 + Node_format_size * MAX_SENT_NODES + length];
999 uint8_t encrypt[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; 1046 uint8_t encrypt[sizeof(plain) + crypto_box_MACBYTES];
1000 uint8_t nonce[crypto_box_NONCEBYTES]; 1047 uint8_t nonce[crypto_box_NONCEBYTES];
1001 new_nonce(nonce); 1048 new_nonce(nonce);
1002 1049
1003 uint32_t i; 1050 int nodes_length = pack_nodes(plain + 1, Node_format_size * MAX_SENT_NODES, nodes_list, num_nodes);
1004 1051
1005 for (i = 0; i < num_nodes; ++i) 1052 if (nodes_length <= 0)
1006 to_net_family(&nodes_list[i].ip_port.ip); 1053 return -1;
1007 1054
1008 memcpy(plain, nodes_list, num_nodes * Node_format_size); 1055 plain[0] = num_nodes;
1009 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); 1056 memcpy(plain + 1 + nodes_length, sendback_data, length);
1010 int len = encrypt_data_fast( shared_encryption_key, 1057 int len = encrypt_data_symmetric( shared_encryption_key,
1011 nonce, 1058 nonce,
1012 plain, 1059 plain,
1013 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, 1060 1 + nodes_length + length,
1014 encrypt ); 1061 encrypt );
1015 1062
1016 if ((unsigned int)len != num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES) 1063 if (len != 1 + nodes_length + length + crypto_box_MACBYTES)
1017 return -1; 1064 return -1;
1018 1065
1019 data[0] = NET_PACKET_SEND_NODES_IPV6; 1066 data[0] = NET_PACKET_SEND_NODES_IPV6;
@@ -1026,35 +1073,38 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
1026 1073
1027static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 1074static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
1028{ 1075{
1029 DHT *dht = object; 1076 uint32_t cmp_len = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + crypto_box_MACBYTES;
1077
1078 if (length <= cmp_len)
1079 return 1;
1030 1080
1031 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + 1081 if (length > cmp_len + NODES_ENCRYPTED_MESSAGE_LENGTH)
1032 crypto_box_MACBYTES ))
1033 return 1; 1082 return 1;
1034 1083
1084 uint16_t sendback_data_length = length - cmp_len;
1085
1086 DHT *dht = object;
1087
1035 /* Check if packet is from ourself. */ 1088 /* Check if packet is from ourself. */
1036 if (id_equal(packet + 1, dht->self_public_key)) 1089 if (id_equal(packet + 1, dht->self_public_key))
1037 return 1; 1090 return 1;
1038 1091
1039 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH]; 1092 uint8_t plain[CLIENT_ID_SIZE + sendback_data_length];
1040 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 1093 uint8_t shared_key[crypto_box_BEFORENMBYTES];
1041 1094
1042 DHT_get_shared_key_recv(dht, shared_key, packet + 1); 1095 DHT_get_shared_key_recv(dht, shared_key, packet + 1);
1043 int len = decrypt_data_fast( shared_key, 1096 int len = decrypt_data_symmetric( shared_key,
1044 packet + 1 + CLIENT_ID_SIZE, 1097 packet + 1 + CLIENT_ID_SIZE,
1045 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 1098 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
1046 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, 1099 CLIENT_ID_SIZE + sendback_data_length + crypto_box_MACBYTES,
1047 plain ); 1100 plain );
1048 1101
1049 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH) 1102 if (len != CLIENT_ID_SIZE + sendback_data_length)
1050 return 1; 1103 return 1;
1051 1104
1052 sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE, shared_key); 1105 sendnodes_ipv6(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE, sendback_data_length, shared_key);
1053 sendnodes_ipv6(dht, source, packet + 1, plain,
1054 plain + CLIENT_ID_SIZE, shared_key); /* TODO: prevent possible amplification attacks */
1055 1106
1056 add_to_ping(dht->ping, packet + 1, source); 1107 add_to_ping(dht->ping, packet + 1, source);
1057 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */
1058 1108
1059 return 0; 1109 return 0;
1060} 1110}
@@ -1066,8 +1116,8 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i
1066{ 1116{
1067 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH]; 1117 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH];
1068 1118
1069 if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_secretbox_NONCEBYTES, 1119 if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_box_NONCEBYTES,
1070 NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES, 1120 NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_box_NONCEBYTES,
1071 plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) 1121 plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2)
1072 return 0; 1122 return 0;
1073 1123
@@ -1089,124 +1139,87 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i
1089} 1139}
1090 1140
1091/* Function is needed in following functions. */ 1141/* Function is needed in following functions. */
1092static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, Node_format *list, 1142static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, uint8_t *nodes_data,
1093 uint16_t num_nodes); 1143 uint16_t nodes_data_length);
1094 1144
1095static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length, 1145static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length,
1096 size_t node_format_size, uint8_t *plain, uint16_t plain_length, uint32_t *num_nodes_out, Node_format *sendback_node) 1146 Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
1097{ 1147{
1098 if (plain_length != MAX_SENT_NODES * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH)
1099 return 1;
1100
1101 DHT *dht = object; 1148 DHT *dht = object;
1102 uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; 1149 uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + 1 + NODES_ENCRYPTED_MESSAGE_LENGTH +
1150 crypto_box_MACBYTES;
1103 1151
1104 if (length <= cid_size) /* too short */ 1152 if (length <= cid_size) /* too short */
1105 return 1; 1153 return 1;
1106 1154
1107 uint32_t data_size = length - cid_size; 1155 uint32_t data_size = length - cid_size;
1108 1156
1109 if ((data_size % node_format_size) != 0) /* invalid length */ 1157 if (data_size == 0)
1110 return 1; 1158 return 1;
1111 1159
1112 uint32_t num_nodes = data_size / node_format_size; 1160 if (data_size > sizeof(Node_format) * MAX_SENT_NODES) /* invalid length */
1113
1114 if (num_nodes > MAX_SENT_NODES) /* too long */
1115 return 1; 1161 return 1;
1116 1162
1163 uint8_t plain[1 + data_size + NODES_ENCRYPTED_MESSAGE_LENGTH];
1117 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 1164 uint8_t shared_key[crypto_box_BEFORENMBYTES];
1118 DHT_get_shared_key_sent(dht, shared_key, packet + 1); 1165 DHT_get_shared_key_sent(dht, shared_key, packet + 1);
1119 int len = decrypt_data_fast( 1166 int len = decrypt_data_symmetric(
1120 shared_key, 1167 shared_key,
1121 packet + 1 + CLIENT_ID_SIZE, 1168 packet + 1 + CLIENT_ID_SIZE,
1122 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 1169 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
1123 num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, 1170 1 + data_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
1124 plain); 1171 plain);
1125 1172
1126 if ((unsigned int)len != num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) 1173 if ((unsigned int)len != sizeof(plain))
1127 return 1; 1174 return 1;
1128 1175
1129 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * node_format_size, sendback_node)) 1176 if (plain[0] > size_plain_nodes || plain[0] == 0)
1130 return 1; 1177 return 1;
1131 1178
1132 /* store the address the *request* was sent to */
1133 addto_lists(dht, source, packet + 1);
1134
1135 *num_nodes_out = num_nodes;
1136
1137 return 0;
1138}
1139
1140static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
1141{
1142 DHT *dht = object;
1143 size_t node4_format_size = sizeof(Node4_format);
1144 uint8_t plain[node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
1145 uint32_t num_nodes;
1146
1147 Node_format sendback_node; 1179 Node_format sendback_node;
1148 1180
1149 if (handle_sendnodes_core(object, source, packet, length, node4_format_size, plain, sizeof(plain), &num_nodes, 1181 if (!sent_getnode_to_node(dht, packet + 1, source, plain + 1 + data_size, &sendback_node))
1150 &sendback_node))
1151 return 1; 1182 return 1;
1152 1183
1153 if (num_nodes == 0) 1184 uint16_t length_nodes = 0;
1154 return 0; 1185 int num_nodes = unpack_nodes(plain_nodes, plain[0], &length_nodes, plain + 1, data_size, 0);
1155
1156 Node4_format *nodes4_list = (Node4_format *)(plain);
1157
1158 uint64_t time_now = unix_time();
1159 IPPTs ippts;
1160 ippts.ip_port.ip.family = AF_INET;
1161 ippts.timestamp = time_now;
1162
1163 uint32_t i;
1164 1186
1165 Node_format nodes_list[MAX_SENT_NODES]; 1187 if (length_nodes != data_size)
1188 return 1;
1166 1189
1167 for (i = 0; i < num_nodes; i++) 1190 if (num_nodes != plain[0])
1168 if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) { 1191 return 1;
1169 ippts.ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32;
1170 ippts.ip_port.port = nodes4_list[i].ip_port.port;
1171 1192
1172 send_ping_request(dht->ping, ippts.ip_port, nodes4_list[i].client_id); 1193 if (num_nodes <= 0)
1173 returnedip_ports(dht, ippts.ip_port, nodes4_list[i].client_id, packet + 1); 1194 return 1;
1174 1195
1175 memcpy(nodes_list[i].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); 1196 /* store the address the *request* was sent to */
1176 ipport_copy(&nodes_list[i].ip_port, &ippts.ip_port); 1197 addto_lists(dht, source, packet + 1);
1177 1198
1178 } 1199 *num_nodes_out = num_nodes;
1179 1200
1180 send_hardening_getnode_res(dht, &sendback_node, packet + 1, nodes_list, num_nodes); 1201 send_hardening_getnode_res(dht, &sendback_node, packet + 1, plain + 1, data_size);
1181 return 0; 1202 return 0;
1182} 1203}
1183 1204
1184static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) 1205static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length)
1185{ 1206{
1186 DHT *dht = object; 1207 DHT *dht = object;
1187 size_t node_format_size = sizeof(Node_format); 1208 Node_format plain_nodes[MAX_SENT_NODES];
1188 uint8_t plain[node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
1189 uint32_t num_nodes; 1209 uint32_t num_nodes;
1190 1210
1191 Node_format sendback_node; 1211 if (handle_sendnodes_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes))
1192
1193 if (handle_sendnodes_core(object, source, packet, length, node_format_size, plain, sizeof(plain), &num_nodes,
1194 &sendback_node))
1195 return 1; 1212 return 1;
1196 1213
1197 if (num_nodes == 0) 1214 if (num_nodes == 0)
1198 return 0; 1215 return 0;
1199 1216
1200 Node_format *nodes_list = (Node_format *)(plain);
1201 uint32_t i; 1217 uint32_t i;
1202 send_hardening_getnode_res(dht, &sendback_node, packet + 1, nodes_list, num_nodes);
1203 1218
1204 for (i = 0; i < num_nodes; i++) { 1219 for (i = 0; i < num_nodes; i++) {
1205 to_host_family(&nodes_list[i].ip_port.ip); 1220 if (ipport_isset(&plain_nodes[i].ip_port)) {
1206 1221 send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].client_id);
1207 if (ipport_isset(&nodes_list[i].ip_port)) { 1222 returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].client_id, packet + 1);
1208 send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id);
1209 returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
1210 } 1223 }
1211 } 1224 }
1212 1225
@@ -1595,7 +1608,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1595/* Send the following packet to everyone who tells us they are connected to friend_id. 1608/* Send the following packet to everyone who tells us they are connected to friend_id.
1596 * 1609 *
1597 * return ip for friend. 1610 * return ip for friend.
1598 * return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 2). 1611 * return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 4).
1599 */ 1612 */
1600int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) 1613int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length)
1601{ 1614{
@@ -1724,7 +1737,7 @@ int friend_ips(DHT *dht, IP_Port *ip_portlist, uint8_t *friend_id)
1724static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) 1737static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type)
1725{ 1738{
1726 uint8_t data[sizeof(uint64_t) + 1]; 1739 uint8_t data[sizeof(uint64_t) + 1];
1727 uint8_t packet[MAX_DATA_SIZE]; 1740 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
1728 1741
1729 int num = 0; 1742 int num = 0;
1730 1743
@@ -1935,7 +1948,7 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8
1935 if (length > HARDREQ_DATA_SIZE - 1) 1948 if (length > HARDREQ_DATA_SIZE - 1)
1936 return -1; 1949 return -1;
1937 1950
1938 uint8_t packet[MAX_DATA_SIZE]; 1951 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
1939 uint8_t data[HARDREQ_DATA_SIZE] = {0}; 1952 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1940 data[0] = type; 1953 data[0] = type;
1941 memcpy(data + 1, contents, length); 1954 memcpy(data + 1, contents, length);
@@ -1958,17 +1971,17 @@ static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *
1958} 1971}
1959 1972
1960/* Send a get node hardening response */ 1973/* Send a get node hardening response */
1961static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, Node_format *list, 1974static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, uint8_t *nodes_data,
1962 uint16_t num_nodes) 1975 uint16_t nodes_data_length)
1963{ 1976{
1964 if (!ip_isset(&sendto->ip_port.ip)) 1977 if (!ip_isset(&sendto->ip_port.ip))
1965 return -1; 1978 return -1;
1966 1979
1967 uint8_t packet[MAX_DATA_SIZE]; 1980 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
1968 uint8_t data[1 + CLIENT_ID_SIZE + num_nodes * sizeof(Node_format)]; 1981 uint8_t data[1 + CLIENT_ID_SIZE + nodes_data_length];
1969 data[0] = CHECK_TYPE_GETNODE_RES; 1982 data[0] = CHECK_TYPE_GETNODE_RES;
1970 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); 1983 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE);
1971 memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format)); 1984 memcpy(data + 1 + CLIENT_ID_SIZE, nodes_data, nodes_data_length);
1972 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, 1985 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
1973 sizeof(data), CRYPTO_PACKET_HARDENING); 1986 sizeof(data), CRYPTO_PACKET_HARDENING);
1974 1987
@@ -2056,28 +2069,22 @@ static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey
2056 if (length <= CLIENT_ID_SIZE + 1) 2069 if (length <= CLIENT_ID_SIZE + 1)
2057 return 1; 2070 return 1;
2058 2071
2059 if ((length - 1 - CLIENT_ID_SIZE) % sizeof(Node_format) != 0) 2072 if (length > 1 + CLIENT_ID_SIZE + sizeof(Node_format) * MAX_SENT_NODES)
2060 return 1; 2073 return 1;
2061 2074
2062 uint16_t num = (length - 1 - CLIENT_ID_SIZE) / sizeof(Node_format); 2075 uint16_t length_nodes = length - 1 - CLIENT_ID_SIZE;
2076 Node_format nodes[MAX_SENT_NODES];
2077 int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, packet + 1 + CLIENT_ID_SIZE, length_nodes, 0);
2063 2078
2064 /* TODO: MAX_SENT_NODES nodes should be returned at all times 2079 /* TODO: MAX_SENT_NODES nodes should be returned at all times
2065 (right now we have a small network size so it could cause problems for testing and etc..) */ 2080 (right now we have a small network size so it could cause problems for testing and etc..) */
2066 if (num > MAX_SENT_NODES || num == 0) 2081 if (num_nodes <= 0)
2067 return 1; 2082 return 1;
2068 2083
2069 Node_format nodes[num];
2070 memcpy(nodes, packet + 1 + CLIENT_ID_SIZE, sizeof(Node_format)*num);
2071 uint32_t i;
2072
2073 for (i = 0; i < num; ++i)
2074 to_host_family(&nodes[i].ip_port.ip);
2075
2076 /* NOTE: This should work for now but should be changed to something better. */ 2084 /* NOTE: This should work for now but should be changed to something better. */
2077 if (have_nodes_closelist(dht, nodes, num) < (uint32_t)((num + 2) / 2)) 2085 if (have_nodes_closelist(dht, nodes, num_nodes) < (uint32_t)((num_nodes + 2) / 2))
2078 return 1; 2086 return 1;
2079 2087
2080
2081 IPPTsPng *temp = get_closelist_IPPTsPng(dht, packet + 1, nodes[0].ip_port.ip.family); 2088 IPPTsPng *temp = get_closelist_IPPTsPng(dht, packet + 1, nodes[0].ip_port.ip.family);
2082 2089
2083 if (temp == NULL) 2090 if (temp == NULL)
@@ -2204,6 +2211,8 @@ static int random_node_fromlist(Client_data *list, uint16_t list_size, Node_form
2204 * return the number of nodes. 2211 * return the number of nodes.
2205 * 2212 *
2206 * NOTE:this is used to pick nodes for paths. 2213 * NOTE:this is used to pick nodes for paths.
2214 *
2215 * TODO: remove the LAN stuff from this.
2207 */ 2216 */
2208uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num) 2217uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num)
2209{ 2218{
@@ -2287,12 +2296,54 @@ void do_hardening(DHT *dht)
2287 2296
2288/*----------------------------------------------------------------------------------*/ 2297/*----------------------------------------------------------------------------------*/
2289 2298
2290DHT *new_DHT(Net_Crypto *c) 2299void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object)
2300{
2301 dht->cryptopackethandlers[byte].function = cb;
2302 dht->cryptopackethandlers[byte].object = object;
2303}
2304
2305static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
2306{
2307 DHT *dht = object;
2308
2309 if (packet[0] == NET_PACKET_CRYPTO) {
2310 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES ||
2311 length > MAX_CRYPTO_REQUEST_SIZE + crypto_box_MACBYTES)
2312 return 1;
2313
2314 if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
2315 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
2316 uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
2317 uint8_t number;
2318 int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
2319
2320 if (len == -1 || len == 0)
2321 return 1;
2322
2323 if (!dht->cryptopackethandlers[number].function) return 1;
2324
2325 return dht->cryptopackethandlers[number].function(dht->cryptopackethandlers[number].object, source, public_key,
2326 data, len);
2327
2328 } else { /* If request is not for us, try routing it. */
2329 int retval = route_packet(dht, packet + 1, packet, length);
2330
2331 if ((unsigned int)retval == length)
2332 return 0;
2333 }
2334 }
2335
2336 return 1;
2337}
2338
2339/*----------------------------------------------------------------------------------*/
2340
2341DHT *new_DHT(Networking_Core *net)
2291{ 2342{
2292 /* init time */ 2343 /* init time */
2293 unix_time_update(); 2344 unix_time_update();
2294 2345
2295 if (c == NULL) 2346 if (net == NULL)
2296 return NULL; 2347 return NULL;
2297 2348
2298 DHT *dht = calloc(1, sizeof(DHT)); 2349 DHT *dht = calloc(1, sizeof(DHT));
@@ -2300,8 +2351,7 @@ DHT *new_DHT(Net_Crypto *c)
2300 if (dht == NULL) 2351 if (dht == NULL)
2301 return NULL; 2352 return NULL;
2302 2353
2303 dht->c = c; 2354 dht->net = net;
2304 dht->net = c->lossless_udp->net;
2305 dht->ping = new_ping(dht); 2355 dht->ping = new_ping(dht);
2306 2356
2307 if (dht->ping == NULL) { 2357 if (dht->ping == NULL) {
@@ -2310,11 +2360,10 @@ DHT *new_DHT(Net_Crypto *c)
2310 } 2360 }
2311 2361
2312 networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); 2362 networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
2313 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
2314 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); 2363 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
2315 init_cryptopackets(dht); 2364 networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
2316 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); 2365 cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
2317 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); 2366 cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
2318 2367
2319 new_symmetric_key(dht->secret_symmetric_key); 2368 new_symmetric_key(dht->secret_symmetric_key);
2320 crypto_box_keypair(dht->self_public_key, dht->self_secret_key); 2369 crypto_box_keypair(dht->self_public_key, dht->self_secret_key);
@@ -2361,8 +2410,8 @@ void kill_DHT(DHT *dht)
2361 networking_registerhandler(dht->net, NET_PACKET_GET_NODES, NULL, NULL); 2410 networking_registerhandler(dht->net, NET_PACKET_GET_NODES, NULL, NULL);
2362 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, NULL, NULL); 2411 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, NULL, NULL);
2363 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL); 2412 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL);
2364 cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_NAT_PING, NULL, NULL); 2413 cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, NULL, NULL);
2365 cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_HARDENING, NULL, NULL); 2414 cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, NULL, NULL);
2366 kill_ping(dht->ping); 2415 kill_ping(dht->ping);
2367 free(dht->friends_list); 2416 free(dht->friends_list);
2368 free(dht); 2417 free(dht);
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 3d2722f8..41fe99c9 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -24,7 +24,8 @@
24#ifndef DHT_H 24#ifndef DHT_H
25#define DHT_H 25#define DHT_H
26 26
27#include "net_crypto.h" 27#include "crypto_core.h"
28#include "network.h"
28 29
29/* Size of the client_id in bytes. */ 30/* Size of the client_id in bytes. */
30#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES 31#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
@@ -36,7 +37,7 @@
36#define LCLIENT_LIST 32 37#define LCLIENT_LIST 32
37 38
38/* The max number of nodes to send with send nodes. */ 39/* The max number of nodes to send with send nodes. */
39#define MAX_SENT_NODES 8 40#define MAX_SENT_NODES 4
40 41
41/* Ping timeout in seconds */ 42/* Ping timeout in seconds */
42#define PING_TIMEOUT 3 43#define PING_TIMEOUT 3
@@ -52,6 +53,8 @@
52/* Redefinitions of variables for safe transfer over wire. */ 53/* Redefinitions of variables for safe transfer over wire. */
53#define TOX_AF_INET 2 54#define TOX_AF_INET 2
54#define TOX_AF_INET6 10 55#define TOX_AF_INET6 10
56#define TOX_TCP_INET 130
57#define TOX_TCP_INET6 138
55 58
56/* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */ 59/* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
57#define DHT_FAKE_FRIEND_NUMBER 4 60#define DHT_FAKE_FRIEND_NUMBER 4
@@ -128,16 +131,30 @@ typedef struct {
128 NAT nat; 131 NAT nat;
129} DHT_Friend; 132} DHT_Friend;
130 133
131/* this must be kept even if IP_Port is expanded: wire compatibility */ 134typedef struct __attribute__ ((__packed__))
132typedef struct { 135{
133 uint8_t client_id[CLIENT_ID_SIZE];
134 IP4_Port ip_port;
135} Node4_format;
136
137typedef struct {
138 uint8_t client_id[CLIENT_ID_SIZE]; 136 uint8_t client_id[CLIENT_ID_SIZE];
139 IP_Port ip_port; 137 IP_Port ip_port;
140} Node_format; 138}
139Node_format;
140
141/* Pack number of nodes into data of maxlength length.
142 *
143 * return length of packed nodes on success.
144 * return -1 on failure.
145 */
146int pack_nodes(uint8_t *data, uint16_t length, Node_format *nodes, uint16_t number);
147
148/* Unpack data of length into nodes of size max_num_nodes.
149 * Put the length of the data processed in processed_data_len.
150 * tcp_enabled sets if TCP nodes are expected (true) or not (false).
151 *
152 * return number of unpacked nodes on success.
153 * return -1 on failure.
154 */
155int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, uint8_t *data,
156 uint16_t length, uint8_t tcp_enabled);
157
141 158
142/*----------------------------------------------------------------------------------*/ 159/*----------------------------------------------------------------------------------*/
143/* struct to store some shared keys so we don't have to regenerate them for each request. */ 160/* struct to store some shared keys so we don't have to regenerate them for each request. */
@@ -155,8 +172,15 @@ typedef struct {
155 172
156/*----------------------------------------------------------------------------------*/ 173/*----------------------------------------------------------------------------------*/
157 174
175typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data,
176 uint32_t len);
177
178typedef struct {
179 cryptopacket_handler_callback function;
180 void *object;
181} Cryptopacket_Handles;
182
158typedef struct { 183typedef struct {
159 Net_Crypto *c;
160 Networking_Core *net; 184 Networking_Core *net;
161 185
162 Client_data close_clientlist[LCLIENT_LIST]; 186 Client_data close_clientlist[LCLIENT_LIST];
@@ -164,7 +188,7 @@ typedef struct {
164 uint32_t close_bootstrap_times; 188 uint32_t close_bootstrap_times;
165 189
166 /* Note: this key should not be/is not used to transmit any sensitive materials */ 190 /* Note: this key should not be/is not used to transmit any sensitive materials */
167 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; 191 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
168 /* DHT keypair */ 192 /* DHT keypair */
169 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 193 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
170 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 194 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
@@ -180,6 +204,8 @@ typedef struct {
180 struct Assoc *assoc; 204 struct Assoc *assoc;
181#endif 205#endif
182 uint64_t last_run; 206 uint64_t last_run;
207
208 Cryptopacket_Handles cryptopackethandlers[256];
183} DHT; 209} DHT;
184/*----------------------------------------------------------------------------------*/ 210/*----------------------------------------------------------------------------------*/
185 211
@@ -191,12 +217,12 @@ typedef struct {
191 */ 217 */
192void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, uint8_t *secret_key, uint8_t *client_id); 218void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, uint8_t *secret_key, uint8_t *client_id);
193 219
194/* Copy shared_key to decrypt DHT packet from client_id into shared_key 220/* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
195 * for packets that we recieve. 221 * for packets that we receive.
196 */ 222 */
197void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id); 223void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id);
198 224
199/* Copy shared_key to decrypt DHT packet from client_id into shared_key 225/* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
200 * for packets that we send. 226 * for packets that we send.
201 */ 227 */
202void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id); 228void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id);
@@ -251,7 +277,7 @@ int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2);
251/* Get the (maximum MAX_SENT_NODES) closest nodes to client_id we know 277/* Get the (maximum MAX_SENT_NODES) closest nodes to client_id we know
252 * and put them in nodes_list (must be MAX_SENT_NODES big). 278 * and put them in nodes_list (must be MAX_SENT_NODES big).
253 * 279 *
254 * sa_family = family (IPv4 or IPv6)? 280 * sa_family = family (IPv4 or IPv6) (0 if we don't care)?
255 * is_LAN = return some LAN ips (true or false) 281 * is_LAN = return some LAN ips (true or false)
256 * want_good = do we want tested nodes or not? (TODO) 282 * want_good = do we want tested nodes or not? (TODO)
257 * 283 *
@@ -315,6 +341,10 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
315 */ 341 */
316int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length); 342int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length);
317 343
344/* Function to handle crypto packets.
345 */
346void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object);
347
318/* NAT PUNCHING FUNCTIONS */ 348/* NAT PUNCHING FUNCTIONS */
319 349
320/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist. 350/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist.
@@ -341,7 +371,7 @@ void DHT_save(DHT *dht, uint8_t *data);
341int DHT_load(DHT *dht, uint8_t *data, uint32_t length); 371int DHT_load(DHT *dht, uint8_t *data, uint32_t length);
342 372
343/* Initialize DHT. */ 373/* Initialize DHT. */
344DHT *new_DHT(Net_Crypto *c); 374DHT *new_DHT(Networking_Core *net);
345 375
346void kill_DHT(DHT *dht); 376void kill_DHT(DHT *dht);
347 377
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index bed14754..9d1f055e 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -78,8 +78,10 @@ static void fetch_broadcast_info(uint16_t port)
78 78
79 struct sockaddr_in *sock4 = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; 79 struct sockaddr_in *sock4 = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
80 80
81 if (broadcast_count >= MAX_INTERFACES) 81 if (broadcast_count >= MAX_INTERFACES) {
82 close(sock);
82 return; 83 return;
84 }
83 85
84 IP_Port *ip_port = &broadcast_ip_port[broadcast_count]; 86 IP_Port *ip_port = &broadcast_ip_port[broadcast_count];
85 ip_port->ip.family = AF_INET; 87 ip_port->ip.family = AF_INET;
diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c
deleted file mode 100644
index c0db8a10..00000000
--- a/toxcore/Lossless_UDP.c
+++ /dev/null
@@ -1,1168 +0,0 @@
1/* Lossless_UDP.c
2 *
3 * An implementation of the Lossless_UDP protocol as seen in http://wiki.tox.im/index.php/Lossless_UDP
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24/*
25 * TODO: clean this file a bit.
26 * There are a couple of useless variables to get rid of.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "Lossless_UDP.h"
34
35#define LUDP_CONNECTION_OUTBOUND 0
36#define LUDP_CONNECTION_INBOUND_HANDLED 1
37#define LUDP_CONNECTION_INBOUND 2
38
39/* Functions */
40
41/*
42 * Get connection id from IP_Port.
43 *
44 * return -1 if there are no connections like we are looking for.
45 * return id if it found it.
46 */
47int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port)
48{
49 tox_array_for_each(&ludp->connections, Connection, tmp) {
50 if (tmp->status != LUDP_NO_CONNECTION && ipport_equal(&tmp->ip_port, &ip_port)) {
51 return tmp_i;
52 }
53 }
54
55 return -1;
56}
57
58/* Resize a queue
59 * return length of queue on success.
60 * return ~0 on failure.
61 */
62uint32_t resize_queue(Data **buffer, uint32_t length, uint32_t new_length, uint32_t min_packetnum,
63 uint32_t max_packetnum)
64{
65 if (MAX_QUEUE_NUM < new_length)
66 new_length = MAX_QUEUE_NUM;
67
68 if (max_packetnum - min_packetnum > new_length)
69 return ~0;
70
71 if (length == new_length)
72 return new_length;
73
74 Data *temp = calloc(1, sizeof(Data) * new_length);
75
76 if (temp == NULL)
77 return ~0;
78
79 if (*buffer == NULL) {
80 *buffer = temp;
81 return new_length;
82 }
83
84 uint32_t i;
85
86 for (i = min_packetnum; i != max_packetnum; ++i)
87 memcpy(temp + (i % new_length), *buffer + (i % length), sizeof(Data));
88
89 free(*buffer);
90 *buffer = temp;
91 return new_length;
92}
93
94
95
96/*
97 * Generate a handshake_id which depends on the ip_port.
98 * This function will always give one unique handshake_id per ip_port.
99 *
100 * TODO: make this better
101 */
102
103static uint32_t randtable_initget(Lossless_UDP *ludp, uint32_t index, uint8_t value)
104{
105 if (ludp->randtable[index][value] == 0)
106 ludp->randtable[index][value] = random_int();
107
108 return ludp->randtable[index][value];
109}
110
111static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source)
112{
113 uint32_t id = 0, i = 0;
114
115 uint8_t *uint8;
116 uint8 = (uint8_t *)&source.port;
117 id ^= randtable_initget(ludp, i, *uint8);
118 i++, uint8++;
119 id ^= randtable_initget(ludp, i, *uint8);
120 i++;
121
122 if (source.ip.family == AF_INET) {
123 int k;
124
125 for (k = 0; k < 4; k++) {
126 id ^= randtable_initget(ludp, i++, source.ip.ip4.uint8[k]);
127 }
128 }
129
130 if (source.ip.family == AF_INET6) {
131 int k;
132
133 for (k = 0; k < 16; k++) {
134 id ^= randtable_initget(ludp, i++, source.ip.ip6.uint8[k]);
135 }
136 }
137
138 /* id can't be zero. */
139 if (id == 0)
140 id = 1;
141
142 return id;
143}
144
145/*
146 * Change the handshake id associated with that ip_port.
147 *
148 * TODO: Make this better
149 */
150static void change_handshake(Lossless_UDP *ludp, IP_Port source)
151{
152 uint8_t rand;
153
154 if (source.ip.family == AF_INET) {
155 rand = random_int() % 4;
156 } else if (source.ip.family == AF_INET6) {
157 rand = random_int() % 16;
158 } else {
159 return;
160 }
161
162 /* Forced to be more robust against strange definitions of sa_family_t */
163 ludp->randtable[2 + rand][((uint8_t *)&source.ip.ip6)[rand]] = random_int();
164}
165
166/*
167 * Initialize a new connection to ip_port
168 *
169 * return an integer corresponding to the connection id.
170 * return -1 if it could not initialize the connectiont
171 * If there already was an existing connection to that ip_port return its number.
172 */
173int new_connection(Lossless_UDP *ludp, IP_Port ip_port)
174{
175 int connection_id = getconnection_id(ludp, ip_port);
176
177 if (connection_id != -1) {
178 confirm_connection(ludp, connection_id);
179 return connection_id;
180 }
181
182 tox_array_for_each(&ludp->connections, Connection, tmp) {
183 if (tmp->status == LUDP_NO_CONNECTION) {
184 connection_id = tmp_i;
185 break;
186 }
187 }
188
189 if (connection_id == -1) {
190 if (tox_array_push_ptr(&ludp->connections, 0) == 0)
191 return -1;
192
193 connection_id = ludp->connections.len - 1;
194 }
195
196 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
197
198 memset(connection, 0, sizeof(Connection));
199
200 uint32_t handshake_id1 = handshake_id(ludp, ip_port);
201 /* Add randomness to timeout to prevent connections getting stuck in a loop. */
202 uint8_t timeout = CONNECTION_TIMEOUT + rand() % CONNECTION_TIMEOUT;
203
204 *connection = (Connection) {
205 .ip_port = ip_port,
206 .status = LUDP_HANDSHAKE_SENDING,
207 .inbound = LUDP_CONNECTION_OUTBOUND,
208 .handshake_id1 = handshake_id1,
209 .sent_packetnum = handshake_id1,
210 .sendbuff_packetnum = handshake_id1,
211 .successful_sent = handshake_id1,
212 .SYNC_rate = SYNC_RATE,
213 .data_rate = DATA_SYNC_RATE,
214 .last_recvSYNC = current_time(),
215 .last_sent = current_time(),
216 .killat = ~0,
217 .send_counter = 0,
218 .timeout = timeout,
219 .confirmed = 1
220 };
221 connection->sendbuffer_length = resize_queue(&connection->sendbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0);
222 connection->recvbuffer_length = resize_queue(&connection->recvbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0);
223
224 if (connection->sendbuffer_length == (uint32_t)~0 || connection->recvbuffer_length == (uint32_t)~0) {
225 free(connection->sendbuffer);
226 free(connection->recvbuffer);
227 memset(connection, 0, sizeof(Connection));
228 return -1;
229 }
230
231 return connection_id;
232}
233
234/*
235 * Initialize a new inbound connection from ip_port.
236 *
237 * return an integer corresponding to the connection id.
238 * return -1 if it could not initialize the connection.
239 */
240static int new_inconnection(Lossless_UDP *ludp, IP_Port ip_port)
241{
242 if (getconnection_id(ludp, ip_port) != -1)
243 return -1; /* TODO: return existing connection instead? */
244
245 int connection_id = -1;
246 tox_array_for_each(&ludp->connections, Connection, tmp) {
247 if (tmp->status == LUDP_NO_CONNECTION) {
248 connection_id = tmp_i;
249 break;
250 }
251 }
252
253 if (connection_id == -1) {
254 if (tox_array_push_ptr(&ludp->connections, 0) == 0)
255 return -1;
256
257 connection_id = ludp->connections.len - 1;
258 }
259
260 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
261 memset(connection, 0, sizeof(Connection));
262 /* Add randomness to timeout to prevent connections getting stuck in a loop. */
263 uint8_t timeout = CONNECTION_TIMEOUT + rand() % CONNECTION_TIMEOUT;
264
265 *connection = (Connection) {
266 .ip_port = ip_port,
267 .status = LUDP_NOT_CONFIRMED,
268 .inbound = LUDP_CONNECTION_INBOUND,
269 .SYNC_rate = SYNC_RATE,
270 .data_rate = DATA_SYNC_RATE,
271 .last_recvSYNC = current_time(),
272 .last_sent = current_time(),
273 .send_counter = 127,
274
275 .timeout = timeout,
276
277 /* If this connection isn't handled within the timeout kill it. */
278 .killat = current_time() + 1000000ULL * timeout,
279 .confirmed = 0
280 };
281 connection->sendbuffer_length = resize_queue(&connection->sendbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0);
282 connection->recvbuffer_length = resize_queue(&connection->recvbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0);
283
284 if (connection->sendbuffer_length == (uint32_t)~0 || connection->recvbuffer_length == (uint32_t)~0) {
285 free(connection->sendbuffer);
286 free(connection->recvbuffer);
287 memset(connection, 0, sizeof(Connection));
288 return -1;
289 }
290
291 return connection_id;
292}
293
294/*
295 * return an integer corresponding to the next connection in our incoming connection list with at least numpackets in the recieve queue.
296 * return -1 if there are no new incoming connections in the list.
297 */
298int incoming_connection(Lossless_UDP *ludp, uint32_t numpackets)
299{
300 tox_array_for_each(&ludp->connections, Connection, tmp) {
301 if (tmp->inbound == LUDP_CONNECTION_INBOUND && tmp->recv_packetnum - tmp->successful_read >= numpackets) {
302 tmp->inbound = LUDP_CONNECTION_INBOUND_HANDLED;
303 return tmp_i;
304 }
305 }
306 return -1;
307}
308/* Try to free some memory from the connections array. */
309static void free_connections(Lossless_UDP *ludp)
310{
311 uint32_t i;
312
313 for (i = ludp->connections.len; i != 0; --i) {
314 Connection *connection = &tox_array_get(&ludp->connections, i - 1, Connection);
315
316 if (connection->status != LUDP_NO_CONNECTION)
317 break;
318 }
319
320 if (ludp->connections.len == i)
321 return;
322
323 return tox_array_pop(&ludp->connections, ludp->connections.len - i);
324}
325/* return -1 if it could not kill the connection.
326 * return 0 if killed successfully.
327 */
328int kill_connection(Lossless_UDP *ludp, int connection_id)
329{
330 if ((unsigned int)connection_id < ludp->connections.len) {
331 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
332
333 if (connection->status != LUDP_NO_CONNECTION) {
334 connection->status = LUDP_NO_CONNECTION;
335 change_handshake(ludp, connection->ip_port);
336 free(connection->sendbuffer);
337 free(connection->recvbuffer);
338 memset(connection, 0, sizeof(Connection));
339 free_connections(ludp);
340 return 0;
341 }
342 }
343
344 return -1;
345}
346
347/*
348 * timeout connection in seconds.
349 *
350 * return -1 if it can not kill the connection.
351 * return 0 if it will kill it.
352 */
353int timeout_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds)
354{
355 if ((unsigned int)connection_id < ludp->connections.len) {
356 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
357
358 if (connection->status != LUDP_NO_CONNECTION) {
359 connection->killat = current_time() + 1000000ULL * seconds;
360 return 0;
361 }
362 }
363
364 return -1;
365}
366
367/*
368 * Check if connection is connected:
369 *
370 * return LUDP_NO_CONNECTION if not.
371 * return LUDP_HANDSHAKE_SENDING if attempting handshake.
372 * return LUDP_NOT_CONFIRMED if handshake is done.
373 * return LUDP_ESTABLISHED if fully connected.
374 * return LUDP_TIMED_OUT if timed out and waiting to be killed.
375 */
376int is_connected(Lossless_UDP *ludp, int connection_id)
377{
378 if ((unsigned int)connection_id < ludp->connections.len)
379 return tox_array_get(&ludp->connections, connection_id, Connection).status;
380
381 return 0;
382}
383
384/* Check if connection is confirmed.
385 *
386 * returns 1 if yes.
387 * returns 0 if no/failure.
388 */
389int connection_confirmed(Lossless_UDP *ludp, int connection_id)
390{
391 if ((unsigned int)connection_id >= ludp->connections.len)
392 return 0;
393
394 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
395
396 if (connection->status == LUDP_NO_CONNECTION)
397 return 0;
398
399 if (connection->confirmed == 1)
400 return 1;
401
402 return 0;
403}
404
405/* Confirm an incoming connection.
406 * Also disable the auto kill timeout on incomming connections.
407 *
408 * return 0 on success
409 * return -1 on failure.
410 */
411int confirm_connection(Lossless_UDP *ludp, int connection_id)
412{
413 if ((unsigned int)connection_id >= ludp->connections.len)
414 return -1;
415
416 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
417
418 if (connection->status == LUDP_NO_CONNECTION)
419 return -1;
420
421 connection->killat = ~0;
422 connection->confirmed = 1;
423 connection->inbound = LUDP_CONNECTION_OUTBOUND;
424 return 0;
425}
426
427/* return the ip_port of the corresponding connection. */
428IP_Port connection_ip(Lossless_UDP *ludp, int connection_id)
429{
430 if ((unsigned int)connection_id < ludp->connections.len)
431 return tox_array_get(&ludp->connections, connection_id, Connection).ip_port;
432
433 IP_Port zero;
434 ip_reset(&zero.ip);
435 zero.port = 0;
436 return zero;
437}
438
439/* return the number of packets in the queue waiting to be successfully sent. */
440uint32_t sendqueue(Lossless_UDP *ludp, int connection_id)
441{
442 if ((unsigned int)connection_id >= ludp->connections.len)
443 return 0;
444
445 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
446
447 if (connection->status == LUDP_NO_CONNECTION)
448 return 0;
449
450 return connection->sendbuff_packetnum - connection->successful_sent;
451}
452
453/* return number of packets in all queues waiting to be successfully sent. */
454uint32_t sendqueue_total(Lossless_UDP *ludp)
455{
456 uint32_t i, total = 0;
457
458 for (i = 0; i < ludp->connections.len; i++) {
459 Connection *connection = &tox_array_get(&ludp->connections, i, Connection);
460
461 if (connection->status != 0)
462 total += connection->sendbuff_packetnum - connection->successful_sent;
463 }
464
465 return total;
466}
467
468/* return the number of packets in the queue waiting to be successfully read with read_packet(...). */
469uint32_t recvqueue(Lossless_UDP *ludp, int connection_id)
470{
471 if ((unsigned int)connection_id >= ludp->connections.len)
472 return 0;
473
474 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
475
476 if (connection->status == LUDP_NO_CONNECTION)
477 return 0;
478
479 return connection->recv_packetnum - connection->successful_read;
480}
481
482/* return the id of the next packet in the queue.
483 * return ~0 if no packet in queue.
484 */
485uint8_t id_packet(Lossless_UDP *ludp, int connection_id)
486{
487 if (recvqueue(ludp, connection_id) == 0)
488 return ~0;
489
490 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
491
492 if (connection->status != LUDP_NO_CONNECTION)
493 return connection->recvbuffer[connection->successful_read % connection->recvbuffer_length].data[0];
494
495 return ~0;
496}
497
498/* return 0 if there is no received data in the buffer.
499 * return length of received packet if successful.
500 */
501int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data)
502{
503 if (recvqueue(ludp, connection_id) == 0)
504 return 0;
505
506 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
507
508 if (connection->status == LUDP_NO_CONNECTION)
509 return 0;
510
511 uint16_t index = connection->successful_read % connection->recvbuffer_length;
512 uint16_t size = connection->recvbuffer[index].size;
513 memcpy(data, connection->recvbuffer[index].data, size);
514 ++connection->successful_read;
515 connection->recvbuffer[index].size = 0;
516 return size;
517}
518
519/* Like read_packet() but does leaves the queue as is.
520 * return 0 if there is no received data in the buffer.
521 * return length of received packet if successful.
522 */
523int read_packet_silent(Lossless_UDP *ludp, int connection_id, uint8_t *data)
524{
525 if (recvqueue(ludp, connection_id) == 0)
526 return 0;
527
528 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
529
530 if (connection->status == LUDP_NO_CONNECTION)
531 return 0;
532
533 uint16_t index = connection->successful_read % connection->recvbuffer_length;
534 uint16_t size = connection->recvbuffer[index].size;
535 memcpy(data, connection->recvbuffer[index].data, size);
536 return size;
537}
538/* Discard the next packet to be read from the queue
539 * return 0 if success.
540 * return -1 if failure.
541 */
542int discard_packet(Lossless_UDP *ludp, int connection_id)
543{
544 if (recvqueue(ludp, connection_id) == 0)
545 return -1;
546
547 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
548 uint16_t index = connection->successful_read % connection->recvbuffer_length;
549 ++connection->successful_read;
550 connection->recvbuffer[index].size = 0;
551 return 0;
552}
553
554#define MAX_SYNC_RATE 20
555#define MIN_SLOTS 16
556/* returns the number of packet slots left in the sendbuffer.
557 * return 0 if failure.
558 */
559uint32_t num_free_sendqueue_slots(Lossless_UDP *ludp, int connection_id)
560{
561 if ((unsigned int)connection_id >= ludp->connections.len)
562 return 0;
563
564 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
565 uint32_t max_slots = (connection->data_rate / MAX_SYNC_RATE) * 1.5;
566
567 if (max_slots > MAX_QUEUE_NUM)
568 max_slots = MAX_QUEUE_NUM;
569
570 if (max_slots < MIN_SLOTS)
571 max_slots = MIN_SLOTS;
572
573 if (sendqueue(ludp, connection_id) > max_slots)
574 return 0;
575
576 return max_slots - sendqueue(ludp, connection_id);
577}
578
579
580/* return 0 if data could not be put in packet queue.
581 * return 1 if data was put into the queue.
582 */
583int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t length)
584{
585 if ((unsigned int)connection_id >= ludp->connections.len)
586 return 0;
587
588 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
589
590 if (connection->status == LUDP_NO_CONNECTION)
591 return 0;
592
593 if (length > MAX_DATA_SIZE || length == 0 || sendqueue(ludp, connection_id) >= MAX_QUEUE_NUM)
594 return 0;
595
596 if (num_free_sendqueue_slots(ludp, connection_id) == 0)
597 return 0;
598
599 if (sendqueue(ludp, connection_id) >= connection->sendbuffer_length && connection->sendbuffer_length != 0) {
600 uint32_t newlen = connection->sendbuffer_length = resize_queue(&connection->sendbuffer, connection->sendbuffer_length,
601 connection->sendbuffer_length * 2, connection->successful_sent, connection->sendbuff_packetnum);
602
603 if (newlen == (uint32_t)~0)
604 return 0;
605
606 connection->sendbuffer_length = newlen;
607 return write_packet(ludp, connection_id, data, length);
608 }
609
610 uint32_t index = connection->sendbuff_packetnum % connection->sendbuffer_length;
611 memcpy(connection->sendbuffer[index].data, data, length);
612 connection->sendbuffer[index].size = length;
613 connection->sendbuff_packetnum++;
614 return 1;
615}
616
617/* Put the packet numbers the we are missing in requested and return the number. */
618static uint32_t missing_packets(Lossless_UDP *ludp, int connection_id, uint32_t *requested)
619{
620 if ((unsigned int)connection_id >= ludp->connections.len)
621 return 0;
622
623 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
624
625 /* Don't request packets if the buffer is full. */
626 if (recvqueue(ludp, connection_id) >= (connection->recvbuffer_length - 1))
627 return 0;
628
629 uint32_t number = 0;
630 uint32_t i;
631 uint32_t temp;
632
633 for (i = connection->recv_packetnum;
634 i != connection->osent_packetnum;
635 i++) {
636 if (connection->recvbuffer[i % connection->recvbuffer_length].size == 0) {
637 temp = htonl(i);
638 memcpy(requested + number, &temp, 4);
639 ++number;
640 }
641
642 if (number >= MAX_REQUESTED_PACKETS)
643 return number;
644 }
645
646 if (number == 0)
647 connection->recv_packetnum = connection->osent_packetnum;
648
649 return number;
650}
651
652/*
653 * BEGIN Packet sending functions.
654 * One per packet type.
655 * See http://wiki.tox.im/index.php/Lossless_UDP for more information.
656 */
657
658static int send_handshake(Lossless_UDP *ludp, IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)
659{
660 uint8_t packet[1 + 4 + 4];
661 uint32_t temp;
662
663 packet[0] = NET_PACKET_HANDSHAKE;
664 temp = htonl(handshake_id1);
665 memcpy(packet + 1, &temp, 4);
666 temp = htonl(handshake_id2);
667 memcpy(packet + 5, &temp, 4);
668
669 return sendpacket(ludp->net, ip_port, packet, sizeof(packet));
670}
671
672static int send_SYNC(Lossless_UDP *ludp, int connection_id)
673{
674 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
675 uint8_t packet[(MAX_REQUESTED_PACKETS * 4 + 4 + 4 + 2)];
676 uint16_t index = 0;
677
678 IP_Port ip_port = connection->ip_port;
679 uint8_t counter = connection->send_counter;
680 uint32_t recv_packetnum = htonl(connection->recv_packetnum);
681 uint32_t sent_packetnum = htonl(connection->sent_packetnum);
682
683 uint32_t requested[MAX_REQUESTED_PACKETS];
684 uint32_t number = missing_packets(ludp, connection_id, requested);
685
686 packet[0] = NET_PACKET_SYNC;
687 index += 1;
688 memcpy(packet + index, &counter, 1);
689 index += 1;
690 memcpy(packet + index, &recv_packetnum, 4);
691 index += 4;
692 memcpy(packet + index, &sent_packetnum, 4);
693 index += 4;
694 memcpy(packet + index, requested, 4 * number);
695
696 return sendpacket(ludp->net, ip_port, packet, (number * 4 + 4 + 4 + 2));
697
698}
699
700static int send_data_packet(Lossless_UDP *ludp, int connection_id, uint32_t packet_num)
701{
702 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
703
704 uint32_t index = packet_num % connection->sendbuffer_length;
705 uint32_t temp;
706 uint8_t packet[1 + 4 + MAX_DATA_SIZE];
707 packet[0] = NET_PACKET_DATA;
708 temp = htonl(packet_num);
709 memcpy(packet + 1, &temp, 4);
710 memcpy(packet + 5, connection->sendbuffer[index].data, connection->sendbuffer[index].size);
711 return sendpacket(ludp->net, connection->ip_port, packet, 1 + 4 + connection->sendbuffer[index].size);
712}
713
714/* Sends 1 data packet. */
715static int send_DATA(Lossless_UDP *ludp, int connection_id)
716{
717 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
718 int ret;
719 uint32_t buffer[MAX_REQUESTED_PACKETS];
720
721 if (connection->num_req_paquets > 0) {
722 ret = send_data_packet(ludp, connection_id, connection->req_packets[0]);
723 connection->num_req_paquets--;
724 memcpy(buffer, connection->req_packets + 1, connection->num_req_paquets * 4);
725 memcpy(connection->req_packets, buffer, connection->num_req_paquets * 4);
726 return ret;
727 }
728
729 if (connection->sendbuff_packetnum != connection->sent_packetnum) {
730 ret = send_data_packet(ludp, connection_id, connection->sent_packetnum);
731 connection->sent_packetnum++;
732 return ret;
733 }
734
735 return 0;
736}
737
738/*
739 * END of packet sending functions.
740 *
741 *
742 * BEGIN Packet handling functions.
743 * One to handle each type of packets we receive.
744 */
745
746
747/* return 0 if handled correctly.
748 * return 1 if packet is bad.
749 */
750static int handle_handshake(void *object, IP_Port source, uint8_t *packet, uint32_t length)
751{
752 Lossless_UDP *ludp = object;
753
754 if (length != (1 + 4 + 4))
755 return 1;
756
757 uint32_t temp;
758 uint32_t handshake_id1, handshake_id2;
759 int connection_id = getconnection_id(ludp, source);
760
761 memcpy(&temp, packet + 1, 4);
762 handshake_id1 = ntohl(temp);
763 memcpy(&temp, packet + 5, 4);
764 handshake_id2 = ntohl(temp);
765
766
767 if (handshake_id2 == 0 && is_connected(ludp, connection_id) != LUDP_ESTABLISHED &&
768 is_connected(ludp, connection_id) != LUDP_TIMED_OUT) {
769 send_handshake(ludp, source, handshake_id(ludp, source), handshake_id1);
770 return 0;
771 }
772
773 if (is_connected(ludp, connection_id) != LUDP_HANDSHAKE_SENDING)
774 return 1;
775
776 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
777
778 /* if handshake_id2 is what we sent previously as handshake_id1 */
779 if (handshake_id2 == connection->handshake_id1) {
780 connection->status = LUDP_NOT_CONFIRMED;
781 /* NOTE: Is this necessary?
782 connection->handshake_id2 = handshake_id1; */
783 connection->orecv_packetnum = handshake_id2;
784 connection->osent_packetnum = handshake_id1;
785 connection->recv_packetnum = handshake_id1;
786 connection->successful_read = handshake_id1;
787 }
788
789 return 0;
790}
791
792/* return 1 if sync packet is valid.
793 * return 0 if not.
794 */
795static int SYNC_valid(uint32_t length)
796{
797 if (length < 4 + 4 + 2)
798 return 0;
799
800 if (length > (MAX_REQUESTED_PACKETS * 4 + 4 + 4 + 2) ||
801 ((length - 4 - 4 - 2) % 4) != 0)
802 return 0;
803
804 return 1;
805}
806
807/* case 1 in handle_SYNC: */
808static int handle_SYNC1(Lossless_UDP *ludp, IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
809{
810 if (handshake_id(ludp, source) == recv_packetnum) {
811 int connection_id = new_inconnection(ludp, source);
812
813 if (connection_id != -1) {
814 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
815 connection->orecv_packetnum = recv_packetnum;
816 connection->sent_packetnum = recv_packetnum;
817 connection->sendbuff_packetnum = recv_packetnum;
818 connection->successful_sent = recv_packetnum;
819 connection->osent_packetnum = sent_packetnum;
820 connection->recv_packetnum = sent_packetnum;
821 connection->successful_read = sent_packetnum;
822
823 return connection_id;
824 }
825 }
826
827 return -1;
828}
829
830/* case 2 in handle_SYNC: */
831static int handle_SYNC2(Lossless_UDP *ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum,
832 uint32_t sent_packetnum)
833{
834 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
835
836 if (recv_packetnum == connection->orecv_packetnum && sent_packetnum == connection->osent_packetnum) {
837 connection->status = LUDP_ESTABLISHED;
838 connection->recv_counter = counter;
839 ++connection->send_counter;
840 send_SYNC(ludp, connection_id);
841 return 0;
842 }
843
844 return 1;
845}
846
847/*
848 * Automatically adjusts send rates of data packets for optimal transmission.
849 *
850 * TODO: Improve this.
851 */
852static void adjust_datasendspeed(Connection *connection, uint32_t req_packets)
853{
854 /* if there are no packets in send buffer */
855 if (connection->sendbuff_packetnum - connection->successful_sent == 0) {
856 connection->data_rate -= connection->data_rate / 8;
857
858 if (connection->data_rate < DATA_SYNC_RATE)
859 connection->data_rate = DATA_SYNC_RATE;
860
861 return;
862 }
863
864 if (req_packets <= (connection->data_rate / connection->SYNC_rate) / 4 || req_packets <= 10) {
865 connection->data_rate += (connection->data_rate / 4) + 1;
866
867 if (connection->data_rate > connection->sendbuffer_length * connection->SYNC_rate)
868 connection->data_rate = connection->sendbuffer_length * connection->SYNC_rate;
869 } else {
870 connection->data_rate -= connection->data_rate / 8;
871 }
872}
873
874
875/* case 3 in handle_SYNC: */
876static int handle_SYNC3(Lossless_UDP *ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum,
877 uint32_t sent_packetnum,
878 uint32_t *req_packets,
879 uint16_t number)
880{
881 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
882
883 uint8_t comp_counter = (counter - connection->recv_counter);
884 uint32_t i, temp;
885 /* uint32_t comp_1 = (recv_packetnum - connection->successful_sent);
886 uint32_t comp_2 = (sent_packetnum - connection->successful_read); */
887 uint32_t comp_1 = (recv_packetnum - connection->orecv_packetnum);
888 uint32_t comp_2 = (sent_packetnum - connection->osent_packetnum);
889
890 /* Packet valid. */
891 if (comp_1 <= connection->sendbuffer_length &&
892 comp_2 <= MAX_QUEUE_NUM &&
893 comp_counter != 0 && comp_counter < 8) {
894 connection->orecv_packetnum = recv_packetnum;
895 connection->osent_packetnum = sent_packetnum;
896 connection->successful_sent = recv_packetnum;
897 connection->last_recvSYNC = current_time();
898
899 connection->recv_counter = counter;
900
901 ++connection->send_counter;
902
903 for (i = 0; i < number; ++i) {
904 temp = ntohl(req_packets[i]);
905 memcpy(connection->req_packets + i, &temp, sizeof(uint32_t));
906 }
907
908 connection->num_req_paquets = number;
909 adjust_datasendspeed(connection, number);
910 return 0;
911 }
912
913 return 1;
914}
915
916static int handle_SYNC(void *object, IP_Port source, uint8_t *packet, uint32_t length)
917{
918 Lossless_UDP *ludp = object;
919
920 if (!SYNC_valid(length))
921 return 1;
922
923 uint8_t counter;
924 uint32_t temp;
925 uint32_t recv_packetnum, sent_packetnum;
926 uint16_t number = (length - 4 - 4 - 2) / 4;
927 uint32_t req_packets[number];
928
929 memcpy(&counter, packet + 1, 1);
930 memcpy(&temp, packet + 2, 4);
931 recv_packetnum = ntohl(temp);
932 memcpy(&temp, packet + 6, 4);
933 sent_packetnum = ntohl(temp);
934
935 if (number != 0)
936 memcpy(req_packets, packet + 10, 4 * number);
937
938 int connection_id = getconnection_id(ludp, source);
939
940 if (connection_id == -1)
941 return handle_SYNC1(ludp, source, recv_packetnum, sent_packetnum);
942
943 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
944
945 if (connection->status == LUDP_NOT_CONFIRMED)
946 return handle_SYNC2(ludp, connection_id, counter,
947 recv_packetnum, sent_packetnum);
948
949 if (connection->status == LUDP_ESTABLISHED)
950 return handle_SYNC3(ludp, connection_id, counter, recv_packetnum,
951 sent_packetnum, req_packets, number);
952
953 return 0;
954}
955
956/*
957 * Add a packet to the received buffer and set the recv_packetnum of the
958 * connection to its proper value.
959 *
960 * return 1 if data was too big.
961 * return 0 if not.
962 */
963static int add_recv(Lossless_UDP *ludp, int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
964{
965 if (size > MAX_DATA_SIZE)
966 return 1;
967
968 Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection);
969 uint32_t i;
970 uint32_t test = data_num - connection->recv_packetnum;
971
972 if (test > MAX_QUEUE_NUM)
973 return 0;
974
975 if (test > connection->recvbuffer_length) {
976 if (connection->confirmed == 0)
977 return 0;
978
979 uint32_t len = resize_queue(&connection->recvbuffer, connection->recvbuffer_length, test * 2,
980 connection->successful_read, connection->successful_read + connection->recvbuffer_length);
981
982 if (len == (uint32_t)~0)
983 return 0;
984
985 connection->recvbuffer_length = len;
986 }
987
988 uint32_t maxnum = connection->successful_read + connection->recvbuffer_length;
989 uint32_t sent_packet = data_num - connection->osent_packetnum;
990
991 for (i = connection->recv_packetnum; i != maxnum; ++i) {
992 if (i == data_num) {
993 memcpy(connection->recvbuffer[data_num % connection->recvbuffer_length].data, data, size);
994
995 connection->recvbuffer[data_num % connection->recvbuffer_length].size = size;
996 connection->last_recvdata = current_time();
997
998 if (sent_packet < connection->recvbuffer_length)
999 connection->osent_packetnum = data_num;
1000
1001 break;
1002 }
1003 }
1004
1005 for (i = connection->recv_packetnum; i != maxnum; ++i) {
1006 if (connection->recvbuffer[i % connection->recvbuffer_length].size != 0)
1007 connection->recv_packetnum = i;
1008 else
1009 break;
1010 }
1011
1012 return 0;
1013}
1014
1015static int handle_data(void *object, IP_Port source, uint8_t *packet, uint32_t length)
1016{
1017 Lossless_UDP *ludp = object;
1018 int connection_id = getconnection_id(ludp, source);
1019
1020 /* Drop the data packet if connection is not connected. */
1021 if (connection_id == -1)
1022 return 1;
1023
1024 if (tox_array_get(&ludp->connections, connection_id, Connection).status != LUDP_ESTABLISHED)
1025 return 1;
1026
1027 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
1028 return 1;
1029
1030 uint32_t temp;
1031 uint32_t number;
1032 uint16_t size = length - 1 - 4;
1033
1034 memcpy(&temp, packet + 1, 4);
1035 number = ntohl(temp);
1036
1037 return add_recv(ludp, connection_id, number, packet + 5, size);
1038}
1039
1040/*
1041 * END of packet handling functions.
1042 */
1043
1044Lossless_UDP *new_lossless_udp(Networking_Core *net)
1045{
1046 if (net == NULL)
1047 return NULL;
1048
1049 Lossless_UDP *temp = calloc(1, sizeof(Lossless_UDP));
1050
1051 if (temp == NULL)
1052 return NULL;
1053
1054 tox_array_init(&temp->connections, sizeof(Connection));
1055
1056 temp->net = net;
1057 networking_registerhandler(net, NET_PACKET_HANDSHAKE, &handle_handshake, temp);
1058 networking_registerhandler(net, NET_PACKET_SYNC, &handle_SYNC, temp);
1059 networking_registerhandler(net, NET_PACKET_DATA, &handle_data, temp);
1060 return temp;
1061}
1062
1063/*
1064 * Send handshake requests.
1065 * Handshake packets are sent at the same rate as SYNC packets.
1066 */
1067static void do_new(Lossless_UDP *ludp)
1068{
1069 uint64_t temp_time = current_time();
1070
1071 tox_array_for_each(&ludp->connections, Connection, tmp) {
1072 if (tmp->status == LUDP_HANDSHAKE_SENDING && (tmp->last_sent + (1000000ULL / tmp->SYNC_rate)) <= temp_time) {
1073 send_handshake(ludp, tmp->ip_port, tmp->handshake_id1, 0);
1074 tmp->last_sent = temp_time;
1075 }
1076
1077 /* kill all timed out connections */
1078 if (tmp->status != LUDP_NO_CONNECTION && (tmp->last_recvSYNC + tmp->timeout * 1000000ULL) < temp_time
1079 && tmp->status != LUDP_TIMED_OUT) {
1080 tmp->status = LUDP_TIMED_OUT;
1081 /* kill_connection(i); */
1082 }
1083
1084 if (tmp->status != LUDP_NO_CONNECTION && tmp->killat < temp_time)
1085 tmp->status = LUDP_TIMED_OUT;
1086
1087 if (tmp->inbound == LUDP_CONNECTION_INBOUND && tmp->status == LUDP_TIMED_OUT)
1088 kill_connection(ludp, tmp_i);
1089 }
1090}
1091
1092static void do_SYNC(Lossless_UDP *ludp)
1093{
1094 uint64_t temp_time = current_time();
1095
1096 tox_array_for_each(&ludp->connections, Connection, tmp) {
1097 if (tmp->status == LUDP_NOT_CONFIRMED || tmp->status == LUDP_ESTABLISHED)
1098 if ((tmp->last_SYNC + (1000000ULL / tmp->SYNC_rate)) <= temp_time) {
1099 send_SYNC(ludp, tmp_i);
1100 tmp->last_SYNC = temp_time;
1101 }
1102 }
1103}
1104
1105static void do_data(Lossless_UDP *ludp)
1106{
1107 uint64_t j;
1108 uint64_t temp_time = current_time();
1109
1110 tox_array_for_each(&ludp->connections, Connection, tmp) {
1111 if (tmp->status == LUDP_ESTABLISHED && sendqueue(ludp, tmp_i) != 0 &&
1112 (tmp->last_sent + (1000000ULL / tmp->data_rate)) <= temp_time) {
1113 for (j = tmp->last_sent; j < temp_time; j += (1000000ULL / tmp->data_rate))
1114 if (send_DATA(ludp, tmp_i) <= 0)
1115 break;
1116
1117 tmp->last_sent = temp_time;
1118
1119 }
1120 }
1121}
1122
1123
1124
1125/*
1126 * Automatically adjusts send rates of packets for optimal transmission.
1127 *
1128 * TODO: Flow control.
1129 */
1130static void adjust_rates(Lossless_UDP *ludp)
1131{
1132 uint64_t temp_time = current_time();
1133
1134 tox_array_for_each(&ludp->connections, Connection, tmp) {
1135 if (tmp->status == LUDP_HANDSHAKE_SENDING || tmp->status == LUDP_NOT_CONFIRMED)
1136 tmp->SYNC_rate = MAX_SYNC_RATE;
1137
1138 if (tmp->status == LUDP_ESTABLISHED) {
1139 if (sendqueue(ludp, tmp_i) != 0) {
1140 tmp->SYNC_rate = MAX_SYNC_RATE;
1141 } else if (tmp->last_recvdata + 200000ULL > temp_time) { /* 200 ms */
1142 tmp->SYNC_rate = MAX_SYNC_RATE;
1143 } else {
1144 tmp->SYNC_rate = SYNC_RATE;
1145 }
1146 }
1147 }
1148}
1149
1150/* Call this function a couple times per second. It is the main loop. */
1151void do_lossless_udp(Lossless_UDP *ludp)
1152{
1153 do_new(ludp);
1154 do_SYNC(ludp);
1155 do_data(ludp);
1156 adjust_rates(ludp);
1157}
1158
1159void kill_lossless_udp(Lossless_UDP *ludp)
1160{
1161 uint32_t i;
1162
1163 for (i = 0; i < ludp->connections.len; ++i)
1164 kill_connection(ludp, i);
1165
1166 tox_array_delete(&ludp->connections);
1167 free(ludp);
1168}
diff --git a/toxcore/Lossless_UDP.h b/toxcore/Lossless_UDP.h
deleted file mode 100644
index b23d602a..00000000
--- a/toxcore/Lossless_UDP.h
+++ /dev/null
@@ -1,261 +0,0 @@
1/* Lossless_UDP.h
2 *
3 * An implementation of the Lossless_UDP protocol as seen in http://wiki.tox.im/index.php/Lossless_UDP
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#ifndef LOSSLESS_UDP_H
25#define LOSSLESS_UDP_H
26
27#include "network.h"
28#include "misc_tools.h"
29
30
31/* Maximum length of the data in the data packets. */
32#define MAX_DATA_SIZE 1024
33
34/* Maximum data packets in sent and receive queues. */
35#define MAX_QUEUE_NUM 1024
36#define DEFAULT_QUEUE_NUM 4
37
38/* Maximum number of data packets in the buffer. */
39#define MAX_REQUESTED_PACKETS 256
40
41/* Timeout per connection is randomly set between CONNECTION_TIMEOUT and 2*CONNECTION_TIMEOUT. */
42#define CONNECTION_TIMEOUT 5
43
44/* Initial amount of sync/handshake packets to send per second. */
45#define SYNC_RATE 2
46
47/* Initial send rate of data. */
48#define DATA_SYNC_RATE 30
49
50typedef struct {
51 uint8_t data[MAX_DATA_SIZE];
52 uint16_t size;
53} Data;
54
55#define LUDP_NO_CONNECTION 0
56#define LUDP_HANDSHAKE_SENDING 1
57#define LUDP_NOT_CONFIRMED 2
58#define LUDP_ESTABLISHED 3
59#define LUDP_TIMED_OUT 4
60
61typedef struct {
62 IP_Port ip_port;
63
64 /*
65 * return LUDP_NO_CONNECTION if connection is dead.
66 * return LUDP_HANDSHAKE_SENDING if attempting handshake.
67 * return LUDP_NOT_CONFIRMED if handshake is done (we start sending SYNC packets).
68 * return LUDP_ESTABLISHED if we are sending SYNC packets and can send data.
69 * return LUDP_TIMED_OUT if the connection has timed out.
70 */
71 uint8_t status;
72
73 /*
74 * return 0 if connection was not initiated by someone else.
75 * return 1 if incoming_connection() has returned.
76 * return 2 if it has not.
77 */
78 uint8_t inbound;
79
80 uint16_t SYNC_rate; /* Current SYNC packet send rate packets per second. */
81 uint32_t data_rate; /* Current data packet send rate packets per second. */
82
83 uint64_t last_SYNC; /* Time our last SYNC packet was sent. */
84 uint64_t last_sent; /* Time our last data or handshake packet was sent. */
85 uint64_t last_recvSYNC; /* Time we last received a SYNC packet from the other. */
86 uint64_t last_recvdata; /* Time we last received a DATA packet from the other. */
87 uint64_t killat; /* Time to kill the connection. */
88
89 Data *sendbuffer; /* packet send buffer. */
90 uint32_t sendbuffer_length;
91 Data *recvbuffer; /* packet receive buffer. */
92 uint32_t recvbuffer_length;
93 uint32_t handshake_id1;
94 uint32_t handshake_id2;
95
96 /* Number of data packets received (also used as handshake_id1). */
97 uint32_t recv_packetnum;
98
99 /* Number of packets received by the other peer. */
100 uint32_t orecv_packetnum;
101
102 /* Number of data packets sent. */
103 uint32_t sent_packetnum;
104
105 /* Number of packets sent by the other peer. */
106 uint32_t osent_packetnum;
107
108 /* Number of latest packet written onto the sendbuffer. */
109 uint32_t sendbuff_packetnum;
110
111 /* We know all packets before that number were successfully sent. */
112 uint32_t successful_sent;
113
114 /* Packet number of last packet read with the read_packet function. */
115 uint32_t successful_read;
116
117 /* List of currently requested packet numbers(by the other person). */
118 uint32_t req_packets[MAX_REQUESTED_PACKETS];
119
120 /* Total number of currently requested packets(by the other person). */
121 uint16_t num_req_paquets;
122
123 uint8_t recv_counter;
124 uint8_t send_counter;
125 uint8_t timeout; /* connection timeout in seconds. */
126
127 /* Is the connection confirmed or not? 1 if yes, 0 if no */
128 uint8_t confirmed;
129} Connection;
130
131typedef struct {
132 Networking_Core *net;
133
134 tox_array connections;
135
136 /* Table of random numbers used in handshake_id. */
137 /* IPv6 (16) + port (2)*/
138 uint32_t randtable[18][256];
139} Lossless_UDP;
140
141/*
142 * Initialize a new connection to ip_port.
143 *
144 * return an integer corresponding to the connection id.
145 * return -1 if it could not initialize the connection.
146 * return number if there already was an existing connection to that ip_port.
147 */
148int new_connection(Lossless_UDP *ludp, IP_Port ip_port);
149
150/*
151 * Get connection id from IP_Port.
152 *
153 * return -1 if there are no connections like we are looking for.
154 * return id if it found it .
155 */
156int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port);
157
158/*
159 * return an integer corresponding to the next connection in our incoming connection list with at least numpackets in the recieve queue.
160 * return -1 if there are no new incoming connections in the list.
161 */
162int incoming_connection(Lossless_UDP *ludp, uint32_t numpackets);
163
164/* return -1 if it could not kill the connection.
165 * return 0 if killed successfully.
166 */
167int kill_connection(Lossless_UDP *ludp, int connection_id);
168
169/*
170 * timeout connection in seconds seconds.
171 *
172 * return -1 if it can not kill the connection.
173 * return 0 if it will kill it.
174 */
175int timeout_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds);
176
177
178/* Check if connection is confirmed.
179 *
180 * returns 1 if yes.
181 * returns 0 if no.
182 */
183int connection_confirmed(Lossless_UDP *ludp, int connection_id);
184
185/* Confirm an incoming connection.
186 * Also disables the auto kill timeout on incomming connections.
187 *
188 * return 0 on success
189 * return -1 on failure.
190 */
191int confirm_connection(Lossless_UDP *ludp, int connection_id);
192
193/* returns the ip_port of the corresponding connection.
194 * return 0 if there is no such connection.
195 */
196IP_Port connection_ip(Lossless_UDP *ludp, int connection_id);
197
198/* returns the id of the next packet in the queue.
199 * return -1 if no packet in queue.
200 */
201uint8_t id_packet(Lossless_UDP *ludp, int connection_id);
202
203/* return 0 if there is no received data in the buffer.
204 * return length of received packet if successful.
205 */
206int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data);
207
208/* Like read_packet() but does leaves the queue as is.
209 * return 0 if there is no received data in the buffer.
210 * return length of received packet if successful.
211 */
212int read_packet_silent(Lossless_UDP *ludp, int connection_id, uint8_t *data);
213
214/* Discard the next packet to be read from the queue
215 * return 0 if success.
216 * return -1 if failure.
217 */
218int discard_packet(Lossless_UDP *ludp, int connection_id);
219
220/* returns the number of packet slots left in the sendbuffer.
221 * return 0 if failure.
222 */
223uint32_t num_free_sendqueue_slots(Lossless_UDP *ludp, int connection_id);
224
225/* return 0 if data could not be put in packet queue.
226 * return 1 if data was put into the queue.
227 */
228int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t length);
229
230/* return number of packets in the queue waiting to be successfully sent. */
231uint32_t sendqueue(Lossless_UDP *ludp, int connection_id);
232
233/* return number of packets in all queues waiting to be successfully sent. */
234uint32_t sendqueue_total(Lossless_UDP *ludp);
235
236/*
237 * return number of packets in the queue waiting to be successfully
238 * read with read_packet(...).
239 */
240uint32_t recvqueue(Lossless_UDP *ludp, int connection_id);
241
242/* Check if connection is connected:
243 *
244 * return LUDP_NO_CONNECTION if not.
245 * return LUDP_HANDSHAKE_SENDING if attempting handshake.
246 * return LUDP_NOT_CONFIRMED if handshake is done.
247 * return LUDP_ESTABLISHED if fully connected.
248 * return LUDP_TIMED_OUT if timed out and wating to be killed.
249 */
250int is_connected(Lossless_UDP *ludp, int connection_id);
251
252/* Call this function a couple times per second. It is the main loop. */
253void do_lossless_udp(Lossless_UDP *ludp);
254
255/* This function sets up LosslessUDP packet handling. */
256Lossless_UDP *new_lossless_udp(Networking_Core *net);
257
258void kill_lossless_udp(Lossless_UDP *ludp);
259
260
261#endif
diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc
index 5f9ab0d7..0760952a 100644
--- a/toxcore/Makefile.inc
+++ b/toxcore/Makefile.inc
@@ -9,8 +9,10 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \
9 ../toxcore/DHT.c \ 9 ../toxcore/DHT.c \
10 ../toxcore/network.h \ 10 ../toxcore/network.h \
11 ../toxcore/network.c \ 11 ../toxcore/network.c \
12 ../toxcore/Lossless_UDP.h \ 12 ../toxcore/crypto_core.h \
13 ../toxcore/Lossless_UDP.c \ 13 ../toxcore/crypto_core.c \
14 ../toxcore/ping_array.h \
15 ../toxcore/ping_array.c \
14 ../toxcore/net_crypto.h \ 16 ../toxcore/net_crypto.h \
15 ../toxcore/net_crypto.c \ 17 ../toxcore/net_crypto.c \
16 ../toxcore/friend_requests.h \ 18 ../toxcore/friend_requests.h \
@@ -52,6 +54,7 @@ libtoxcore_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \
52 $(EXTRA_LT_LDFLAGS) \ 54 $(EXTRA_LT_LDFLAGS) \
53 $(LIBSODIUM_LDFLAGS) \ 55 $(LIBSODIUM_LDFLAGS) \
54 $(NACL_LDFLAGS) \ 56 $(NACL_LDFLAGS) \
57 $(RT_LIBS) \
55 $(WINSOCK2_LIBS) 58 $(WINSOCK2_LIBS)
56 59
57libtoxcore_la_LIBADD = $(LIBSODIUM_LIBS) \ 60libtoxcore_la_LIBADD = $(LIBSODIUM_LIBS) \
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index f5ed14b1..28c8845a 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -38,6 +38,8 @@
38static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); 38static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status);
39static int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); 39static int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
40 40
41static IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber);
42
41// friend_not_valid determines if the friendnumber passed is valid in the Messenger object 43// friend_not_valid determines if the friendnumber passed is valid in the Messenger object
42static uint8_t friend_not_valid(Messenger *m, int32_t friendnumber) 44static uint8_t friend_not_valid(Messenger *m, int32_t friendnumber)
43{ 45{
@@ -194,6 +196,21 @@ void getaddress(Messenger *m, uint8_t *address)
194 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); 196 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum));
195} 197}
196 198
199/* callback for recv TCP relay nodes. */
200static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key)
201{
202 Messenger *m = object;
203
204 if (friend_not_valid(m, number))
205 return -1;
206
207 if (m->friendlist[number].crypt_connection_id != -1) {
208 return add_tcp_relay_peer(m->net_crypto, m->friendlist[number].crypt_connection_id, ip_port, public_key);
209 } else {
210 return add_tcp_relay(m->net_crypto, ip_port, public_key);
211 }
212}
213
197/* 214/*
198 * Add a friend. 215 * Add a friend.
199 * Set the data that will be sent along with friend request. 216 * Set the data that will be sent along with friend request.
@@ -213,9 +230,7 @@ void getaddress(Messenger *m, uint8_t *address)
213 */ 230 */
214int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) 231int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
215{ 232{
216 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES 233 if (length > MAX_FRIEND_REQUEST_DATA_SIZE)
217 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
218 + crypto_box_ZEROBYTES))
219 return FAERR_TOOLONG; 234 return FAERR_TOOLONG;
220 235
221 uint8_t client_id[crypto_box_PUBLICKEYBYTES]; 236 uint8_t client_id[crypto_box_PUBLICKEYBYTES];
@@ -278,6 +293,7 @@ int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t leng
278 m->friendlist[i].message_id = 0; 293 m->friendlist[i].message_id = 0;
279 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ 294 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
280 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); 295 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
296 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
281 297
282 if (m->numfriends == i) 298 if (m->numfriends == i)
283 ++m->numfriends; 299 ++m->numfriends;
@@ -323,6 +339,7 @@ int32_t m_addfriend_norequest(Messenger *m, uint8_t *client_id)
323 m->friendlist[i].is_typing = 0; 339 m->friendlist[i].is_typing = 0;
324 m->friendlist[i].message_id = 0; 340 m->friendlist[i].message_id = 0;
325 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ 341 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
342 recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i);
326 343
327 if (m->numfriends == i) 344 if (m->numfriends == i)
328 ++m->numfriends; 345 ++m->numfriends;
@@ -407,10 +424,10 @@ uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, uint8_t *message, uin
407 424
408uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length) 425uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
409{ 426{
410 if (length >= (MAX_DATA_SIZE - sizeof(theid))) 427 if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)))
411 return 0; 428 return 0;
412 429
413 uint8_t temp[MAX_DATA_SIZE]; 430 uint8_t temp[MAX_CRYPTO_DATA_SIZE];
414 theid = htonl(theid); 431 theid = htonl(theid);
415 memcpy(temp, &theid, sizeof(theid)); 432 memcpy(temp, &theid, sizeof(theid));
416 memcpy(temp + sizeof(theid), message, length); 433 memcpy(temp + sizeof(theid), message, length);
@@ -441,10 +458,10 @@ uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint3
441 458
442uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length) 459uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length)
443{ 460{
444 if (length >= (MAX_DATA_SIZE - sizeof(theid))) 461 if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)))
445 return 0; 462 return 0;
446 463
447 uint8_t temp[MAX_DATA_SIZE]; 464 uint8_t temp[MAX_CRYPTO_DATA_SIZE];
448 theid = htonl(theid); 465 theid = htonl(theid);
449 memcpy(temp, &theid, sizeof(theid)); 466 memcpy(temp, &theid, sizeof(theid));
450 memcpy(temp + sizeof(theid), action, length); 467 memcpy(temp + sizeof(theid), action, length);
@@ -690,7 +707,7 @@ static int send_user_istyping(Messenger *m, int32_t friendnumber, uint8_t is_typ
690 707
691static int send_ping(Messenger *m, int32_t friendnumber) 708static int send_ping(Messenger *m, int32_t friendnumber)
692{ 709{
693 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0); 710 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_ALIVE, 0, 0);
694 711
695 if (ret == 1) 712 if (ret == 1)
696 m->friendlist[friendnumber].ping_lastsent = unix_time(); 713 m->friendlist[friendnumber].ping_lastsent = unix_time();
@@ -841,7 +858,7 @@ int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id,
841 if (friend_not_valid(m, friendnumber)) 858 if (friend_not_valid(m, friendnumber))
842 return 0; 859 return 0;
843 860
844 if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE) 861 if (length >= MAX_CRYPTO_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
845 return 0; 862 return 0;
846 863
847 uint8_t packet[length + 1]; 864 uint8_t packet[length + 1];
@@ -850,7 +867,7 @@ int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id,
850 if (length != 0) 867 if (length != 0)
851 memcpy(packet + 1, data, length); 868 memcpy(packet + 1, data, length);
852 869
853 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); 870 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1) != -1;
854} 871}
855 872
856/**********GROUP CHATS************/ 873/**********GROUP CHATS************/
@@ -876,7 +893,7 @@ static uint8_t groupnumber_not_valid(Messenger *m, int groupnumber)
876/* returns valid ip port of connected friend on success 893/* returns valid ip port of connected friend on success
877 * returns zeroed out IP_Port on failure 894 * returns zeroed out IP_Port on failure
878 */ 895 */
879IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber) 896static IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber)
880{ 897{
881 IP_Port zero; 898 IP_Port zero;
882 memset(&zero, 0, sizeof(zero)); 899 memset(&zero, 0, sizeof(zero));
@@ -886,10 +903,15 @@ IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber)
886 903
887 int crypt_id = m->friendlist[friendnumber].crypt_connection_id; 904 int crypt_id = m->friendlist[friendnumber].crypt_connection_id;
888 905
889 if (is_cryptoconnected(m->net_crypto, crypt_id) != CRYPTO_CONN_ESTABLISHED) 906 uint8_t direct_connected;
907
908 if (crypto_connection_status(m->net_crypto, crypt_id, &direct_connected) != CRYPTO_CONN_ESTABLISHED)
890 return zero; 909 return zero;
891 910
892 return connection_ip(m->net_crypto->lossless_udp, m->net_crypto->crypto_connections[crypt_id].number); 911 if (direct_connected == 0)
912 return zero;
913
914 return m->net_crypto->crypto_connections[crypt_id].ip_port;
893} 915}
894 916
895/* returns the group number of the chat with public key group_public_key. 917/* returns the group number of the chat with public key group_public_key.
@@ -1396,7 +1418,7 @@ int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_
1396int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, 1418int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
1397 uint8_t *data, uint16_t length) 1419 uint8_t *data, uint16_t length)
1398{ 1420{
1399 if (length > MAX_DATA_SIZE - 3) 1421 if (length > MAX_CRYPTO_DATA_SIZE - 3)
1400 return -1; 1422 return -1;
1401 1423
1402 if (friend_not_valid(m, friendnumber)) 1424 if (friend_not_valid(m, friendnumber))
@@ -1413,7 +1435,7 @@ int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8
1413 if (send_receive > 1) 1435 if (send_receive > 1)
1414 return -1; 1436 return -1;
1415 1437
1416 uint8_t packet[MAX_DATA_SIZE]; 1438 uint8_t packet[MAX_CRYPTO_DATA_SIZE];
1417 packet[0] = send_receive; 1439 packet[0] = send_receive;
1418 packet[1] = filenumber; 1440 packet[1] = filenumber;
1419 packet[2] = message_id; 1441 packet[2] = message_id;
@@ -1483,7 +1505,7 @@ int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8
1483 */ 1505 */
1484int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) 1506int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length)
1485{ 1507{
1486 if (length > MAX_DATA_SIZE - 1) 1508 if (length > MAX_CRYPTO_DATA_SIZE - 1)
1487 return -1; 1509 return -1;
1488 1510
1489 if (friend_not_valid(m, friendnumber)) 1511 if (friend_not_valid(m, friendnumber))
@@ -1496,7 +1518,7 @@ int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *d
1496 if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE) 1518 if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE)
1497 return -1; 1519 return -1;
1498 1520
1499 uint8_t packet[MAX_DATA_SIZE]; 1521 uint8_t packet[MAX_CRYPTO_DATA_SIZE];
1500 packet[0] = filenumber; 1522 packet[0] = filenumber;
1501 memcpy(packet + 1, data, length); 1523 memcpy(packet + 1, data, length);
1502 1524
@@ -1739,6 +1761,30 @@ static void LANdiscovery(Messenger *m)
1739 } 1761 }
1740} 1762}
1741 1763
1764static int handle_status(void *object, int i, uint8_t status);
1765static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len);
1766
1767static int handle_new_connections(void *object, New_Connection *n_c)
1768{
1769 Messenger *m = object;
1770 int friend_id = getfriend_id(m, n_c->public_key);
1771
1772 if (friend_id != -1) {
1773 if (m->friendlist[friend_id].crypt_connection_id != -1)
1774 return -1;
1775
1776 int id = accept_crypto_connection(m->net_crypto, n_c);
1777 connection_status_handler(m->net_crypto, id, &handle_status, m, friend_id);
1778 connection_data_handler(m->net_crypto, id, &handle_packet, m, friend_id);
1779 m->friendlist[friend_id].crypt_connection_id = id;
1780 set_friend_status(m, friend_id, FRIEND_CONFIRMED);
1781 return 0;
1782 }
1783
1784 return -1;
1785}
1786
1787
1742/* Run this at startup. */ 1788/* Run this at startup. */
1743Messenger *new_messenger(uint8_t ipv6enabled) 1789Messenger *new_messenger(uint8_t ipv6enabled)
1744{ 1790{
@@ -1756,26 +1802,28 @@ Messenger *new_messenger(uint8_t ipv6enabled)
1756 return NULL; 1802 return NULL;
1757 } 1803 }
1758 1804
1759 m->net_crypto = new_net_crypto(m->net); 1805 m->dht = new_DHT(m->net);
1760 1806
1761 if (m->net_crypto == NULL) { 1807 if (m->dht == NULL) {
1762 kill_networking(m->net); 1808 kill_networking(m->net);
1763 free(m); 1809 free(m);
1764 return NULL; 1810 return NULL;
1765 } 1811 }
1766 1812
1767 m->dht = new_DHT(m->net_crypto); 1813 m->net_crypto = new_net_crypto(m->dht);
1768 1814
1769 if (m->dht == NULL) { 1815 if (m->net_crypto == NULL) {
1770 kill_net_crypto(m->net_crypto);
1771 kill_networking(m->net); 1816 kill_networking(m->net);
1817 kill_DHT(m->dht);
1772 free(m); 1818 free(m);
1773 return NULL; 1819 return NULL;
1774 } 1820 }
1775 1821
1822 new_connection_handler(m->net_crypto, &handle_new_connections, m);
1823
1776 m->onion = new_onion(m->dht); 1824 m->onion = new_onion(m->dht);
1777 m->onion_a = new_onion_announce(m->dht); 1825 m->onion_a = new_onion_announce(m->dht);
1778 m->onion_c = new_onion_client(m->dht); 1826 m->onion_c = new_onion_client(m->net_crypto);
1779 1827
1780 if (!(m->onion && m->onion_a && m->onion_c)) { 1828 if (!(m->onion && m->onion_a && m->onion_c)) {
1781 kill_onion(m->onion); 1829 kill_onion(m->onion);
@@ -1814,9 +1862,15 @@ void kill_messenger(Messenger *m)
1814 kill_onion(m->onion); 1862 kill_onion(m->onion);
1815 kill_onion_announce(m->onion_a); 1863 kill_onion_announce(m->onion_a);
1816 kill_onion_client(m->onion_c); 1864 kill_onion_client(m->onion_c);
1817 kill_DHT(m->dht);
1818 kill_net_crypto(m->net_crypto); 1865 kill_net_crypto(m->net_crypto);
1866 kill_DHT(m->dht);
1819 kill_networking(m->net); 1867 kill_networking(m->net);
1868
1869 for (i = 0; i < m->numfriends; ++i) {
1870 if (m->friendlist[i].statusmessage)
1871 free(m->friendlist[i].statusmessage);
1872 }
1873
1820 free(m->friendlist); 1874 free(m->friendlist);
1821 free(m); 1875 free(m);
1822} 1876}
@@ -1839,379 +1893,395 @@ static void check_friend_request_timed_out(Messenger *m, uint32_t i, uint64_t t)
1839 } 1893 }
1840} 1894}
1841 1895
1842/* TODO: Make this function not suck. */ 1896static int handle_status(void *object, int i, uint8_t status)
1843void do_friends(Messenger *m)
1844{ 1897{
1845 uint32_t i;
1846 int len;
1847 uint8_t temp[MAX_DATA_SIZE];
1848 uint64_t temp_time = unix_time(); 1898 uint64_t temp_time = unix_time();
1899 Messenger *m = object;
1849 1900
1850 for (i = 0; i < m->numfriends; ++i) { 1901 if (status) { /* Went online. */
1851 if (m->friendlist[i].status == FRIEND_ADDED) { 1902 set_friend_status(m, i, FRIEND_ONLINE);
1852 int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, 1903 m->friendlist[i].name_sent = 0;
1853 m->friendlist[i].info, 1904 m->friendlist[i].userstatus_sent = 0;
1854 m->friendlist[i].info_size); 1905 m->friendlist[i].statusmessage_sent = 0;
1906 m->friendlist[i].ping_lastrecv = temp_time;
1907 } else { /* Went offline. */
1908 m->friendlist[i].crypt_connection_id = -1;
1855 1909
1856 if (fr >= 0) { 1910 if (m->friendlist[i].status == FRIEND_ONLINE) {
1857 set_friend_status(m, i, FRIEND_REQUESTED); 1911 set_friend_status(m, i, FRIEND_CONFIRMED);
1858 m->friendlist[i].friendrequest_lastsent = temp_time;
1859 }
1860 } 1912 }
1913 }
1861 1914
1862 if (m->friendlist[i].status == FRIEND_REQUESTED 1915 return 0;
1863 || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online. */ 1916}
1864 if (m->friendlist[i].status == FRIEND_REQUESTED) {
1865 /* If we didn't connect to friend after successfully sending him a friend request the request is deemed
1866 * unsuccessful so we set the status back to FRIEND_ADDED and try again.
1867 */
1868 check_friend_request_timed_out(m, i, temp_time);
1869 }
1870 1917
1871 IP_Port friendip; 1918static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
1872 int friendok = onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip); 1919{
1920 if (len == 0)
1921 return -1;
1873 1922
1874 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { 1923 Messenger *m = object;
1875 case CRYPTO_CONN_NO_CONNECTION: 1924 uint64_t temp_time = unix_time();
1876 if (friendok == 1) 1925 uint8_t packet_id = temp[0];
1877 m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); 1926 uint8_t *data = temp + 1;
1927 uint32_t data_length = len - 1;
1878 1928
1879 break; 1929 if (m->friendlist[i].status != FRIEND_ONLINE)
1930 return -1;
1880 1931
1881 case CRYPTO_CONN_ESTABLISHED: /* Connection is established. */ 1932 switch (packet_id) {
1882 set_friend_status(m, i, FRIEND_ONLINE); 1933 case PACKET_ID_ALIVE: {
1883 m->friendlist[i].name_sent = 0; 1934 m->friendlist[i].ping_lastrecv = temp_time;
1884 m->friendlist[i].userstatus_sent = 0; 1935 break;
1885 m->friendlist[i].statusmessage_sent = 0; 1936 }
1886 m->friendlist[i].ping_lastrecv = temp_time;
1887 break;
1888 1937
1889 case CRYPTO_CONN_TIMED_OUT: 1938 case PACKET_ID_NICKNAME: {
1890 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); 1939 if (data_length > MAX_NAME_LENGTH || data_length == 0)
1891 m->friendlist[i].crypt_connection_id = -1; 1940 break;
1892 break;
1893 1941
1894 default: 1942 /* Make sure the NULL terminator is present. */
1895 break; 1943 uint8_t data_terminated[data_length + 1];
1896 } 1944 memcpy(data_terminated, data, data_length);
1945 data_terminated[data_length] = 0;
1946
1947 /* inform of namechange before we overwrite the old name */
1948 if (m->friend_namechange)
1949 m->friend_namechange(m, i, data_terminated, data_length, m->friend_namechange_userdata);
1950
1951 memcpy(m->friendlist[i].name, data_terminated, data_length);
1952 m->friendlist[i].name_length = data_length;
1953
1954 break;
1897 } 1955 }
1898 1956
1899 while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */ 1957 case PACKET_ID_STATUSMESSAGE: {
1900 if (m->friendlist[i].name_sent == 0) { 1958 if (data_length == 0 || data_length > MAX_STATUSMESSAGE_LENGTH)
1901 if (m_sendname(m, i, m->name, m->name_length)) 1959 break;
1902 m->friendlist[i].name_sent = 1;
1903 }
1904 1960
1905 if (m->friendlist[i].statusmessage_sent == 0) { 1961 /* Make sure the NULL terminator is present. */
1906 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) 1962 uint8_t data_terminated[data_length + 1];
1907 m->friendlist[i].statusmessage_sent = 1; 1963 memcpy(data_terminated, data, data_length);
1908 } 1964 data_terminated[data_length] = 0;
1909 1965
1910 if (m->friendlist[i].userstatus_sent == 0) { 1966 if (m->friend_statusmessagechange)
1911 if (send_userstatus(m, i, m->userstatus)) 1967 m->friend_statusmessagechange(m, i, data_terminated, data_length,
1912 m->friendlist[i].userstatus_sent = 1; 1968 m->friend_statuschange_userdata);
1913 }
1914 1969
1915 if (m->friendlist[i].user_istyping_sent == 0) { 1970 set_friend_statusmessage(m, i, data_terminated, data_length);
1916 if (send_user_istyping(m, i, m->friendlist[i].user_istyping)) 1971 break;
1917 m->friendlist[i].user_istyping_sent = 1; 1972 }
1918 }
1919 1973
1920 if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) { 1974 case PACKET_ID_USERSTATUS: {
1921 send_ping(m, i); 1975 if (data_length != 1)
1922 } 1976 break;
1923 1977
1924 len = read_cryptpacket(m->net_crypto, m->friendlist[i].crypt_connection_id, temp); 1978 USERSTATUS status = data[0];
1925 1979
1926 if (len > 0) { 1980 if (status >= USERSTATUS_INVALID)
1927 uint8_t packet_id = temp[0]; 1981 break;
1928 uint8_t *data = temp + 1;
1929 uint32_t data_length = len - 1;
1930 1982
1931 switch (packet_id) { 1983 if (m->friend_userstatuschange)
1932 case PACKET_ID_PING: { 1984 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
1933 m->friendlist[i].ping_lastrecv = temp_time;
1934 break;
1935 }
1936 1985
1937 case PACKET_ID_NICKNAME: { 1986 set_friend_userstatus(m, i, status);
1938 if (data_length > MAX_NAME_LENGTH || data_length == 0) 1987 break;
1939 break; 1988 }
1940 1989
1941 /* Make sure the NULL terminator is present. */ 1990 case PACKET_ID_TYPING: {
1942 uint8_t data_terminated[data_length + 1]; 1991 if (data_length != 1)
1943 memcpy(data_terminated, data, data_length); 1992 break;
1944 data_terminated[data_length] = 0;
1945 1993
1946 /* inform of namechange before we overwrite the old name */ 1994 uint8_t typing = data[0];
1947 if (m->friend_namechange)
1948 m->friend_namechange(m, i, data_terminated, data_length, m->friend_namechange_userdata);
1949 1995
1950 memcpy(m->friendlist[i].name, data_terminated, data_length); 1996 set_friend_typing(m, i, typing);
1951 m->friendlist[i].name_length = data_length;
1952 1997
1953 break; 1998 if (m->friend_typingchange)
1954 } 1999 m->friend_typingchange(m, i, typing, m->friend_typingchange_userdata);
1955 2000
1956 case PACKET_ID_STATUSMESSAGE: { 2001 break;
1957 if (data_length == 0 || data_length > MAX_STATUSMESSAGE_LENGTH) 2002 }
1958 break;
1959 2003
1960 /* Make sure the NULL terminator is present. */ 2004 case PACKET_ID_MESSAGE: {
1961 uint8_t data_terminated[data_length + 1]; 2005 uint8_t *message_id = data;
1962 memcpy(data_terminated, data, data_length); 2006 uint8_t message_id_length = 4;
1963 data_terminated[data_length] = 0;
1964 2007
1965 if (m->friend_statusmessagechange) 2008 if (data_length <= message_id_length)
1966 m->friend_statusmessagechange(m, i, data_terminated, data_length, 2009 break;
1967 m->friend_statuschange_userdata);
1968 2010
1969 set_friend_statusmessage(m, i, data_terminated, data_length); 2011 uint8_t *message = data + message_id_length;
1970 break; 2012 uint16_t message_length = data_length - message_id_length;
1971 }
1972 2013
1973 case PACKET_ID_USERSTATUS: { 2014 /* Make sure the NULL terminator is present. */
1974 if (data_length != 1) 2015 uint8_t message_terminated[message_length + 1];
1975 break; 2016 memcpy(message_terminated, message, message_length);
2017 message_terminated[message_length] = 0;
1976 2018
1977 USERSTATUS status = data[0]; 2019 if (m->friendlist[i].receives_read_receipts) {
2020 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
2021 }
1978 2022
1979 if (status >= USERSTATUS_INVALID) 2023 if (m->friend_message)
1980 break; 2024 (*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata);
1981 2025
1982 if (m->friend_userstatuschange) 2026 break;
1983 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata); 2027 }
1984 2028
1985 set_friend_userstatus(m, i, status); 2029 case PACKET_ID_ACTION: {
1986 break; 2030 uint8_t *message_id = data;
1987 } 2031 uint8_t message_id_length = 4;
1988 2032
1989 case PACKET_ID_TYPING: { 2033 if (data_length <= message_id_length)
1990 if (data_length != 1) 2034 break;
1991 break;
1992 2035
1993 uint8_t typing = data[0]; 2036 uint8_t *action = data + message_id_length;
2037 uint16_t action_length = data_length - message_id_length;
1994 2038
1995 set_friend_typing(m, i, typing); 2039 /* Make sure the NULL terminator is present. */
2040 uint8_t action_terminated[action_length + 1];
2041 memcpy(action_terminated, action, action_length);
2042 action_terminated[action_length] = 0;
1996 2043
1997 if (m->friend_typingchange) 2044 if (m->friendlist[i].receives_read_receipts) {
1998 m->friend_typingchange(m, i, typing, m->friend_typingchange_userdata); 2045 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
2046 }
1999 2047
2000 break; 2048 if (m->friend_action)
2001 } 2049 (*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata);
2002 2050
2003 case PACKET_ID_MESSAGE: { 2051 break;
2004 uint8_t *message_id = data; 2052 }
2005 uint8_t message_id_length = 4;
2006 2053
2007 if (data_length <= message_id_length) 2054 case PACKET_ID_RECEIPT: {
2008 break; 2055 uint32_t msgid;
2009 2056
2010 uint8_t *message = data + message_id_length; 2057 if (data_length < sizeof(msgid))
2011 uint16_t message_length = data_length - message_id_length; 2058 break;
2012 2059
2013 /* Make sure the NULL terminator is present. */ 2060 memcpy(&msgid, data, sizeof(msgid));
2014 uint8_t message_terminated[message_length + 1]; 2061 msgid = ntohl(msgid);
2015 memcpy(message_terminated, message, message_length);
2016 message_terminated[message_length] = 0;
2017 2062
2018 if (m->friendlist[i].receives_read_receipts) { 2063 if (m->read_receipt)
2019 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); 2064 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
2020 }
2021 2065
2022 if (m->friend_message) 2066 break;
2023 (*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata); 2067 }
2024 2068
2025 break; 2069 case PACKET_ID_INVITE_GROUPCHAT: {
2026 } 2070 if (data_length != crypto_box_PUBLICKEYBYTES)
2071 break;
2027 2072
2028 case PACKET_ID_ACTION: { 2073 if (m->group_invite)
2029 uint8_t *message_id = data; 2074 (*m->group_invite)(m, i, data, m->group_invite_userdata);
2030 uint8_t message_id_length = 4;
2031 2075
2032 if (data_length <= message_id_length) 2076 break;
2033 break; 2077 }
2034 2078
2035 uint8_t *action = data + message_id_length; 2079 case PACKET_ID_JOIN_GROUPCHAT: {
2036 uint16_t action_length = data_length - message_id_length; 2080 if (data_length != crypto_box_PUBLICKEYBYTES * 2)
2081 break;
2037 2082
2038 /* Make sure the NULL terminator is present. */ 2083 int groupnum = group_num(m, data);
2039 uint8_t action_terminated[action_length + 1];
2040 memcpy(action_terminated, action, action_length);
2041 action_terminated[action_length] = 0;
2042 2084
2043 if (m->friendlist[i].receives_read_receipts) { 2085 if (groupnum == -1)
2044 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); 2086 break;
2045 }
2046 2087
2047 if (m->friend_action) 2088 if (!group_invited(m, i, groupnum))
2048 (*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata); 2089 break;
2049 2090
2050 break; 2091 group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES);
2051 } 2092 /* This is just there to speedup joining. */
2093 chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES);
2094 break;
2095 }
2052 2096
2053 case PACKET_ID_RECEIPT: { 2097 case PACKET_ID_FILE_SENDREQUEST: {
2054 uint32_t msgid; 2098 if (data_length < 1 + sizeof(uint64_t) + 1)
2099 break;
2055 2100
2056 if (data_length < sizeof(msgid)) 2101 uint8_t filenumber = data[0];
2057 break; 2102 uint64_t filesize;
2103 net_to_host(data + 1, sizeof(filesize));
2104 memcpy(&filesize, data + 1, sizeof(filesize));
2105 m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED;
2106 m->friendlist[i].file_receiving[filenumber].size = filesize;
2107 m->friendlist[i].file_receiving[filenumber].transferred = 0;
2058 2108
2059 memcpy(&msgid, data, sizeof(msgid)); 2109 /* Force NULL terminate file name. */
2060 msgid = ntohl(msgid); 2110 uint8_t filename_terminated[data_length - 1 - sizeof(uint64_t) + 1];
2111 memcpy(filename_terminated, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t));
2112 filename_terminated[data_length - 1 - sizeof(uint64_t)] = 0;
2061 2113
2062 if (m->read_receipt) 2114 if (m->file_sendrequest)
2063 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata); 2115 (*m->file_sendrequest)(m, i, filenumber, filesize, filename_terminated, data_length - 1 - sizeof(uint64_t),
2116 m->file_sendrequest_userdata);
2064 2117
2065 break; 2118 break;
2066 } 2119 }
2067 2120
2068 case PACKET_ID_INVITE_GROUPCHAT: { 2121 case PACKET_ID_FILE_CONTROL: {
2069 if (data_length != crypto_box_PUBLICKEYBYTES) 2122 if (data_length < 3)
2070 break; 2123 break;
2071 2124
2072 if (m->group_invite) 2125 uint8_t send_receive = data[0];
2073 (*m->group_invite)(m, i, data, m->group_invite_userdata); 2126 uint8_t filenumber = data[1];
2127 uint8_t control_type = data[2];
2074 2128
2075 break; 2129 if (handle_filecontrol(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3) == -1)
2076 } 2130 break;
2077 2131
2078 case PACKET_ID_JOIN_GROUPCHAT: { 2132 if (m->file_filecontrol)
2079 if (data_length != crypto_box_PUBLICKEYBYTES * 2) 2133 (*m->file_filecontrol)(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3,
2080 break; 2134 m->file_filecontrol_userdata);
2081 2135
2082 int groupnum = group_num(m, data); 2136 break;
2137 }
2083 2138
2084 if (groupnum == -1) 2139 case PACKET_ID_FILE_DATA: {
2085 break; 2140 if (data_length < 2)
2141 break;
2086 2142
2087 if (!group_invited(m, i, groupnum)) 2143 uint8_t filenumber = data[0];
2088 break;
2089 2144
2090 group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); 2145 if (m->friendlist[i].file_receiving[filenumber].status == FILESTATUS_NONE)
2091 /* This is just there to speedup joining. */ 2146 break;
2092 chat_bootstrap(m->chats[groupnum], get_friend_ipport(m, i), data + crypto_box_PUBLICKEYBYTES);
2093 break;
2094 }
2095 2147
2096 case PACKET_ID_FILE_SENDREQUEST: { 2148 m->friendlist[i].file_receiving[filenumber].transferred += (data_length - 1);
2097 if (data_length < 1 + sizeof(uint64_t) + 1)
2098 break;
2099 2149
2100 uint8_t filenumber = data[0]; 2150 if (m->file_filedata)
2101 uint64_t filesize; 2151 (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata);
2102 net_to_host(data + 1, sizeof(filesize));
2103 memcpy(&filesize, data + 1, sizeof(filesize));
2104 m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED;
2105 m->friendlist[i].file_receiving[filenumber].size = filesize;
2106 m->friendlist[i].file_receiving[filenumber].transferred = 0;
2107 2152
2108 /* Force NULL terminate file name. */ 2153 break;
2109 uint8_t filename_terminated[data_length - 1 - sizeof(uint64_t) + 1]; 2154 }
2110 memcpy(filename_terminated, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t));
2111 filename_terminated[data_length - 1 - sizeof(uint64_t)] = 0;
2112 2155
2113 if (m->file_sendrequest) 2156 case PACKET_ID_MSI: {
2114 (*m->file_sendrequest)(m, i, filenumber, filesize, filename_terminated, data_length - 1 - sizeof(uint64_t), 2157 if (data_length == 0)
2115 m->file_sendrequest_userdata); 2158 break;
2116 2159
2117 break; 2160 if (m->msi_packet)
2118 } 2161 (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata);
2162 }
2119 2163
2120 case PACKET_ID_FILE_CONTROL: { 2164 default: {
2121 if (data_length < 3) 2165 break;
2122 break; 2166 }
2167 }
2123 2168
2124 uint8_t send_receive = data[0]; 2169 return 0;
2125 uint8_t filenumber = data[1]; 2170}
2126 uint8_t control_type = data[2];
2127 2171
2128 if (handle_filecontrol(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3) == -1) 2172static int friend_new_connection(Messenger *m, int32_t friendnumber, uint8_t *real_public_key)
2129 break; 2173{
2174 if (friend_not_valid(m, friendnumber))
2175 return -1;
2130 2176
2131 if (m->file_filecontrol) 2177 if (m->friendlist[friendnumber].crypt_connection_id != -1) {
2132 (*m->file_filecontrol)(m, i, send_receive, filenumber, control_type, data + 3, data_length - 3, 2178 return -1;
2133 m->file_filecontrol_userdata); 2179 }
2134 2180
2135 break; 2181 int id = new_crypto_connection(m->net_crypto, real_public_key);
2136 }
2137 2182
2138 case PACKET_ID_FILE_DATA: { 2183 if (id == -1)
2139 if (data_length < 2) 2184 return -1;
2140 break;
2141 2185
2142 uint8_t filenumber = data[0]; 2186 m->friendlist[friendnumber].crypt_connection_id = id;
2187 connection_status_handler(m->net_crypto, id, &handle_status, m, friendnumber);
2188 connection_data_handler(m->net_crypto, id, &handle_packet, m, friendnumber);
2189 return 0;
2143 2190
2144 if (m->friendlist[i].file_receiving[filenumber].status == FILESTATUS_NONE) 2191}
2145 break;
2146 2192
2147 m->friendlist[i].file_receiving[filenumber].transferred += (data_length - 1); 2193/* TODO: Make this function not suck. */
2194void do_friends(Messenger *m)
2195{
2196 uint32_t i;
2197 uint64_t temp_time = unix_time();
2148 2198
2149 if (m->file_filedata) 2199 for (i = 0; i < m->numfriends; ++i) {
2150 (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata); 2200 if (m->friendlist[i].status == FRIEND_ADDED) {
2201 int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam,
2202 m->friendlist[i].info,
2203 m->friendlist[i].info_size);
2151 2204
2152 break; 2205 if (fr >= 0) {
2153 } 2206 set_friend_status(m, i, FRIEND_REQUESTED);
2207 m->friendlist[i].friendrequest_lastsent = temp_time;
2208 }
2209 }
2210
2211 if (m->friendlist[i].status == FRIEND_REQUESTED
2212 || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online. */
2213 if (m->friendlist[i].status == FRIEND_REQUESTED) {
2214 /* If we didn't connect to friend after successfully sending him a friend request the request is deemed
2215 * unsuccessful so we set the status back to FRIEND_ADDED and try again.
2216 */
2217 check_friend_request_timed_out(m, i, temp_time);
2218 }
2154 2219
2155 case PACKET_ID_MSI: { 2220 friend_new_connection(m, i, m->friendlist[i].client_id);
2156 if (data_length == 0) 2221 }
2157 break;
2158 2222
2159 if (m->msi_packet) 2223 if (m->friendlist[i].crypt_connection_id != -1) {
2160 (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata); 2224 uint8_t dht_public_key1[crypto_box_PUBLICKEYBYTES];
2161 } 2225 uint64_t timestamp1 = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key1);
2226 uint8_t dht_public_key2[crypto_box_PUBLICKEYBYTES];
2227 uint64_t timestamp2 = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key2);
2162 2228
2163 default: { 2229 if (timestamp1 > timestamp2) {
2164 break; 2230 set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key1, timestamp1);
2165 } 2231 } else if (timestamp1 < timestamp2) {
2166 } 2232 onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key2, timestamp2);
2167 } else { 2233 }
2168 if (is_cryptoconnected(m->net_crypto,
2169 m->friendlist[i].crypt_connection_id) == CRYPTO_CONN_TIMED_OUT) { /* If the connection timed out, kill it. */
2170 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id);
2171 m->friendlist[i].crypt_connection_id = -1;
2172 set_friend_status(m, i, FRIEND_CONFIRMED);
2173 }
2174 2234
2175 if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { 2235 uint8_t direct_connected;
2176 /* If we stopped recieving ping packets, kill it. */ 2236 unsigned int status = crypto_connection_status(m->net_crypto, m->friendlist[i].crypt_connection_id, &direct_connected);
2177 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id);
2178 m->friendlist[i].crypt_connection_id = -1;
2179 set_friend_status(m, i, FRIEND_CONFIRMED);
2180 }
2181 2237
2182 break; 2238 if (direct_connected == 0 || status == CRYPTO_CONN_COOKIE_REQUESTING) {
2239 IP_Port friendip;
2240
2241 if (onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip) == 1) {
2242 set_direct_ip_port(m->net_crypto, m->friendlist[i].crypt_connection_id, friendip);
2243 }
2183 } 2244 }
2184 } 2245 }
2185 }
2186}
2187 2246
2188void do_inbound(Messenger *m) 2247 if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */
2189{ 2248 if (m->friendlist[i].name_sent == 0) {
2190 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 2249 if (m_sendname(m, i, m->name, m->name_length))
2191 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 2250 m->friendlist[i].name_sent = 1;
2192 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 2251 }
2193 int inconnection = crypto_inbound(m->net_crypto, public_key, secret_nonce, session_key);
2194 2252
2195 if (inconnection != -1) { 2253 if (m->friendlist[i].statusmessage_sent == 0) {
2196 int friend_id = getfriend_id(m, public_key); 2254 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length))
2255 m->friendlist[i].statusmessage_sent = 1;
2256 }
2197 2257
2198 if (friend_id != -1) { 2258 if (m->friendlist[i].userstatus_sent == 0) {
2199 if (m_get_friend_connectionstatus(m, friend_id) == 1) { 2259 if (send_userstatus(m, i, m->userstatus))
2200 kill_connection(m->net_crypto->lossless_udp, inconnection); 2260 m->friendlist[i].userstatus_sent = 1;
2201 return; 2261 }
2262
2263 if (m->friendlist[i].user_istyping_sent == 0) {
2264 if (send_user_istyping(m, i, m->friendlist[i].user_istyping))
2265 m->friendlist[i].user_istyping_sent = 1;
2202 } 2266 }
2203 2267
2204 crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id); 2268 if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) {
2205 m->friendlist[friend_id].crypt_connection_id = 2269 send_ping(m, i);
2206 accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key); 2270 }
2207 2271
2208 set_friend_status(m, friend_id, FRIEND_CONFIRMED); 2272 if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) {
2209 } else { 2273 /* If we stopped receiving ping packets, kill it. */
2210 kill_connection(m->net_crypto->lossless_udp, inconnection); 2274 crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id);
2275 m->friendlist[i].crypt_connection_id = -1;
2276 set_friend_status(m, i, FRIEND_CONFIRMED);
2277 }
2211 } 2278 }
2212 } 2279 }
2213} 2280}
2214 2281
2282
2283
2284
2215#ifdef LOGGING 2285#ifdef LOGGING
2216#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL 2286#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL
2217static time_t lastdump = 0; 2287static time_t lastdump = 0;
@@ -2239,7 +2309,6 @@ void do_messenger(Messenger *m)
2239 do_net_crypto(m->net_crypto); 2309 do_net_crypto(m->net_crypto);
2240 do_onion_client(m->onion_c); 2310 do_onion_client(m->onion_c);
2241 do_friends(m); 2311 do_friends(m);
2242 do_inbound(m);
2243 do_allgroupchats(m); 2312 do_allgroupchats(m);
2244 LANdiscovery(m); 2313 LANdiscovery(m);
2245 2314
@@ -2369,7 +2438,9 @@ size_t wait_data_size()
2369 2438
2370int wait_prepare_messenger(Messenger *m, uint8_t *data) 2439int wait_prepare_messenger(Messenger *m, uint8_t *data)
2371{ 2440{
2372 return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data); 2441 //TODO
2442 //return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data);
2443 return networking_wait_prepare(m->net, 1024, data);
2373} 2444}
2374 2445
2375int wait_execute_messenger(uint8_t *data, long seconds, long microseconds) 2446int wait_execute_messenger(uint8_t *data, long seconds, long microseconds)
@@ -2394,11 +2465,14 @@ int wait_cleanup_messenger(Messenger *m, uint8_t *data)
2394#define MESSENGER_STATE_TYPE_NAME 4 2465#define MESSENGER_STATE_TYPE_NAME 4
2395#define MESSENGER_STATE_TYPE_STATUSMESSAGE 5 2466#define MESSENGER_STATE_TYPE_STATUSMESSAGE 5
2396#define MESSENGER_STATE_TYPE_STATUS 6 2467#define MESSENGER_STATE_TYPE_STATUS 6
2468#define MESSENGER_STATE_TYPE_TCP_RELAY 10
2397 2469
2470#define SAVED_FRIEND_REQUEST_SIZE 1024
2471#define NUM_SAVED_TCP_RELAYS 8
2398struct SAVED_FRIEND { 2472struct SAVED_FRIEND {
2399 uint8_t status; 2473 uint8_t status;
2400 uint8_t client_id[CLIENT_ID_SIZE]; 2474 uint8_t client_id[CLIENT_ID_SIZE];
2401 uint8_t info[MAX_DATA_SIZE]; // the data that is sent during the friend requests we do. 2475 uint8_t info[SAVED_FRIEND_REQUEST_SIZE]; // the data that is sent during the friend requests we do.
2402 uint16_t info_size; // Length of the info. 2476 uint16_t info_size; // Length of the info.
2403 uint8_t name[MAX_NAME_LENGTH]; 2477 uint8_t name[MAX_NAME_LENGTH];
2404 uint16_t name_length; 2478 uint16_t name_length;
@@ -2414,7 +2488,7 @@ struct SAVED_FRIEND {
2414struct SAVED_FRIEND_OLD { 2488struct SAVED_FRIEND_OLD {
2415 uint8_t status; 2489 uint8_t status;
2416 uint8_t client_id[CLIENT_ID_SIZE]; 2490 uint8_t client_id[CLIENT_ID_SIZE];
2417 uint8_t info[MAX_DATA_SIZE]; 2491 uint8_t info[1024];
2418 uint16_t info_size; 2492 uint16_t info_size;
2419 uint8_t name[MAX_NAME_LENGTH]; 2493 uint8_t name[MAX_NAME_LENGTH];
2420 uint16_t name_length; 2494 uint16_t name_length;
@@ -2442,7 +2516,12 @@ static uint32_t friends_list_save(Messenger *m, uint8_t *data)
2442 memcpy(temp.client_id, m->friendlist[i].client_id, CLIENT_ID_SIZE); 2516 memcpy(temp.client_id, m->friendlist[i].client_id, CLIENT_ID_SIZE);
2443 2517
2444 if (temp.status < 3) { 2518 if (temp.status < 3) {
2445 memcpy(temp.info, m->friendlist[i].info, m->friendlist[i].info_size); 2519 if (m->friendlist[i].info_size > SAVED_FRIEND_REQUEST_SIZE) {
2520 memcpy(temp.info, m->friendlist[i].info, SAVED_FRIEND_REQUEST_SIZE);
2521 } else {
2522 memcpy(temp.info, m->friendlist[i].info, m->friendlist[i].info_size);
2523 }
2524
2446 temp.info_size = htons(m->friendlist[i].info_size); 2525 temp.info_size = htons(m->friendlist[i].info_size);
2447 temp.friendrequest_nospam = m->friendlist[i].friendrequest_nospam; 2526 temp.friendrequest_nospam = m->friendlist[i].friendrequest_nospam;
2448 } else { 2527 } else {
@@ -2524,6 +2603,7 @@ uint32_t messenger_size(Messenger *m)
2524 + sizesubhead + m->name_length // Own nickname. 2603 + sizesubhead + m->name_length // Own nickname.
2525 + sizesubhead + m->statusmessage_length // status message 2604 + sizesubhead + m->statusmessage_length // status message
2526 + sizesubhead + 1 // status 2605 + sizesubhead + 1 // status
2606 + sizesubhead + NUM_SAVED_TCP_RELAYS * sizeof(Node_format) //TCP relays
2527 ; 2607 ;
2528} 2608}
2529 2609
@@ -2588,74 +2668,15 @@ void messenger_save(Messenger *m, uint8_t *data)
2588 data = z_state_save_subheader(data, len, type); 2668 data = z_state_save_subheader(data, len, type);
2589 *data = m->userstatus; 2669 *data = m->userstatus;
2590 data += len; 2670 data += len;
2591}
2592
2593static int messenger_load_state_callback_old(void *outer, uint8_t *data, uint32_t length, uint16_t type)
2594{
2595 Messenger *m = outer;
2596
2597 switch (type) {
2598 case MESSENGER_STATE_TYPE_NOSPAMKEYS:
2599 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) {
2600 set_nospam(&(m->fr), *(uint32_t *)data);
2601 load_keys(m->net_crypto, &data[sizeof(uint32_t)]);
2602#ifdef ENABLE_ASSOC_DHT
2603
2604 if (m->dht->assoc)
2605 Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key);
2606 2671
2607#endif 2672 Node_format relays[NUM_SAVED_TCP_RELAYS];
2608 } else 2673 len = sizeof(relays);
2609 return -1; /* critical */ 2674 type = MESSENGER_STATE_TYPE_TCP_RELAY;
2610 2675 data = z_state_save_subheader(data, len, type);
2611 break; 2676 memset(relays, 0, len);
2612 2677 copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS);
2613 case MESSENGER_STATE_TYPE_DHT: 2678 memcpy(data, relays, len);
2614 DHT_load(m->dht, data, length); 2679 data += len;
2615 break;
2616
2617 case MESSENGER_STATE_TYPE_FRIENDS:
2618 if (!(length % sizeof(Friend))) {
2619 uint16_t num = length / sizeof(Friend);
2620 Friend *friends = (Friend *)data;
2621 uint32_t i;
2622
2623 for (i = 0; i < num; ++i) {
2624 if (friends[i].status >= 3) {
2625 int fnum = m_addfriend_norequest(m, friends[i].client_id);
2626 setfriendname(m, fnum, friends[i].name, friends[i].name_length);
2627 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
2628 } else if (friends[i].status != 0) {
2629 /* TODO: This is not a good way to do this. */
2630 uint8_t address[FRIEND_ADDRESS_SIZE];
2631 id_copy(address, friends[i].client_id);
2632 memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t));
2633 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
2634 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
2635 m_addfriend(m, address, friends[i].info, friends[i].info_size);
2636 }
2637 }
2638 }
2639
2640 break;
2641
2642 case MESSENGER_STATE_TYPE_NAME:
2643 if ((length > 0) && (length < MAX_NAME_LENGTH)) {
2644 setname(m, data, length);
2645 }
2646
2647 break;
2648
2649#ifdef DEBUG
2650
2651 default:
2652 fprintf(stderr, "Load state: contains unrecognized part (len %u, type %u)\n",
2653 length, type);
2654 break;
2655#endif
2656 }
2657
2658 return 0;
2659} 2680}
2660 2681
2661static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t length, uint16_t type) 2682static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t length, uint16_t type)
@@ -2706,6 +2727,22 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
2706 } 2727 }
2707 2728
2708 break; 2729 break;
2730
2731 case MESSENGER_STATE_TYPE_TCP_RELAY: {
2732 Node_format relays[NUM_SAVED_TCP_RELAYS];
2733
2734 if (length != sizeof(relays)) {
2735 return -1;
2736 }
2737
2738 memcpy(relays, data, length);
2739 uint32_t i;
2740
2741 for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) {
2742 add_tcp_relay(m->net_crypto, relays[i].ip_port, relays[i].client_id);
2743 }
2744 }
2745 break;
2709#ifdef DEBUG 2746#ifdef DEBUG
2710 2747
2711 default: 2748 default:
@@ -2721,93 +2758,21 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
2721/* Load the messenger from data of size length. */ 2758/* Load the messenger from data of size length. */
2722int messenger_load(Messenger *m, uint8_t *data, uint32_t length) 2759int messenger_load(Messenger *m, uint8_t *data, uint32_t length)
2723{ 2760{
2724 uint32_t cookie_len = 2 * sizeof(uint32_t); 2761 uint32_t data32[2];
2762 uint32_t cookie_len = sizeof(data32);
2725 2763
2726 if (length < cookie_len) 2764 if (length < cookie_len)
2727 return -1; 2765 return -1;
2728 2766
2729 uint32_t *data32 = (uint32_t *)data; 2767 memcpy(data32, data, sizeof(data32));
2730 2768
2731 if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) 2769 if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL))
2732 return load_state(messenger_load_state_callback, m, data + cookie_len, 2770 return load_state(messenger_load_state_callback, m, data + cookie_len,
2733 length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); 2771 length - cookie_len, MESSENGER_STATE_COOKIE_TYPE);
2734 2772 else
2735 else if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL_OLD))
2736 return load_state(messenger_load_state_callback_old, m, data + cookie_len,
2737 length - cookie_len, MESSENGER_STATE_COOKIE_TYPE);
2738 else /* old state file */
2739 return -1; 2773 return -1;
2740} 2774}
2741 2775
2742/* return the size of data to pass to messenger_save_encrypted(...)
2743 *
2744 */
2745uint32_t messenger_size_encrypted(Messenger *m)
2746{
2747 return messenger_size(m) + crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
2748}
2749
2750/* Save the messenger, encrypting the data with key of length key_length
2751 *
2752 * return 0 on success.
2753 * return -1 on failure.
2754 */
2755int messenger_save_encrypted(Messenger *m, uint8_t *data, uint8_t *key, uint16_t key_length)
2756{
2757 uint32_t m_size = messenger_size(m);
2758 uint8_t *plain_messenger = malloc(m_size);
2759
2760 if (plain_messenger == NULL)
2761 return -1;
2762
2763 messenger_save(m, plain_messenger);
2764
2765 /* Hash the key with SHA256 to get a 32byte key. */
2766 uint8_t hash[crypto_hash_sha256_BYTES];
2767 crypto_hash_sha256(hash, key, key_length);
2768 random_nonce(data);
2769 encrypt_data_symmetric(hash, data, plain_messenger, m_size, data + crypto_secretbox_NONCEBYTES);
2770
2771 memset(plain_messenger, 0, m_size);
2772 free(plain_messenger);
2773 memset(hash, 0, crypto_hash_sha256_BYTES);
2774 return 0;
2775}
2776
2777/* Load the messenger from data of size length encrypted with key of key_length.
2778 *
2779 * return 0 on success.
2780 * return -1 on failure.
2781 */
2782int messenger_load_encrypted(Messenger *m, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length)
2783{
2784 if (length <= crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES)
2785 return -1;
2786
2787 uint8_t *plain_messenger = malloc(length);
2788
2789 if (plain_messenger == NULL)
2790 return -1;
2791
2792 /* Hash the key with SHA256 to get a 32byte key. */
2793 uint8_t hash[crypto_hash_sha256_BYTES];
2794 crypto_hash_sha256(hash, key, key_length);
2795 int len = decrypt_data_symmetric(hash, data, data + crypto_secretbox_NONCEBYTES, length - crypto_secretbox_NONCEBYTES,
2796 plain_messenger);
2797 int ret;
2798
2799 if ((uint32_t)len == length - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES) {
2800 ret = messenger_load(m, plain_messenger, length - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES);
2801 } else {
2802 ret = -1;
2803 }
2804
2805 memset(plain_messenger, 0, length);
2806 free(plain_messenger);
2807 memset(hash, 0, crypto_hash_sha256_BYTES);
2808 return ret;
2809}
2810
2811/* Return the number of friends in the instance m. 2776/* Return the number of friends in the instance m.
2812 * You should use this to determine how much memory to allocate 2777 * You should use this to determine how much memory to allocate
2813 * for copy_friendlist. */ 2778 * for copy_friendlist. */
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index c29b6594..b72a0831 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -34,18 +34,20 @@
34#include "onion_client.h" 34#include "onion_client.h"
35 35
36#define MAX_NAME_LENGTH 128 36#define MAX_NAME_LENGTH 128
37/* TODO: this must depend on other variable. */
37#define MAX_STATUSMESSAGE_LENGTH 1007 38#define MAX_STATUSMESSAGE_LENGTH 1007
38 39
39#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) 40#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
40 41
41#define PACKET_ID_PING 0 42/* NOTE: Packet ids below 16 must never be used. */
43#define PACKET_ID_ALIVE 16
42#define PACKET_ID_NICKNAME 48 44#define PACKET_ID_NICKNAME 48
43#define PACKET_ID_STATUSMESSAGE 49 45#define PACKET_ID_STATUSMESSAGE 49
44#define PACKET_ID_USERSTATUS 50 46#define PACKET_ID_USERSTATUS 50
45#define PACKET_ID_TYPING 51 47#define PACKET_ID_TYPING 51
46#define PACKET_ID_RECEIPT 65 48#define PACKET_ID_RECEIPT 63
47#define PACKET_ID_MESSAGE 64 49#define PACKET_ID_MESSAGE 64
48#define PACKET_ID_ACTION 63 50#define PACKET_ID_ACTION 65
49#define PACKET_ID_MSI 69 51#define PACKET_ID_MSI 69
50#define PACKET_ID_FILE_SENDREQUEST 80 52#define PACKET_ID_FILE_SENDREQUEST 80
51#define PACKET_ID_FILE_CONTROL 81 53#define PACKET_ID_FILE_CONTROL 81
@@ -80,17 +82,13 @@ enum {
80 FAERR_NOMEM = -8 82 FAERR_NOMEM = -8
81}; 83};
82 84
83/* Don't assume MAX_STATUSMESSAGE_LENGTH will stay at 128, it may be increased
84 * to an absurdly large number later.
85 */
86
87/* Default start timeout in seconds between friend requests. */ 85/* Default start timeout in seconds between friend requests. */
88#define FRIENDREQUEST_TIMEOUT 5; 86#define FRIENDREQUEST_TIMEOUT 5;
89 87
90/* Interval between the sending of ping packets. */ 88/* Interval between the sending of ping packets. */
91#define FRIEND_PING_INTERVAL 5 89#define FRIEND_PING_INTERVAL 5
92 90
93/* If no packets are recieved from friend in this time interval, kill the connection. */ 91/* If no packets are received from friend in this time interval, kill the connection. */
94#define FRIEND_CONNECTION_TIMEOUT (FRIEND_PING_INTERVAL * 2) 92#define FRIEND_CONNECTION_TIMEOUT (FRIEND_PING_INTERVAL * 2)
95 93
96/* USERSTATUS - 94/* USERSTATUS -
@@ -137,7 +135,7 @@ typedef struct {
137 uint64_t friendrequest_lastsent; // Time at which the last friend request was sent. 135 uint64_t friendrequest_lastsent; // Time at which the last friend request was sent.
138 uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts. 136 uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts.
139 uint8_t status; // 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. 137 uint8_t status; // 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online.
140 uint8_t info[MAX_DATA_SIZE]; // the data that is sent during the friend requests we do. 138 uint8_t info[MAX_FRIEND_REQUEST_DATA_SIZE]; // the data that is sent during the friend requests we do.
141 uint8_t name[MAX_NAME_LENGTH]; 139 uint8_t name[MAX_NAME_LENGTH];
142 uint16_t name_length; 140 uint16_t name_length;
143 uint8_t name_sent; // 0 if we didn't send our name to this friend 1 if we have. 141 uint8_t name_sent; // 0 if we didn't send our name to this friend 1 if we have.
@@ -354,7 +352,7 @@ int setname(Messenger *m, uint8_t *name, uint16_t length);
354 352
355/* 353/*
356 * Get your nickname. 354 * Get your nickname.
357 * m - The messanger context to use. 355 * m - The messenger context to use.
358 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 356 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
359 * 357 *
360 * return length of the name. 358 * return length of the name.
@@ -376,11 +374,6 @@ int getname(Messenger *m, int32_t friendnumber, uint8_t *name);
376int m_get_name_size(Messenger *m, int32_t friendnumber); 374int m_get_name_size(Messenger *m, int32_t friendnumber);
377int m_get_self_name_size(Messenger *m); 375int m_get_self_name_size(Messenger *m);
378 376
379/* returns valid ip port of connected friend on success
380 * returns zeroed out IP_Port on failure
381 */
382IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber);
383
384/* Set our user status. 377/* Set our user status.
385 * You are responsible for freeing status after. 378 * You are responsible for freeing status after.
386 * 379 *
@@ -739,24 +732,6 @@ void messenger_save(Messenger *m, uint8_t *data);
739/* Load the messenger from data of size length. */ 732/* Load the messenger from data of size length. */
740int messenger_load(Messenger *m, uint8_t *data, uint32_t length); 733int messenger_load(Messenger *m, uint8_t *data, uint32_t length);
741 734
742/* return the size of data to pass to messenger_save_encrypted(...)
743 */
744uint32_t messenger_size_encrypted(Messenger *m);
745
746/* Save the messenger, encrypting the data with key of length key_length
747 *
748 * return 0 on success.
749 * return -1 on failure.
750 */
751int messenger_save_encrypted(Messenger *m, uint8_t *data, uint8_t *key, uint16_t key_length);
752
753/* Load the messenger from data of size length encrypted with key of key_length.
754 *
755 * return 0 on success.
756 * return -1 on failure.
757 */
758int messenger_load_encrypted(Messenger *m, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length);
759
760/* Return the number of friends in the instance m. 735/* Return the number of friends in the instance m.
761 * You should use this to determine how much memory to allocate 736 * You should use this to determine how much memory to allocate
762 * for copy_friendlist. */ 737 * for copy_friendlist. */
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index 437429b9..e4845852 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -20,6 +20,9 @@
20* 20*
21*/ 21*/
22 22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
23 26
24#include "TCP_client.h" 27#include "TCP_client.h"
25 28
@@ -71,8 +74,8 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn, uint8_t *self_pub
71 memcpy(plain + crypto_box_PUBLICKEYBYTES, TCP_conn->sent_nonce, crypto_box_NONCEBYTES); 74 memcpy(plain + crypto_box_PUBLICKEYBYTES, TCP_conn->sent_nonce, crypto_box_NONCEBYTES);
72 memcpy(TCP_conn->last_packet, self_public_key, crypto_box_PUBLICKEYBYTES); 75 memcpy(TCP_conn->last_packet, self_public_key, crypto_box_PUBLICKEYBYTES);
73 new_nonce(TCP_conn->last_packet + crypto_box_PUBLICKEYBYTES); 76 new_nonce(TCP_conn->last_packet + crypto_box_PUBLICKEYBYTES);
74 int len = encrypt_data_fast(TCP_conn->shared_key, TCP_conn->last_packet + crypto_box_PUBLICKEYBYTES, plain, 77 int len = encrypt_data_symmetric(TCP_conn->shared_key, TCP_conn->last_packet + crypto_box_PUBLICKEYBYTES, plain,
75 sizeof(plain), TCP_conn->last_packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); 78 sizeof(plain), TCP_conn->last_packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
76 79
77 if (len != sizeof(plain) + crypto_box_MACBYTES) 80 if (len != sizeof(plain) + crypto_box_MACBYTES)
78 return -1; 81 return -1;
@@ -90,8 +93,8 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn, uint8_t *self_pub
90static int handle_handshake(TCP_Client_Connection *TCP_conn, uint8_t *data) 93static int handle_handshake(TCP_Client_Connection *TCP_conn, uint8_t *data)
91{ 94{
92 uint8_t plain[crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES]; 95 uint8_t plain[crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES];
93 int len = decrypt_data_fast(TCP_conn->shared_key, data, data + crypto_box_NONCEBYTES, 96 int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + crypto_box_NONCEBYTES,
94 TCP_SERVER_HANDSHAKE_SIZE - crypto_box_NONCEBYTES, plain); 97 TCP_SERVER_HANDSHAKE_SIZE - crypto_box_NONCEBYTES, plain);
95 98
96 if (len != sizeof(plain)) 99 if (len != sizeof(plain))
97 return -1; 100 return -1;
@@ -130,6 +133,206 @@ static int send_pending_data(TCP_Client_Connection *con)
130 return -1; 133 return -1;
131} 134}
132 135
136/* return 1 on success.
137 * return 0 if could not send packet.
138 * return -1 on failure (connection must be killed).
139 */
140static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, uint8_t *data, uint16_t length)
141{
142 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
143 return -1;
144
145 if (send_pending_data(con) == -1)
146 return 0;
147
148 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
149
150 uint16_t c_length = htons(length + crypto_box_MACBYTES);
151 memcpy(packet, &c_length, sizeof(uint16_t));
152 int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
153
154 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
155 return -1;
156
157 increment_nonce(con->sent_nonce);
158
159 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
160
161 if ((unsigned int)len == sizeof(packet))
162 return 1;
163
164 if (len <= 0)
165 return 0;
166
167 memcpy(con->last_packet, packet, length);
168 con->last_packet_length = sizeof(packet);
169 con->last_packet_sent = len;
170 return 1;
171}
172
173/* return 1 on success.
174 * return 0 if could not send packet.
175 * return -1 on failure (connection must be killed).
176 */
177int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
178{
179 uint8_t packet[1 + crypto_box_PUBLICKEYBYTES];
180 packet[0] = TCP_PACKET_ROUTING_REQUEST;
181 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
182 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
183}
184
185void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
186 uint8_t *public_key), void *object)
187{
188 con->response_callback = response_callback;
189 con->response_callback_object = object;
190}
191
192void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number,
193 uint8_t connection_id, uint8_t status), void *object)
194{
195 con->status_callback = status_callback;
196 con->status_callback_object = object;
197}
198
199/* return 1 on success.
200 * return 0 if could not send packet.
201 * return -1 on failure.
202 */
203int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_t length)
204{
205 if (con_id >= NUM_CLIENT_CONNECTIONS)
206 return -1;
207
208 if (con->connections[con_id].status != 2)
209 return -1;
210
211 uint8_t packet[1 + length];
212 packet[0] = con_id + NUM_RESERVED_PORTS;
213 memcpy(packet + 1, data, length);
214 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
215}
216
217/* return 1 on success.
218 * return 0 if could not send packet.
219 * return -1 on failure.
220 */
221int send_oob_packet(TCP_Client_Connection *con, uint8_t *public_key, uint8_t *data, uint16_t length)
222{
223 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH)
224 return -1;
225
226 uint8_t packet[1 + crypto_box_PUBLICKEYBYTES + length];
227 packet[0] = TCP_PACKET_OOB_SEND;
228 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
229 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
230 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
231}
232
233
234/* Set the number that will be used as an argument in the callbacks related to con_id.
235 *
236 * When not set by this function, the number is ~0.
237 *
238 * return 0 on success.
239 * return -1 on failure.
240 */
241int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number)
242{
243 if (con_id >= NUM_CLIENT_CONNECTIONS)
244 return -1;
245
246 if (con->connections[con_id].status == 0)
247 return -1;
248
249 con->connections[con_id].number = number;
250 return 0;
251}
252
253void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number,
254 uint8_t connection_id, uint8_t *data, uint16_t length), void *object)
255{
256 con->data_callback = data_callback;
257 con->data_callback_object = object;
258}
259
260void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, uint8_t *public_key,
261 uint8_t *data, uint16_t length), void *object)
262{
263 con->oob_data_callback = oob_data_callback;
264 con->oob_data_callback_object = object;
265}
266
267/* return 1 on success.
268 * return 0 if could not send packet.
269 * return -1 on failure (connection must be killed).
270 */
271static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
272{
273 uint8_t packet[1 + 1];
274 packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
275 packet[1] = id;
276 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
277}
278
279/* return 1 on success.
280 * return 0 if could not send packet.
281 * return -1 on failure (connection must be killed).
282 */
283static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id)
284{
285 uint8_t packet[1 + sizeof(uint64_t)];
286 packet[0] = TCP_PACKET_PING;
287 memcpy(packet + 1, &ping_id, sizeof(uint64_t));
288 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
289}
290
291/* return 1 on success.
292 * return 0 if could not send packet.
293 * return -1 on failure (connection must be killed).
294 */
295static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id)
296{
297 uint8_t packet[1 + sizeof(uint64_t)];
298 packet[0] = TCP_PACKET_PONG;
299 memcpy(packet + 1, &ping_id, sizeof(uint64_t));
300 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
301}
302
303/* return 1 on success.
304 * return 0 if could not send packet.
305 * return -1 on failure (connection must be killed).
306 */
307int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id)
308{
309 if (con_id >= NUM_CLIENT_CONNECTIONS)
310 return -1;
311
312 con->connections[con_id].status = 0;
313 con->connections[con_id].number = 0;
314 return send_disconnect_notification(con, con_id + NUM_RESERVED_PORTS);
315}
316
317/* return 1 on success.
318 * return 0 if could not send packet.
319 * return -1 on failure (connection must be killed).
320 */
321int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length)
322{
323 uint8_t packet[1 + length];
324 packet[0] = TCP_PACKET_ONION_REQUEST;
325 memcpy(packet + 1, data, length);
326 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
327}
328
329void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, uint8_t *data,
330 uint16_t length), void *object)
331{
332 con->onion_callback = onion_callback;
333 con->onion_callback_object = object;
334}
335
133/* Create new TCP connection to ip_port/public_key 336/* Create new TCP connection to ip_port/public_key
134 */ 337 */
135TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key, 338TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key,
@@ -149,6 +352,11 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
149 return NULL; 352 return NULL;
150 } 353 }
151 354
355 if (!set_socket_nosigpipe(sock)) {
356 kill_sock(sock);
357 return 0;
358 }
359
152 if (!(set_socket_nonblock(sock) && connect_sock_to(sock, ip_port))) { 360 if (!(set_socket_nonblock(sock) && connect_sock_to(sock, ip_port))) {
153 kill_sock(sock); 361 kill_sock(sock);
154 return NULL; 362 return NULL;
@@ -164,6 +372,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
164 temp->status = TCP_CLIENT_CONNECTING; 372 temp->status = TCP_CLIENT_CONNECTING;
165 temp->sock = sock; 373 temp->sock = sock;
166 memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES); 374 memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES);
375 temp->ip_port = ip_port;
167 376
168 if (generate_handshake(temp, self_public_key, self_secret_key) == -1) { 377 if (generate_handshake(temp, self_public_key, self_secret_key) == -1) {
169 kill_sock(sock); 378 kill_sock(sock);
@@ -176,8 +385,181 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
176 return temp; 385 return temp;
177} 386}
178 387
179static int do_confirmed_TCP(TCP_Client_Connection *TCP_connection) 388/* return 0 on success
389 * return -1 on failure
390 */
391static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_t length)
180{ 392{
393 if (length <= 1)
394 return -1;
395
396 switch (data[0]) {
397 case TCP_PACKET_ROUTING_RESPONSE: {
398 if (length != 1 + 1 + crypto_box_PUBLICKEYBYTES)
399 return -1;
400
401 if (data[1] < NUM_RESERVED_PORTS)
402 return 0;
403
404 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
405
406 if (conn->connections[con_id].status != 0)
407 return 0;
408
409 conn->connections[con_id].status = 1;
410 conn->connections[con_id].number = ~0;
411 memcpy(conn->connections[con_id].public_key, data + 2, crypto_box_PUBLICKEYBYTES);
412
413 if (conn->response_callback)
414 conn->response_callback(conn->response_callback_object, con_id, conn->connections[con_id].public_key);
415
416 return 0;
417 }
418
419 case TCP_PACKET_CONNECTION_NOTIFICATION: {
420 if (length != 1 + 1)
421 return -1;
422
423 if (data[1] < NUM_RESERVED_PORTS)
424 return -1;
425
426 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
427
428 if (conn->connections[con_id].status != 1)
429 return -1;
430
431 conn->connections[con_id].status = 2;
432
433 if (conn->status_callback)
434 conn->status_callback(conn->status_callback_object, conn->connections[con_id].number, con_id,
435 conn->connections[con_id].status);
436
437 return 0;
438 }
439
440 case TCP_PACKET_DISCONNECT_NOTIFICATION: {
441 if (length != 1 + 1)
442 return -1;
443
444 if (data[1] < NUM_RESERVED_PORTS)
445 return -1;
446
447 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
448
449 if (conn->connections[con_id].status == 0)
450 return 0;
451
452 if (conn->connections[con_id].status != 2)
453 return -1;
454
455 conn->connections[con_id].status = 1;
456
457 if (conn->status_callback)
458 conn->status_callback(conn->status_callback_object, conn->connections[con_id].number, con_id,
459 conn->connections[con_id].status);
460
461 return 0;
462 }
463
464 case TCP_PACKET_PING: {
465 if (length != 1 + sizeof(uint64_t))
466 return -1;
467
468 uint64_t ping_id;
469 memcpy(&ping_id, data + 1, sizeof(uint64_t));
470 send_ping_response(conn, ping_id);
471 return 0;
472 }
473
474 case TCP_PACKET_PONG: {
475 if (length != 1 + sizeof(uint64_t))
476 return -1;
477
478 uint64_t ping_id;
479 memcpy(&ping_id, data + 1, sizeof(uint64_t));
480
481 if (ping_id) {
482 if (ping_id == conn->ping_id) {
483 conn->ping_id = 0;
484 }
485
486 return 0;
487 } else {
488 return -1;
489 }
490 }
491
492 case TCP_PACKET_OOB_RECV: {
493 if (length <= 1 + crypto_box_PUBLICKEYBYTES)
494 return -1;
495
496 if (conn->oob_data_callback)
497 conn->oob_data_callback(conn->oob_data_callback_object, data + 1, data + 1 + crypto_box_PUBLICKEYBYTES,
498 length - (1 + crypto_box_PUBLICKEYBYTES));
499
500 return 0;
501 }
502
503 case TCP_PACKET_ONION_RESPONSE: {
504 conn->onion_callback(conn->onion_callback_object, data + 1, length - 1);
505 return 0;
506 }
507
508 default: {
509 if (data[0] < NUM_RESERVED_PORTS)
510 return -1;
511
512 uint8_t con_id = data[0] - NUM_RESERVED_PORTS;
513
514 if (conn->data_callback)
515 conn->data_callback(conn->data_callback_object, conn->connections[con_id].number, con_id, data + 1, length - 1);
516 }
517 }
518
519 return 0;
520}
521
522static int do_confirmed_TCP(TCP_Client_Connection *conn)
523{
524 send_pending_data(conn);
525 uint8_t packet[MAX_PACKET_SIZE];
526 int len;
527
528 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) {
529 uint64_t ping_id = random_64b();
530
531 if (!ping_id)
532 ++ping_id;
533
534 int ret = send_ping_request(conn, ping_id);
535
536 if (ret == 1) {
537 conn->last_pinged = unix_time();
538 conn->ping_id = ping_id;
539 } else {
540 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
541 conn->status = TCP_CLIENT_DISCONNECTED;
542 }
543 }
544 }
545
546 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
547 conn->status = TCP_CLIENT_DISCONNECTED;
548 return 0;
549 }
550
551 while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
552 conn->recv_nonce, packet, sizeof(packet)))) {
553 if (len == -1) {
554 conn->status = TCP_CLIENT_DISCONNECTED;
555 break;
556 }
557
558 if (handle_TCP_packet(conn, packet, len) == -1) {
559 conn->status = TCP_CLIENT_DISCONNECTED;
560 break;
561 }
562 }
181 563
182 return 0; 564 return 0;
183} 565}
@@ -204,6 +586,7 @@ void do_TCP_connection(TCP_Client_Connection *TCP_connection)
204 586
205 if (sizeof(data) == len) { 587 if (sizeof(data) == len) {
206 if (handle_handshake(TCP_connection, data) == 0) { 588 if (handle_handshake(TCP_connection, data) == 0) {
589 TCP_connection->kill_at = ~0;
207 TCP_connection->status = TCP_CLIENT_CONFIRMED; 590 TCP_connection->status = TCP_CLIENT_CONFIRMED;
208 } else { 591 } else {
209 TCP_connection->kill_at = 0; 592 TCP_connection->kill_at = 0;
@@ -225,7 +608,10 @@ void do_TCP_connection(TCP_Client_Connection *TCP_connection)
225 */ 608 */
226void kill_TCP_connection(TCP_Client_Connection *TCP_connection) 609void kill_TCP_connection(TCP_Client_Connection *TCP_connection)
227{ 610{
611 if (TCP_connection == NULL)
612 return;
613
228 kill_sock(TCP_connection->sock); 614 kill_sock(TCP_connection->sock);
229 memset(TCP_connection, 0, sizeof(TCP_Client_Connection)); 615 memset(TCP_connection, 0, sizeof(TCP_Client_Connection));
230 free(TCP_connection); 616 free(TCP_connection);
231} \ No newline at end of file 617}
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index eb2aa39c..afb95392 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -24,7 +24,7 @@
24#ifndef TCP_CLIENT_H 24#ifndef TCP_CLIENT_H
25#define TCP_CLIENT_H 25#define TCP_CLIENT_H
26 26
27#include "net_crypto.h" 27#include "crypto_core.h"
28#include "TCP_server.h" 28#include "TCP_server.h"
29 29
30#define TCP_CONNECTION_TIMEOUT 10 30#define TCP_CONNECTION_TIMEOUT 10
@@ -40,6 +40,7 @@ typedef struct {
40 uint8_t status; 40 uint8_t status;
41 sock_t sock; 41 sock_t sock;
42 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* public key of the server */ 42 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* public key of the server */
43 IP_Port ip_port; /* The ip and port of the server */
43 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */ 44 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
44 uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */ 45 uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */
45 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 46 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -55,6 +56,25 @@ typedef struct {
55 56
56 uint64_t last_pinged; 57 uint64_t last_pinged;
57 uint64_t ping_id; 58 uint64_t ping_id;
59
60 void *net_crypto_pointer;
61 uint32_t net_crypto_location;
62 struct {
63 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
64 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
65 uint32_t number;
66 } connections[NUM_CLIENT_CONNECTIONS];
67 int (*response_callback)(void *object, uint8_t connection_id, uint8_t *public_key);
68 void *response_callback_object;
69 int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status);
70 void *status_callback_object;
71 int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length);
72 void *data_callback_object;
73 int (*oob_data_callback)(void *object, uint8_t *public_key, uint8_t *data, uint16_t length);
74 void *oob_data_callback_object;
75
76 int (*onion_callback)(void *object, uint8_t *data, uint16_t length);
77 void *onion_callback_object;
58} TCP_Client_Connection; 78} TCP_Client_Connection;
59 79
60/* Create new TCP connection to ip_port/public_key 80/* Create new TCP connection to ip_port/public_key
@@ -70,9 +90,54 @@ void do_TCP_connection(TCP_Client_Connection *TCP_connection);
70 */ 90 */
71void kill_TCP_connection(TCP_Client_Connection *TCP_connection); 91void kill_TCP_connection(TCP_Client_Connection *TCP_connection);
72 92
73int get_TCP_connection_status(TCP_Client_Connection *TCP_connection); 93/* return 1 on success.
94 * return 0 if could not send packet.
95 * return -1 on failure (connection must be killed).
96 */
97int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length);
98void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, uint8_t *data,
99 uint16_t length), void *object);
74 100
75int read_TCP_connection(TCP_Client_Connection *TCP_connection, uint8_t *data); 101/* return 1 on success.
102 * return 0 if could not send packet.
103 * return -1 on failure (connection must be killed).
104 */
105int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key);
106void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
107 uint8_t *public_key), void *object);
108void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number,
109 uint8_t connection_id, uint8_t status), void *object);
110
111/* return 1 on success.
112 * return 0 if could not send packet.
113 * return -1 on failure (connection must be killed).
114 */
115int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id);
116
117/* Set the number that will be used as an argument in the callbacks related to con_id.
118 *
119 * When not set by this function, the number is ~0.
120 *
121 * return 0 on success.
122 * return -1 on failure.
123 */
124int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32_t number);
125
126/* return 1 on success.
127 * return 0 if could not send packet.
128 * return -1 on failure.
129 */
130int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_t length);
131void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number,
132 uint8_t connection_id, uint8_t *data, uint16_t length), void *object);
133
134/* return 1 on success.
135 * return 0 if could not send packet.
136 * return -1 on failure.
137 */
138int send_oob_packet(TCP_Client_Connection *con, uint8_t *public_key, uint8_t *data, uint16_t length);
139void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, uint8_t *public_key,
140 uint8_t *data, uint16_t length), void *object);
76 141
77 142
78#endif 143#endif
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index 4eed1209..ceab5f10 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -20,6 +20,10 @@
20* 20*
21*/ 21*/
22 22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
23#include "TCP_server.h" 27#include "TCP_server.h"
24 28
25#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) 29#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
@@ -69,17 +73,46 @@ static int realloc_connection(TCP_Server *TCP_server, uint32_t num)
69 return 0; 73 return 0;
70 } 74 }
71 75
76 if (num == TCP_server->size_accepted_connections) {
77 return 0;
78 }
79
72 TCP_Secure_Connection *new_connections = realloc(TCP_server->accepted_connection_array, 80 TCP_Secure_Connection *new_connections = realloc(TCP_server->accepted_connection_array,
73 num * sizeof(TCP_Secure_Connection)); 81 num * sizeof(TCP_Secure_Connection));
74 82
75 if (new_connections == NULL) 83 if (new_connections == NULL)
76 return -1; 84 return -1;
77 85
86 if (num > TCP_server->size_accepted_connections) {
87 uint32_t old_size = TCP_server->size_accepted_connections;
88 uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection);
89 memset(new_connections + old_size, 0, size_new_entries);
90 }
91
78 TCP_server->accepted_connection_array = new_connections; 92 TCP_server->accepted_connection_array = new_connections;
79 TCP_server->size_accepted_connections = num; 93 TCP_server->size_accepted_connections = num;
80 return 0; 94 return 0;
81} 95}
82 96
97/* return index corresponding to connection with peer on success
98 * return -1 on failure.
99 */
100static int get_TCP_connection_index(TCP_Server *TCP_server, uint8_t *public_key)
101{
102 //TODO optimize this function.
103 uint32_t i;
104
105 for (i = 0; i < TCP_server->size_accepted_connections; ++i) {
106 if (memcmp(TCP_server->accepted_connection_array[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
107 return i;
108 }
109
110 return -1;
111}
112
113
114static int kill_accepted(TCP_Server *TCP_server, int index);
115
83/* Add accepted TCP connection to the list. 116/* Add accepted TCP connection to the list.
84 * 117 *
85 * return index on success 118 * return index on success
@@ -87,7 +120,12 @@ static int realloc_connection(TCP_Server *TCP_server, uint32_t num)
87 */ 120 */
88static int add_accepted(TCP_Server *TCP_server, TCP_Secure_Connection *con) 121static int add_accepted(TCP_Server *TCP_server, TCP_Secure_Connection *con)
89{ 122{
90 int index = -1; 123 int index = get_TCP_connection_index(TCP_server, con->public_key);
124
125 if (index != -1) { /* If an old connection to the same public key exists, kill it. */
126 kill_accepted(TCP_server, index);
127 index = -1;
128 }
91 129
92 if (TCP_server->size_accepted_connections == TCP_server->num_accepted_connections) { 130 if (TCP_server->size_accepted_connections == TCP_server->num_accepted_connections) {
93 if (realloc_connection(TCP_server, TCP_server->size_accepted_connections + 4) == -1) 131 if (realloc_connection(TCP_server, TCP_server->size_accepted_connections + 4) == -1)
@@ -141,22 +179,6 @@ static int del_accepted(TCP_Server *TCP_server, int index)
141 return 0; 179 return 0;
142} 180}
143 181
144/* return index corresponding to connection with peer on success
145 * return -1 on failure.
146 */
147static int get_TCP_connection_index(TCP_Server *TCP_server, uint8_t *public_key)
148{
149 //TODO optimize this function.
150 uint32_t i;
151
152 for (i = 0; i < TCP_server->size_accepted_connections; ++i) {
153 if (memcmp(TCP_server->accepted_connection_array[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
154 return i;
155 }
156
157 return -1;
158}
159
160/* Read the next two bytes in TCP stream then convert them to 182/* Read the next two bytes in TCP stream then convert them to
161 * length (host byte order). 183 * length (host byte order).
162 * 184 *
@@ -224,14 +246,15 @@ int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length)
224 return -1; 246 return -1;
225} 247}
226 248
227/* return length of recieved packet on success. 249/* return length of received packet on success.
228 * return 0 if could not read any packet. 250 * return 0 if could not read any packet.
229 * return -1 on failure (connection must be killed). 251 * return -1 on failure (connection must be killed).
230 */ 252 */
231static int read_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t max_len) 253int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key,
254 uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
232{ 255{
233 if (con->next_packet_length == 0) { 256 if (*next_packet_length == 0) {
234 uint16_t len = read_TCP_length(con->sock); 257 uint16_t len = read_TCP_length(sock);
235 258
236 if (len == (uint16_t)~0) 259 if (len == (uint16_t)~0)
237 return -1; 260 return -1;
@@ -239,26 +262,26 @@ static int read_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t
239 if (len == 0) 262 if (len == 0)
240 return 0; 263 return 0;
241 264
242 con->next_packet_length = len; 265 *next_packet_length = len;
243 } 266 }
244 267
245 if (max_len + crypto_box_MACBYTES < con->next_packet_length) 268 if (max_len + crypto_box_MACBYTES < *next_packet_length)
246 return -1; 269 return -1;
247 270
248 uint8_t data_encrypted[con->next_packet_length]; 271 uint8_t data_encrypted[*next_packet_length];
249 int len_packet = read_TCP_packet(con->sock, data_encrypted, con->next_packet_length); 272 int len_packet = read_TCP_packet(sock, data_encrypted, *next_packet_length);
250 273
251 if (len_packet != con->next_packet_length) 274 if (len_packet != *next_packet_length)
252 return 0; 275 return 0;
253 276
254 con->next_packet_length = 0; 277 *next_packet_length = 0;
255 278
256 int len = decrypt_data_fast(con->shared_key, con->recv_nonce, data_encrypted, len_packet, data); 279 int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
257 280
258 if (len + crypto_box_MACBYTES != len_packet) 281 if (len + crypto_box_MACBYTES != len_packet)
259 return -1; 282 return -1;
260 283
261 increment_nonce(con->recv_nonce); 284 increment_nonce(recv_nonce);
262 285
263 return len; 286 return len;
264} 287}
@@ -308,7 +331,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_
308 331
309 uint16_t c_length = htons(length + crypto_box_MACBYTES); 332 uint16_t c_length = htons(length + crypto_box_MACBYTES);
310 memcpy(packet, &c_length, sizeof(uint16_t)); 333 memcpy(packet, &c_length, sizeof(uint16_t));
311 int len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); 334 int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
312 335
313 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) 336 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
314 return -1; 337 return -1;
@@ -337,6 +360,33 @@ static void kill_TCP_connection(TCP_Secure_Connection *con)
337 memset(con, 0, sizeof(TCP_Secure_Connection)); 360 memset(con, 0, sizeof(TCP_Secure_Connection));
338} 361}
339 362
363static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number);
364
365/* Kill an accepted TCP_Secure_Connection
366 *
367 * return -1 on failure.
368 * return 0 on success.
369 */
370static int kill_accepted(TCP_Server *TCP_server, int index)
371{
372 if ((uint32_t)index >= TCP_server->size_accepted_connections)
373 return -1;
374
375 uint32_t i;
376
377 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
378 rm_connection_index(TCP_server, &TCP_server->accepted_connection_array[index], i);
379 }
380
381 sock_t sock = TCP_server->accepted_connection_array[index].sock;
382
383 if (del_accepted(TCP_server, index) != 0)
384 return -1;
385
386 kill_sock(sock);
387 return 0;
388}
389
340/* return 1 if everything went well. 390/* return 1 if everything went well.
341 * return -1 if the connection must be killed. 391 * return -1 if the connection must be killed.
342 */ 392 */
@@ -351,8 +401,8 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint1
351 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 401 uint8_t shared_key[crypto_box_BEFORENMBYTES];
352 encrypt_precompute(data, self_secret_key, shared_key); 402 encrypt_precompute(data, self_secret_key, shared_key);
353 uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE]; 403 uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
354 int len = decrypt_data_fast(shared_key, data + crypto_box_PUBLICKEYBYTES, 404 int len = decrypt_data_symmetric(shared_key, data + crypto_box_PUBLICKEYBYTES,
355 data + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES, plain); 405 data + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES, plain);
356 406
357 if (len != TCP_HANDSHAKE_PLAIN_SIZE) 407 if (len != TCP_HANDSHAKE_PLAIN_SIZE)
358 return -1; 408 return -1;
@@ -368,7 +418,8 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint1
368 uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; 418 uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
369 new_nonce(response); 419 new_nonce(response);
370 420
371 len = encrypt_data_fast(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, response + crypto_box_NONCEBYTES); 421 len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
422 response + crypto_box_NONCEBYTES);
372 423
373 if (len != TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES) 424 if (len != TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES)
374 return -1; 425 return -1;
@@ -449,9 +500,16 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8
449 } 500 }
450 501
451 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { 502 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
452 if (con->connections[i].status == 0) { 503 if (con->connections[i].status != 0) {
504 if (memcmp(public_key, con->connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
505 if (send_routing_response(con, i + NUM_RESERVED_PORTS, public_key) == -1) {
506 return -1;
507 } else {
508 return 0;
509 }
510 }
511 } else if (index == (uint32_t)~0) {
453 index = i; 512 index = i;
454 break;
455 } 513 }
456 } 514 }
457 515
@@ -502,7 +560,37 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8
502 return 0; 560 return 0;
503} 561}
504 562
505static int disconnect_conection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number) 563/* return 0 on success.
564 * return -1 on failure (connection must be killed).
565 */
566static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, uint8_t *public_key, uint8_t *data,
567 uint16_t length)
568{
569 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH)
570 return -1;
571
572 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id];
573
574 int other_index = get_TCP_connection_index(TCP_server, public_key);
575
576 if (other_index != -1) {
577 uint8_t resp_packet[1 + crypto_box_PUBLICKEYBYTES + length];
578 resp_packet[0] = TCP_PACKET_OOB_RECV;
579 memcpy(resp_packet + 1, con->public_key, crypto_box_PUBLICKEYBYTES);
580 memcpy(resp_packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
581 write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet,
582 sizeof(resp_packet));
583 }
584
585 return 0;
586}
587
588/* Remove connection with con_number from the connections array of con.
589 *
590 * return -1 on failure.
591 * return 0 on success.
592 */
593static int rm_connection_index(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t con_number)
506{ 594{
507 if (con_number >= NUM_CLIENT_CONNECTIONS) 595 if (con_number >= NUM_CLIENT_CONNECTIONS)
508 return -1; 596 return -1;
@@ -526,8 +614,6 @@ static int disconnect_conection_index(TCP_Server *TCP_server, TCP_Secure_Connect
526 con->connections[con_number].index = 0; 614 con->connections[con_number].index = 0;
527 con->connections[con_number].other_id = 0; 615 con->connections[con_number].other_id = 0;
528 con->connections[con_number].status = 0; 616 con->connections[con_number].status = 0;
529 //TODO: return values?
530 send_disconnect_notification(con, con_number);
531 return 0; 617 return 0;
532 } else { 618 } else {
533 return -1; 619 return -1;
@@ -586,7 +672,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *d
586 if (length != 2) 672 if (length != 2)
587 return -1; 673 return -1;
588 674
589 return disconnect_conection_index(TCP_server, con, data[1] - NUM_RESERVED_PORTS); 675 return rm_connection_index(TCP_server, con, data[1] - NUM_RESERVED_PORTS);
590 } 676 }
591 677
592 case TCP_PACKET_PING: { 678 case TCP_PACKET_PING: {
@@ -618,6 +704,14 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *d
618 } 704 }
619 } 705 }
620 706
707 case TCP_PACKET_OOB_SEND: {
708 if (length <= 1 + crypto_box_PUBLICKEYBYTES)
709 return -1;
710
711 return handle_TCP_oob_send(TCP_server, con_id, data + 1, data + 1 + crypto_box_PUBLICKEYBYTES,
712 length - (1 + crypto_box_PUBLICKEYBYTES));
713 }
714
621 case TCP_PACKET_ONION_REQUEST: { 715 case TCP_PACKET_ONION_REQUEST: {
622 if (TCP_server->onion) { 716 if (TCP_server->onion) {
623 if (length <= 1 + crypto_box_NONCEBYTES + ONION_SEND_BASE * 2) 717 if (length <= 1 + crypto_box_NONCEBYTES + ONION_SEND_BASE * 2)
@@ -642,22 +736,22 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *d
642 if (data[0] < NUM_RESERVED_PORTS) 736 if (data[0] < NUM_RESERVED_PORTS)
643 return -1; 737 return -1;
644 738
645 uint8_t con_id = data[0] - NUM_RESERVED_PORTS; 739 uint8_t c_id = data[0] - NUM_RESERVED_PORTS;
646 740
647 if (con_id >= NUM_CLIENT_CONNECTIONS) 741 if (c_id >= NUM_CLIENT_CONNECTIONS)
648 return -1; 742 return -1;
649 743
650 if (con->connections[con_id].status == 0) 744 if (con->connections[c_id].status == 0)
651 return -1; 745 return -1;
652 746
653 if (con->connections[con_id].status != 2) 747 if (con->connections[c_id].status != 2)
654 return 0; 748 return 0;
655 749
656 uint32_t index = con->connections[con_id].index; 750 uint32_t index = con->connections[c_id].index;
657 uint8_t other_con_id = con->connections[con_id].other_id + NUM_RESERVED_PORTS; 751 uint8_t other_c_id = con->connections[c_id].other_id + NUM_RESERVED_PORTS;
658 uint8_t new_data[length]; 752 uint8_t new_data[length];
659 memcpy(new_data, data, length); 753 memcpy(new_data, data, length);
660 new_data[0] = other_con_id; 754 new_data[0] = other_c_id;
661 int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length); 755 int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length);
662 756
663 if (ret == -1) 757 if (ret == -1)
@@ -678,11 +772,8 @@ static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection
678 if (index == -1) 772 if (index == -1)
679 return -1; 773 return -1;
680 774
681 TCP_Secure_Connection *conn = &TCP_server->accepted_connection_array[index];
682
683 if (handle_TCP_packet(TCP_server, index, data, length) == -1) { 775 if (handle_TCP_packet(TCP_server, index, data, length) == -1) {
684 kill_TCP_connection(conn); 776 kill_accepted(TCP_server, index);
685 del_accepted(TCP_server, index);
686 } 777 }
687 778
688 return 0; 779 return 0;
@@ -701,6 +792,11 @@ static int accept_connection(TCP_Server *TCP_server, sock_t sock)
701 return 0; 792 return 0;
702 } 793 }
703 794
795 if (!set_socket_nosigpipe(sock)) {
796 kill_sock(sock);
797 return 0;
798 }
799
704 TCP_Secure_Connection *conn = 800 TCP_Secure_Connection *conn =
705 &TCP_server->incomming_connection_queue[TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS]; 801 &TCP_server->incomming_connection_queue[TCP_server->incomming_connection_queue_index % MAX_INCOMMING_CONNECTIONS];
706 802
@@ -848,7 +944,8 @@ static void do_TCP_unconfirmed(TCP_Server *TCP_server)
848 continue; 944 continue;
849 945
850 uint8_t packet[MAX_PACKET_SIZE]; 946 uint8_t packet[MAX_PACKET_SIZE];
851 int len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet)); 947 int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, conn->recv_nonce,
948 packet, sizeof(packet));
852 949
853 if (len == 0) { 950 if (len == 0) {
854 continue; 951 continue;
@@ -889,12 +986,16 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
889 if (ret == 1) { 986 if (ret == 1) {
890 conn->last_pinged = unix_time(); 987 conn->last_pinged = unix_time();
891 conn->ping_id = ping_id; 988 conn->ping_id = ping_id;
989 } else {
990 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
991 kill_accepted(TCP_server, i);
992 continue;
993 }
892 } 994 }
893 } 995 }
894 996
895 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) { 997 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
896 kill_TCP_connection(conn); 998 kill_accepted(TCP_server, i);
897 del_accepted(TCP_server, i);
898 continue; 999 continue;
899 } 1000 }
900 1001
@@ -902,16 +1003,15 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
902 uint8_t packet[MAX_PACKET_SIZE]; 1003 uint8_t packet[MAX_PACKET_SIZE];
903 int len; 1004 int len;
904 1005
905 while ((len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet)))) { 1006 while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key,
1007 conn->recv_nonce, packet, sizeof(packet)))) {
906 if (len == -1) { 1008 if (len == -1) {
907 kill_TCP_connection(conn); 1009 kill_accepted(TCP_server, i);
908 del_accepted(TCP_server, i);
909 break; 1010 break;
910 } 1011 }
911 1012
912 if (handle_TCP_packet(TCP_server, i, packet, len) == -1) { 1013 if (handle_TCP_packet(TCP_server, i, packet, len) == -1) {
913 kill_TCP_connection(conn); 1014 kill_accepted(TCP_server, i);
914 del_accepted(TCP_server, i);
915 break; 1015 break;
916 } 1016 }
917 } 1017 }
diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h
index 3ae0eba4..fc8c234b 100644
--- a/toxcore/TCP_server.h
+++ b/toxcore/TCP_server.h
@@ -23,10 +23,10 @@
23#ifndef TCP_SERVER_H 23#ifndef TCP_SERVER_H
24#define TCP_SERVER_H 24#define TCP_SERVER_H
25 25
26#include "net_crypto.h" 26#include "crypto_core.h"
27#include "onion.h" 27#include "onion.h"
28 28
29#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 29#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MACH__)
30#define MSG_NOSIGNAL 0 30#define MSG_NOSIGNAL 0
31#endif 31#endif
32 32
@@ -39,6 +39,7 @@
39#define TCP_HANDSHAKE_PLAIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES) 39#define TCP_HANDSHAKE_PLAIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES)
40#define TCP_SERVER_HANDSHAKE_SIZE (crypto_box_NONCEBYTES + TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES) 40#define TCP_SERVER_HANDSHAKE_SIZE (crypto_box_NONCEBYTES + TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES)
41#define TCP_CLIENT_HANDSHAKE_SIZE (crypto_box_PUBLICKEYBYTES + TCP_SERVER_HANDSHAKE_SIZE) 41#define TCP_CLIENT_HANDSHAKE_SIZE (crypto_box_PUBLICKEYBYTES + TCP_SERVER_HANDSHAKE_SIZE)
42#define TCP_MAX_OOB_DATA_LENGTH 1024
42 43
43#define NUM_RESERVED_PORTS 16 44#define NUM_RESERVED_PORTS 16
44#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS) 45#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS)
@@ -49,16 +50,16 @@
49#define TCP_PACKET_DISCONNECT_NOTIFICATION 3 50#define TCP_PACKET_DISCONNECT_NOTIFICATION 3
50#define TCP_PACKET_PING 4 51#define TCP_PACKET_PING 4
51#define TCP_PACKET_PONG 5 52#define TCP_PACKET_PONG 5
53#define TCP_PACKET_OOB_SEND 6
54#define TCP_PACKET_OOB_RECV 7
52#define TCP_PACKET_ONION_REQUEST 8 55#define TCP_PACKET_ONION_REQUEST 8
53#define TCP_PACKET_ONION_RESPONSE 9 56#define TCP_PACKET_ONION_RESPONSE 9
54 57
55#define ARRAY_ENTRY_SIZE 6 58#define ARRAY_ENTRY_SIZE 6
56 59
57#define TCP_ONION_FAMILY (AF_INET6 + 1)
58
59/* frequency to ping connected nodes and timeout in seconds */ 60/* frequency to ping connected nodes and timeout in seconds */
60#define TCP_PING_FREQUENCY 30 61#define TCP_PING_FREQUENCY 30
61#define TCP_PING_TIMEOUT 20 62#define TCP_PING_TIMEOUT 10
62 63
63enum { 64enum {
64 TCP_STATUS_NO_STATUS, 65 TCP_STATUS_NO_STATUS,
@@ -140,4 +141,12 @@ uint16_t read_TCP_length(sock_t sock);
140 */ 141 */
141int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length); 142int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length);
142 143
144/* return length of received packet on success.
145 * return 0 if could not read any packet.
146 * return -1 on failure (connection must be killed).
147 */
148int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key,
149 uint8_t *recv_nonce, uint8_t *data, uint16_t max_len);
150
151
143#endif 152#endif
diff --git a/toxcore/assoc.c b/toxcore/assoc.c
index c8f58c9c..ed1ec241 100644
--- a/toxcore/assoc.c
+++ b/toxcore/assoc.c
@@ -29,7 +29,7 @@
29 * Candidates are kept in buckets of hash tables. The hash 29 * Candidates are kept in buckets of hash tables. The hash
30 * function is calculated from the client_id. Up to 30 * function is calculated from the client_id. Up to
31 * HASH_COLLIDE_COUNT alternative positions are tried if 31 * HASH_COLLIDE_COUNT alternative positions are tried if
32 * the inital position is already used by a different entry. 32 * the initial position is already used by a different entry.
33 * The collision function is multiplicative, not additive. 33 * The collision function is multiplicative, not additive.
34 * 34 *
35 * A new candidate can bump an existing candidate, if it is 35 * A new candidate can bump an existing candidate, if it is
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
new file mode 100644
index 00000000..6e92f5b6
--- /dev/null
+++ b/toxcore/crypto_core.c
@@ -0,0 +1,262 @@
1/* net_crypto.c
2 *
3 * Functions for the core crypto.
4 *
5 * NOTE: This code has to be perfect. We don't mess around with encryption.
6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 *
9 * This file is part of Tox.
10 *
11 * Tox is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * Tox is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23 *
24 */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include "crypto_core.h"
31
32
33/* Use this instead of memcmp; not vulnerable to timing attacks.
34 returns 0 if both mem locations of length are equal,
35 return -1 if they are not. */
36int crypto_cmp(uint8_t *mem1, uint8_t *mem2, uint32_t length)
37{
38 if (length == 16) {
39 return crypto_verify_16(mem1, mem2);
40 } else if (length == 32) {
41 return crypto_verify_32(mem1, mem2);
42 }
43
44 unsigned int i, check = 0;
45
46 for (i = 0; i < length; ++i) {
47 check |= mem1[i] ^ mem2[i];
48 }
49
50 return (1 & ((check - 1) >> 8)) - 1;
51}
52
53/* return a random number.
54 */
55uint32_t random_int(void)
56{
57 uint32_t randnum;
58 randombytes((uint8_t *)&randnum , sizeof(randnum));
59 return randnum;
60}
61
62uint64_t random_64b(void)
63{
64 uint64_t randnum;
65 randombytes((uint8_t *)&randnum, sizeof(randnum));
66 return randnum;
67}
68
69/* Precomputes the shared key from their public_key and our secret_key.
70 * This way we can avoid an expensive elliptic curve scalar multiply for each
71 * encrypt/decrypt operation.
72 * enc_key has to be crypto_box_BEFORENMBYTES bytes long.
73 */
74void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key)
75{
76 crypto_box_beforenm(enc_key, public_key, secret_key);
77}
78
79int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted)
80{
81 if (length == 0)
82 return -1;
83
84 uint8_t temp_plain[length + crypto_box_ZEROBYTES];
85 uint8_t temp_encrypted[length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES];
86
87 memset(temp_plain, 0, crypto_box_ZEROBYTES);
88 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
89
90 if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0)
91 return -1;
92
93 /* Unpad the encrypted message. */
94 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
95 return length + crypto_box_MACBYTES;
96}
97
98int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain)
99{
100 if (length <= crypto_box_BOXZEROBYTES)
101 return -1;
102
103 uint8_t temp_plain[length + crypto_box_ZEROBYTES];
104 uint8_t temp_encrypted[length + crypto_box_BOXZEROBYTES];
105
106 memset(temp_plain, 0, crypto_box_BOXZEROBYTES);
107 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
108
109 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, secret_key) != 0)
110 return -1;
111
112 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
113 return length - crypto_box_MACBYTES;
114}
115
116int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
117 uint8_t *plain, uint32_t length, uint8_t *encrypted)
118{
119 uint8_t k[crypto_box_BEFORENMBYTES];
120 encrypt_precompute(public_key, secret_key, k);
121 return encrypt_data_symmetric(k, nonce, plain, length, encrypted);
122}
123
124int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
125 uint8_t *encrypted, uint32_t length, uint8_t *plain)
126{
127 uint8_t k[crypto_box_BEFORENMBYTES];
128 encrypt_precompute(public_key, secret_key, k);
129 return decrypt_data_symmetric(k, nonce, encrypted, length, plain);
130}
131
132
133/* Increment the given nonce by 1. */
134void increment_nonce(uint8_t *nonce)
135{
136 uint32_t i;
137
138 for (i = crypto_box_NONCEBYTES; i != 0; --i) {
139 ++nonce[i - 1];
140
141 if (nonce[i - 1] != 0)
142 break;
143 }
144}
145/* increment the given nonce by num */
146void increment_nonce_number(uint8_t *nonce, uint32_t num)
147{
148 uint32_t num1, num2;
149 memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1));
150 num1 = ntohl(num1);
151 num2 = num + num1;
152
153 if (num2 < num1) {
154 uint32_t i;
155
156 for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) {
157 ++nonce[i - 1];
158
159 if (nonce[i - 1] != 0)
160 break;
161 }
162 }
163
164 num2 = htonl(num2);
165 memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2));
166}
167
168/* Fill the given nonce with random bytes. */
169void random_nonce(uint8_t *nonce)
170{
171 randombytes(nonce, crypto_box_NONCEBYTES);
172}
173
174/* Fill a key crypto_box_KEYBYTES big with random bytes */
175void new_symmetric_key(uint8_t *key)
176{
177 randombytes(key, crypto_box_KEYBYTES);
178}
179
180static uint8_t base_nonce[crypto_box_NONCEBYTES];
181static uint8_t nonce_set = 0;
182
183/* Gives a nonce guaranteed to be different from previous ones.*/
184void new_nonce(uint8_t *nonce)
185{
186 if (nonce_set == 0) {
187 random_nonce(base_nonce);
188 nonce_set = 1;
189 }
190
191 increment_nonce(base_nonce);
192 memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
193}
194
195/* Create a request to peer.
196 * send_public_key and send_secret_key are the pub/secret keys of the sender.
197 * recv_public_key is public key of reciever.
198 * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
199 * Data represents the data we send with the request with length being the length of the data.
200 * request_id is the id of the request (32 = friend request, 254 = ping request).
201 *
202 * return -1 on failure.
203 * return the length of the created packet on success.
204 */
205int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
206 uint8_t *data, uint32_t length, uint8_t request_id)
207{
208 if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 +
209 crypto_box_MACBYTES)
210 return -1;
211
212 uint8_t nonce[crypto_box_NONCEBYTES];
213 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
214 memcpy(temp + 1, data, length);
215 temp[0] = request_id;
216 new_nonce(nonce);
217 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
218 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
219
220 if (len == -1)
221 return -1;
222
223 packet[0] = NET_PACKET_CRYPTO;
224 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
225 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
226 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
227
228 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
229}
230
231/* Puts the senders public key in the request in public_key, the data from the request
232 * in data if a friend or ping request was sent to us and returns the length of the data.
233 * packet is the request packet and length is its length.
234 *
235 * return -1 if not valid request.
236 */
237int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
238 uint8_t *request_id, uint8_t *packet, uint16_t length)
239{
240 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
241 length <= MAX_CRYPTO_REQUEST_SIZE) {
242 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
243 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
244 uint8_t nonce[crypto_box_NONCEBYTES];
245 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
246 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
247 int len1 = decrypt_data(public_key, self_secret_key, nonce,
248 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
249 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
250
251 if (len1 == -1 || len1 == 0)
252 return -1;
253
254 request_id[0] = temp[0];
255 --len1;
256 memcpy(data, temp + 1, len1);
257 return len1;
258 }
259 }
260
261 return -1;
262}
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
new file mode 100644
index 00000000..6b69f917
--- /dev/null
+++ b/toxcore/crypto_core.h
@@ -0,0 +1,142 @@
1/* crypto_core.h
2 *
3 * Functions for the core crypto.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23#ifndef CORE_CRYPTO_H
24#define CORE_CRYPTO_H
25
26#include "network.h"
27
28#ifndef VANILLA_NACL
29/* We use libsodium by default. */
30#include <sodium.h>
31#else
32#include <crypto_box.h>
33#include <randombytes.h>
34#include <crypto_hash_sha256.h>
35#include <crypto_hash_sha512.h>
36#include <crypto_verify_16.h>
37#include <crypto_verify_32.h>
38#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
39#endif
40
41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES)
42
43/* Use this instead of memcmp; not vulnerable to timing attacks.
44 returns 0 if both mem locations of length are equal,
45 return -1 if they are not. */
46int crypto_cmp(uint8_t *mem1, uint8_t *mem2, uint32_t length);
47
48/* return a random number.
49 *
50 * random_int for a 32bin int.
51 * random_64b for a 64bit int.
52 */
53uint32_t random_int(void);
54uint64_t random_64b(void);
55
56
57/* Encrypts plain of length length to encrypted of length + 16 using the
58 * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce.
59 *
60 * return -1 if there was a problem.
61 * return length of encrypted data if everything was fine.
62 */
63int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
64 uint8_t *plain, uint32_t length, uint8_t *encrypted);
65
66
67/* Decrypts encrypted of length length to plain of length length - 16 using the
68 * public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce.
69 *
70 * return -1 if there was a problem (decryption failed).
71 * return length of plain data if everything was fine.
72 */
73int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
74 uint8_t *encrypted, uint32_t length, uint8_t *plain);
75
76/* Fast encrypt/decrypt operations. Use if this is not a one-time communication.
77 encrypt_precompute does the shared-key generation once so it does not have
78 to be preformed on every encrypt/decrypt. */
79void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key);
80
81/* Encrypts plain of length length to encrypted of length + 16 using a
82 * secret key crypto_box_KEYBYTES big and a 24 byte nonce.
83 *
84 * return -1 if there was a problem.
85 * return length of encrypted data if everything was fine.
86 */
87int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted);
88
89/* Decrypts encrypted of length length to plain of length length - 16 using a
90 * secret key crypto_box_KEYBYTES big and a 24 byte nonce.
91 *
92 * return -1 if there was a problem (decryption failed).
93 * return length of plain data if everything was fine.
94 */
95int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain);
96
97/* Increment the given nonce by 1. */
98void increment_nonce(uint8_t *nonce);
99
100/* increment the given nonce by num */
101void increment_nonce_number(uint8_t *nonce, uint32_t num);
102
103/* Fill the given nonce with random bytes. */
104void random_nonce(uint8_t *nonce);
105
106/* Fill a key crypto_box_KEYBYTES big with random bytes */
107void new_symmetric_key(uint8_t *key);
108
109/*Gives a nonce guaranteed to be different from previous ones.*/
110void new_nonce(uint8_t *nonce);
111
112#define MAX_CRYPTO_REQUEST_SIZE 1024
113
114#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
115#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
116#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
117#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */
118#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */
119#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */
120
121/* Create a request to peer.
122 * send_public_key and send_secret_key are the pub/secret keys of the sender.
123 * recv_public_key is public key of reciever.
124 * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
125 * Data represents the data we send with the request with length being the length of the data.
126 * request_id is the id of the request (32 = friend request, 254 = ping request).
127 *
128 * return -1 on failure.
129 * return the length of the created packet on success.
130 */
131int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
132 uint8_t *data, uint32_t length, uint8_t request_id);
133
134/* puts the senders public key in the request in public_key, the data from the request
135 in data if a friend or ping request was sent to us and returns the length of the data.
136 packet is the request packet and length is its length
137 return -1 if not valid request. */
138int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
139 uint8_t *request_id, uint8_t *packet, uint16_t length);
140
141
142#endif
diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c
index 469ab02d..eb2a791c 100644
--- a/toxcore/friend_requests.c
+++ b/toxcore/friend_requests.c
@@ -37,10 +37,10 @@
37 */ 37 */
38int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) 38int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
39{ 39{
40 if (length + sizeof(nospam_num) > MAX_DATA_SIZE) 40 if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0)
41 return -1; 41 return -1;
42 42
43 uint8_t temp[MAX_DATA_SIZE]; 43 uint8_t temp[1 + sizeof(nospam_num) + length];
44 temp[0] = CRYPTO_PACKET_FRIEND_REQ; 44 temp[0] = CRYPTO_PACKET_FRIEND_REQ;
45 memcpy(temp + 1, &nospam_num, sizeof(nospam_num)); 45 memcpy(temp + 1, &nospam_num, sizeof(nospam_num));
46 memcpy(temp + 1 + sizeof(nospam_num), data, length); 46 memcpy(temp + 1 + sizeof(nospam_num), data, length);
@@ -50,7 +50,7 @@ int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nosp
50 if (friend_num == -1) 50 if (friend_num == -1)
51 return -1; 51 return -1;
52 52
53 int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length); 53 int num = send_onion_data(onion_c, friend_num, temp, sizeof(temp));
54 54
55 if (num <= 0) 55 if (num <= 0)
56 return -1; 56 return -1;
@@ -135,20 +135,17 @@ int remove_request_received(Friend_Requests *fr, uint8_t *client_id)
135 135
136static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) 136static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
137{ 137{
138 if (length == 0) 138 Friend_Requests *fr = object;
139
140 if (length <= 1 + sizeof(fr->nospam) || length > ONION_CLIENT_MAX_DATA_SIZE)
139 return 1; 141 return 1;
140 142
141 ++packet; 143 ++packet;
142 --length; 144 --length;
143 145
144 Friend_Requests *fr = object;
145
146 if (fr->handle_friendrequest_isset == 0) 146 if (fr->handle_friendrequest_isset == 0)
147 return 1; 147 return 1;
148 148
149 if (length <= sizeof(fr->nospam))
150 return 1;
151
152 if (request_received(fr, source_pubkey)) 149 if (request_received(fr, source_pubkey))
153 return 1; 150 return 1;
154 151
@@ -161,11 +158,12 @@ static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t
161 158
162 addto_receivedlist(fr, source_pubkey); 159 addto_receivedlist(fr, source_pubkey);
163 160
164 uint8_t message[length - 4 + 1]; 161 uint32_t message_len = length - sizeof(fr->nospam);
165 memcpy(message, packet + 4, length - 4); 162 uint8_t message[message_len + 1];
163 memcpy(message, packet + sizeof(fr->nospam), message_len);
166 message[sizeof(message) - 1] = 0; /* Be sure the message is null terminated. */ 164 message[sizeof(message) - 1] = 0; /* Be sure the message is null terminated. */
167 165
168 (*fr->handle_friendrequest)(fr->handle_friendrequest_object, source_pubkey, message, length - 4, 166 (*fr->handle_friendrequest)(fr->handle_friendrequest_object, source_pubkey, message, message_len,
169 fr->handle_friendrequest_userdata); 167 fr->handle_friendrequest_userdata);
170 return 0; 168 return 0;
171} 169}
diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h
index eab359f0..429ffbad 100644
--- a/toxcore/friend_requests.h
+++ b/toxcore/friend_requests.h
@@ -25,8 +25,8 @@
25#define FRIEND_REQUESTS_H 25#define FRIEND_REQUESTS_H
26 26
27#include "onion_client.h" 27#include "onion_client.h"
28#include "net_crypto.h"
29 28
29#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t)))
30 30
31typedef struct { 31typedef struct {
32 uint32_t nospam; 32 uint32_t nospam;
@@ -48,7 +48,8 @@ typedef struct {
48} Friend_Requests; 48} Friend_Requests;
49 49
50/* Try to send a friendrequest to peer with public_key. 50/* Try to send a friendrequest to peer with public_key.
51 * data is the data in the request and length is the length. 51 * data is the data in the request and length is the length.
52 * Maximum length of data is MAX_FRIEND_REQUEST_DATA_SIZE.
52 */ 53 */
53int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); 54int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
54/* Set and get the nospam variable used to prevent one type of friend request spam. */ 55/* Set and get the nospam variable used to prevent one type of friend request spam. */
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c
index de39331e..fbe76d16 100644
--- a/toxcore/group_chats.c
+++ b/toxcore/group_chats.c
@@ -26,12 +26,13 @@
26#include "config.h" 26#include "config.h"
27#endif 27#endif
28 28
29#include "group_chats.h" 29#include "DHT.h"
30#include "assoc.h" 30#include "assoc.h"
31#include "group_chats.h"
31#include "LAN_discovery.h" 32#include "LAN_discovery.h"
32#include "util.h" 33#include "util.h"
33 34
34#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES)) 35#define GROUPCHAT_MAXDATA_LENGTH (MAX_CRYPTO_REQUEST_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES))
35#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES) 36#define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES)
36 37
37#define GROUP_MAX_SENDNODES (GROUP_CLOSE_CONNECTIONS * 2) 38#define GROUP_MAX_SENDNODES (GROUP_CLOSE_CONNECTIONS * 2)
@@ -180,7 +181,7 @@ static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *publ
180 if (id_equal(chat->self_public_key, public_key)) 181 if (id_equal(chat->self_public_key, public_key))
181 return -1; 182 return -1;
182 183
183 uint8_t packet[MAX_DATA_SIZE]; 184 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
184 int len = create_request(chat->self_public_key, chat->self_secret_key, packet, public_key, data, length, request_id); 185 int len = create_request(chat->self_public_key, chat->self_secret_key, packet, public_key, data, length, request_id);
185 packet[0] = NET_PACKET_GROUP_CHATS; 186 packet[0] = NET_PACKET_GROUP_CHATS;
186 187
@@ -586,10 +587,10 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
586 587
587static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id) 588static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id)
588{ 589{
589 if (len + GROUP_DATA_MIN_SIZE > MAX_DATA_SIZE) /*NOTE: not the real maximum len.*/ 590 if (len + GROUP_DATA_MIN_SIZE > MAX_CRYPTO_REQUEST_SIZE) /*NOTE: not the real maximum len.*/
590 return 1; 591 return 1;
591 592
592 uint8_t packet[MAX_DATA_SIZE]; 593 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
593 ++chat->message_number; 594 ++chat->message_number;
594 595
595 if (chat->message_number == 0) 596 if (chat->message_number == 0)
@@ -615,11 +616,11 @@ static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t
615 616
616int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length) 617int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length)
617{ 618{
618 if (length > MAX_DATA_SIZE) 619 if (length > MAX_CRYPTO_REQUEST_SIZE)
619 return 1; 620 return 1;
620 621
621 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 622 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
622 uint8_t data[MAX_DATA_SIZE]; 623 uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
623 uint8_t number; 624 uint8_t number;
624 int len = handle_request(chat->self_public_key, chat->self_secret_key, public_key, data, &number, packet, length); 625 int len = handle_request(chat->self_public_key, chat->self_secret_key, public_key, data, &number, packet, length);
625 626
diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h
index f218fe42..d9da54a5 100644
--- a/toxcore/group_chats.h
+++ b/toxcore/group_chats.h
@@ -25,8 +25,6 @@
25#ifndef GROUP_CHATS_H 25#ifndef GROUP_CHATS_H
26#define GROUP_CHATS_H 26#define GROUP_CHATS_H
27 27
28#include "net_crypto.h"
29
30#define MAX_NICK_BYTES 128 28#define MAX_NICK_BYTES 128
31 29
32typedef struct { 30typedef struct {
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 17d2e8ff..875c639f 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -35,439 +35,1159 @@ static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection
35 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 35 return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
36} 36}
37 37
38/* Use this instead of memcmp; not vulnerable to timing attacks. */ 38/* return 0 if connection is dead.
39uint8_t crypto_iszero(uint8_t *mem, uint32_t length) 39 * return 1 if connection is alive.
40 */
41static int is_alive(uint8_t status)
40{ 42{
41 uint8_t check = 0; 43 if (status == CRYPTO_CONN_COOKIE_REQUESTING ||
42 uint32_t i; 44 status == CRYPTO_CONN_HANDSHAKE_SENT ||
43 45 status == CRYPTO_CONN_NOT_CONFIRMED ||
44 for (i = 0; i < length; ++i) { 46 status == CRYPTO_CONN_ESTABLISHED) {
45 check |= mem[i]; 47 return 1;
46 } 48 }
47 49
48 return check; // We return zero if mem is made out of zeroes. 50 return 0;
49} 51}
50 52
51/* Precomputes the shared key from their public_key and our secret_key. 53/* cookie timeout in seconds */
52 * This way we can avoid an expensive elliptic curve scalar multiply for each 54#define COOKIE_TIMEOUT 10
53 * encrypt/decrypt operation. 55#define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2)
54 * enc_key has to be crypto_box_BEFORENMBYTES bytes long. 56#define COOKIE_CONTENTS_LENGTH (sizeof(uint64_t) + COOKIE_DATA_LENGTH)
57#define COOKIE_LENGTH (crypto_box_NONCEBYTES + COOKIE_CONTENTS_LENGTH + crypto_box_MACBYTES)
58
59#define COOKIE_REQUEST_PLAIN_LENGTH (COOKIE_DATA_LENGTH + sizeof(uint64_t))
60#define COOKIE_REQUEST_LENGTH (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES)
61#define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + sizeof(uint64_t) + crypto_box_MACBYTES)
62
63/* Create a cookie request packet and put it in packet.
64 * dht_public_key is the dht public key of the other
65 *
66 * packet must be of size COOKIE_REQUEST_LENGTH or bigger.
67 *
68 * return -1 on failure.
69 * return COOKIE_REQUEST_LENGTH on success.
55 */ 70 */
56void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key) 71static int create_cookie_request(Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number,
72 uint8_t *shared_key)
57{ 73{
58 crypto_box_beforenm(enc_key, public_key, secret_key); 74 uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH];
75 uint8_t padding[crypto_box_PUBLICKEYBYTES] = {0};
76
77 memcpy(plain, c->self_public_key, crypto_box_PUBLICKEYBYTES);
78 memcpy(plain + crypto_box_PUBLICKEYBYTES, padding, crypto_box_PUBLICKEYBYTES);
79 memcpy(plain + (crypto_box_PUBLICKEYBYTES * 2), &number, sizeof(uint64_t));
80
81 DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key);
82 uint8_t nonce[crypto_box_NONCEBYTES];
83 new_nonce(nonce);
84 packet[0] = NET_PACKET_COOKIE_REQUEST;
85 memcpy(packet + 1, c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
86 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
87 int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
88 packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
89
90 if (len != COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES)
91 return -1;
92
93 return (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + len);
59} 94}
60 95
61/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ 96/* Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key
62int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 97 *
63 uint8_t *plain, uint32_t length, uint8_t *encrypted) 98 * return -1 on failure.
99 * return 0 on success.
100 */
101static int create_cookie(uint8_t *cookie, uint8_t *bytes, uint8_t *encryption_key)
64{ 102{
65 if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) 103 uint8_t contents[COOKIE_CONTENTS_LENGTH];
104 uint64_t temp_time = unix_time();
105 memcpy(contents, &temp_time, sizeof(temp_time));
106 memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
107 new_nonce(cookie);
108 int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + crypto_box_NONCEBYTES);
109
110 if (len != COOKIE_LENGTH - crypto_box_NONCEBYTES)
66 return -1; 111 return -1;
67 112
68 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; 113 return 0;
69 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES]; 114}
115
116/* Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key
117 *
118 * return -1 on failure.
119 * return 0 on success.
120 */
121static int open_cookie(uint8_t *bytes, uint8_t *cookie, uint8_t *encryption_key)
122{
123 uint8_t contents[COOKIE_CONTENTS_LENGTH];
124 int len = decrypt_data_symmetric(encryption_key, cookie, cookie + crypto_box_NONCEBYTES,
125 COOKIE_LENGTH - crypto_box_NONCEBYTES, contents);
70 126
71 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. 127 if (len != sizeof(contents))
128 return -1;
72 129
73 crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key); 130 uint64_t cookie_time;
131 memcpy(&cookie_time, contents, sizeof(cookie_time));
132 uint64_t temp_time = unix_time();
74 133
75 if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) 134 if (cookie_time + COOKIE_TIMEOUT < temp_time || temp_time < cookie_time)
76 return -1; 135 return -1;
77 136
78 /* Unpad the encrypted message. */ 137 memcpy(bytes, contents + sizeof(cookie_time), COOKIE_DATA_LENGTH);
79 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); 138 return 0;
80 return length + crypto_box_MACBYTES;
81} 139}
82 140
83/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ 141
84int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 142/* Create a cookie response packet and put it in packet.
85 uint8_t *encrypted, uint32_t length, uint8_t *plain) 143 * request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes.
144 * packet must be of size COOKIE_RESPONSE_LENGTH or bigger.
145 *
146 * return -1 on failure.
147 * return COOKIE_RESPONSE_LENGTH on success.
148 */
149static int create_cookie_response(Net_Crypto *c, uint8_t *packet, uint8_t *request_plain, uint8_t *shared_key,
150 uint8_t *dht_public_key)
86{ 151{
87 if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) 152 uint8_t cookie_plain[COOKIE_DATA_LENGTH];
153 memcpy(cookie_plain, request_plain, crypto_box_PUBLICKEYBYTES);
154 memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, dht_public_key, crypto_box_PUBLICKEYBYTES);
155 uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
156
157 if (create_cookie(plain, cookie_plain, c->secret_symmetric_key) != 0)
88 return -1; 158 return -1;
89 159
90 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; 160 memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
91 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0}; 161 packet[0] = NET_PACKET_COOKIE_RESPONSE;
162 new_nonce(packet + 1);
163 int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + crypto_box_NONCEBYTES);
164
165 if (len != COOKIE_RESPONSE_LENGTH - (1 + crypto_box_NONCEBYTES))
166 return -1;
92 167
93 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes. 168 return COOKIE_RESPONSE_LENGTH;
169}
94 170
95 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, 171/* Handle the cookie request packet of length length.
96 nonce, enc_key) == -1) 172 * Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH)
173 * Put the key used to decrypt the request into shared_key (of size crypto_box_BEFORENMBYTES) for use in the response.
174 *
175 * return -1 on failure.
176 * return 0 on success.
177 */
178static int handle_cookie_request(Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key,
179 uint8_t *packet, uint16_t length)
180{
181 if (length != COOKIE_REQUEST_LENGTH)
97 return -1; 182 return -1;
98 183
99 /* If decryption is successful the first crypto_box_ZEROBYTES of the message will be zero. 184 memcpy(dht_public_key, packet + 1, crypto_box_PUBLICKEYBYTES);
100 * Apparently memcmp should not be used so we do this instead: 185 DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key);
101 */ 186 int len = decrypt_data_symmetric(shared_key, packet + 1 + crypto_box_PUBLICKEYBYTES,
102 if (crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) 187 packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES,
188 request_plain);
189
190 if (len != COOKIE_REQUEST_PLAIN_LENGTH)
103 return -1; 191 return -1;
104 192
105 /* Unpad the plain message. */ 193 return 0;
106 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
107 return length - crypto_box_MACBYTES;
108} 194}
109 195
110int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 196/* Handle the cookie request packet (for raw UDP)
111 uint8_t *plain, uint32_t length, uint8_t *encrypted) 197 */
198static int udp_handle_cookie_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
112{ 199{
113 uint8_t k[crypto_box_BEFORENMBYTES]; 200 Net_Crypto *c = object;
114 encrypt_precompute(public_key, secret_key, k); 201 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
115 return encrypt_data_fast(k, nonce, plain, length, encrypted); 202 uint8_t shared_key[crypto_box_BEFORENMBYTES];
203 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
204
205 if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0)
206 return 1;
207
208 uint8_t data[COOKIE_RESPONSE_LENGTH];
209
210 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
211 return 1;
212
213 if ((uint32_t)sendpacket(c->dht->net, source, data, sizeof(data)) != sizeof(data))
214 return 1;
215
216 return 0;
116} 217}
117 218
118int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 219/* Handle the cookie request packet (for TCP)
119 uint8_t *encrypted, uint32_t length, uint8_t *plain) 220 */
221static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, uint8_t *packet,
222 uint32_t length)
120{ 223{
121 uint8_t k[crypto_box_BEFORENMBYTES]; 224 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
122 encrypt_precompute(public_key, secret_key, k); 225 uint8_t shared_key[crypto_box_BEFORENMBYTES];
123 return decrypt_data_fast(k, nonce, encrypted, length, plain); 226 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
227
228 if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0)
229 return -1;
230
231 uint8_t data[COOKIE_RESPONSE_LENGTH];
232
233 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
234 return -1;
235
236 if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1)
237 return -1;
238
239 return 0;
124} 240}
125 241
126int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted) 242/* Handle the cookie request packet (for TCP oob packets)
243 */
244static int tcp_oob_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t *dht_public_key,
245 uint8_t *packet, uint32_t length)
127{ 246{
128 if (length == 0) 247 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
248 uint8_t shared_key[crypto_box_BEFORENMBYTES];
249 uint8_t dht_public_key_temp[crypto_box_PUBLICKEYBYTES];
250
251 if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0)
252 return -1;
253
254 if (memcmp(dht_public_key, dht_public_key_temp, crypto_box_PUBLICKEYBYTES) != 0)
129 return -1; 255 return -1;
130 256
131 uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES]; 257 uint8_t data[COOKIE_RESPONSE_LENGTH];
132 uint8_t temp_encrypted[length + crypto_secretbox_MACBYTES + crypto_secretbox_BOXZEROBYTES]; 258
259 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
260 return -1;
133 261
134 memset(temp_plain, 0, crypto_secretbox_ZEROBYTES); 262 if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1)
135 memcpy(temp_plain + crypto_secretbox_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. 263 return -1;
136 264
137 crypto_secretbox(temp_encrypted, temp_plain, length + crypto_secretbox_ZEROBYTES, nonce, secret_key); 265 return 0;
138 /* Unpad the encrypted message. */
139 memcpy(encrypted, temp_encrypted + crypto_secretbox_BOXZEROBYTES, length + crypto_secretbox_MACBYTES);
140 return length + crypto_secretbox_MACBYTES;
141} 266}
142 267
143int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain) 268/* Handle a cookie response packet of length encrypted with shared_key.
269 * put the cookie in the response in cookie
270 *
271 * cookie must be of length COOKIE_LENGTH.
272 *
273 * return -1 on failure.
274 * return COOKIE_LENGTH on success.
275 */
276static int handle_cookie_response(uint8_t *cookie, uint64_t *number, uint8_t *packet, uint32_t length,
277 uint8_t *shared_key)
278{
279 if (length != COOKIE_RESPONSE_LENGTH)
280 return -1;
281
282 uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
283 int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
284 length - (1 + crypto_box_NONCEBYTES), plain);
285
286 if (len != sizeof(plain))
287 return -1;
288
289 memcpy(cookie, plain, COOKIE_LENGTH);
290 memcpy(number, plain + COOKIE_LENGTH, sizeof(uint64_t));
291 return COOKIE_LENGTH;
292}
293
294#define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH + crypto_box_MACBYTES)
295
296/* Create a handshake packet and put it in packet.
297 * cookie must be COOKIE_LENGTH bytes.
298 * packet must be of size HANDSHAKE_PACKET_LENGTH or bigger.
299 *
300 * return -1 on failure.
301 * return HANDSHAKE_PACKET_LENGTH on success.
302 */
303static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk,
304 uint8_t *peer_real_pk, uint8_t *peer_dht_pubkey)
305{
306 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
307 memcpy(plain, nonce, crypto_box_NONCEBYTES);
308 memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES);
309 crypto_hash_sha512(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, cookie, COOKIE_LENGTH);
310 uint8_t cookie_plain[COOKIE_DATA_LENGTH];
311 memcpy(cookie_plain, peer_real_pk, crypto_box_PUBLICKEYBYTES);
312 memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, peer_dht_pubkey, crypto_box_PUBLICKEYBYTES);
313
314 if (create_cookie(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, cookie_plain,
315 c->secret_symmetric_key) != 0)
316 return -1;
317
318 new_nonce(packet + 1 + COOKIE_LENGTH);
319 int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
320 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES);
321
322 if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES))
323 return -1;
324
325 packet[0] = NET_PACKET_CRYPTO_HS;
326 memcpy(packet + 1, cookie, COOKIE_LENGTH);
327
328 return HANDSHAKE_PACKET_LENGTH;
329}
330
331/* Handle a crypto handshake packet of length.
332 * put the nonce contained in the packet in nonce,
333 * the session public key in session_pk
334 * the real public key of the peer in peer_real_pk
335 * the dht public key of the peer in dht_public_key and
336 * the cookie inside the encrypted part of the packet in cookie.
337 *
338 * if expected_real_pk isn't NULL it denotes the real public key
339 * the packet should be from.
340 *
341 * nonce must be at least crypto_box_NONCEBYTES
342 * session_pk must be at least crypto_box_PUBLICKEYBYTES
343 * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES
344 * cookie must be at least COOKIE_LENGTH
345 *
346 * return -1 on failure.
347 * return 0 on success.
348 */
349static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
350 uint8_t *dht_public_key, uint8_t *cookie, uint8_t *packet, uint32_t length, uint8_t *expected_real_pk)
144{ 351{
145 if (length <= crypto_secretbox_BOXZEROBYTES) 352 if (length != HANDSHAKE_PACKET_LENGTH)
353 return -1;
354
355 uint8_t cookie_plain[COOKIE_DATA_LENGTH];
356
357 if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0)
146 return -1; 358 return -1;
147 359
148 uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES]; 360 if (expected_real_pk)
149 uint8_t temp_encrypted[length + crypto_secretbox_BOXZEROBYTES]; 361 if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0)
362 return -1;
363
364 uint8_t cookie_hash[crypto_hash_sha512_BYTES];
365 crypto_hash_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
150 366
151 memset(temp_plain, 0, crypto_secretbox_BOXZEROBYTES); 367 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
152 memcpy(temp_encrypted + crypto_secretbox_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes. 368 int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
369 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES,
370 HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain);
153 371
154 if (crypto_secretbox_open(temp_plain, temp_encrypted, length + crypto_secretbox_BOXZEROBYTES, nonce, secret_key) == -1) 372 if (len != sizeof(plain))
155 return -1; 373 return -1;
156 374
157 memcpy(plain, temp_plain + crypto_secretbox_ZEROBYTES, length - crypto_secretbox_MACBYTES); 375 if (memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, crypto_hash_sha512_BYTES) != 0)
158 return length - crypto_secretbox_MACBYTES; 376 return -1;
377
378 memcpy(nonce, plain, crypto_box_NONCEBYTES);
379 memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
380 memcpy(cookie, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, COOKIE_LENGTH);
381 memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES);
382 memcpy(dht_public_key, cookie_plain + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
383 return 0;
159} 384}
160 385
161/* Increment the given nonce by 1. */ 386
162void increment_nonce(uint8_t *nonce) 387static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connection_id)
163{ 388{
389 if (crypt_connection_id_not_valid(c, crypt_connection_id))
390 return 0;
391
392 return &c->crypto_connections[crypt_connection_id];
393}
394
395
396/* Sends a packet to the peer using the fastest route.
397 *
398 * return -1 on failure.
399 * return 0 on success.
400 */
401static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length)
402{
403//TODO TCP, etc...
404 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
405
406 if (conn == 0)
407 return -1;
408
409 int direct_send_attempt = 0;
410
411 //TODO: on bad networks, direct connections might not last indefinitely.
412 if (conn->ip_port.ip.family != 0) {
413 uint8_t direct_connected = 0;
414 crypto_connection_status(c, crypt_connection_id, &direct_connected);
415
416 if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
417 return 0;
418
419 //TODO: a better way of sending packets directly to confirm the others ip.
420 if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) {
421 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
422 direct_send_attempt = 1;
423 }
424
425 }
426
427 //TODO: spread packets over many relays, detect and kill bad relays.
164 uint32_t i; 428 uint32_t i;
165 429
166 for (i = 0; i < crypto_box_NONCEBYTES; ++i) { 430 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
167 ++nonce[i]; 431 if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
432 if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1)
433 return 0;
434 }
435 }
168 436
169 if (nonce[i] != 0) 437 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
170 break; 438 if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) {
439 if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1)
440 return 0;
441 }
442 }
443
444 if (direct_send_attempt) {
445 return 0;
171 } 446 }
447
448 return -1;
172} 449}
173 450
174#if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES 451/** START: Array Related functions **/
175/*if they no longer equal each other, this function must be split into two.*/ 452
176#error random_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES. 453
177#endif 454/* Return number of packets in array
178/* Fill the given nonce with random bytes. */ 455 * Note that holes are counted too.
179void random_nonce(uint8_t *nonce) 456 */
457static uint32_t num_packets_array(Packets_Array *array)
180{ 458{
181 randombytes(nonce, crypto_box_NONCEBYTES); 459 return array->buffer_end - array->buffer_start;
182} 460}
183 461
184/* Fill a key crypto_secretbox_KEYBYTES big with random bytes */ 462/* Add data with packet number to array.
185void new_symmetric_key(uint8_t *key) 463 *
464 * return -1 on failure.
465 * return 0 on success.
466 */
467static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data *data)
186{ 468{
187 randombytes(key, crypto_secretbox_KEYBYTES); 469 if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE)
470 return -1;
471
472 uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
473
474 if (array->buffer[num])
475 return -1;
476
477 Packet_Data *new_d = malloc(sizeof(Packet_Data));
478
479 if (new_d == NULL)
480 return -1;
481
482 memcpy(new_d, data, sizeof(Packet_Data));
483 array->buffer[num] = new_d;
484
485 if ((number - array->buffer_start) >= (array->buffer_end - array->buffer_start))
486 array->buffer_end = number + 1;
487
488 return 0;
188} 489}
189 490
190static uint8_t base_nonce[crypto_box_NONCEBYTES]; 491/* Get pointer of data with packet number.
191static uint8_t nonce_set = 0; 492 *
493 * return -1 on failure.
494 * return 0 if data at number is empty.
495 * return 1 if data pointer was put in data.
496 */
497static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t number)
498{
499 uint32_t num_spots = array->buffer_end - array->buffer_start;
500
501 if (array->buffer_end - number > num_spots || number - array->buffer_start >= num_spots)
502 return -1;
503
504 uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
192 505
193#if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES 506 if (!array->buffer[num])
194/*if they no longer equal each other, this function must be split into two.*/ 507 return 0;
195#error new_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES. 508
196#endif 509 *data = array->buffer[num];
197/* Gives a nonce guaranteed to be different from previous ones.*/ 510 return 1;
198void new_nonce(uint8_t *nonce) 511}
512
513/* Add data to end of array.
514 *
515 * return -1 on failure.
516 * return packet number on success.
517 */
518static int64_t add_data_end_of_buffer(Packets_Array *array, Packet_Data *data)
199{ 519{
200 if (nonce_set == 0) { 520 if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE)
201 random_nonce(base_nonce); 521 return -1;
202 nonce_set = 1; 522
203 } 523 Packet_Data *new_d = malloc(sizeof(Packet_Data));
524
525 if (new_d == NULL)
526 return -1;
204 527
205 increment_nonce(base_nonce); 528 memcpy(new_d, data, sizeof(Packet_Data));
206 memcpy(nonce, base_nonce, crypto_box_NONCEBYTES); 529 uint32_t id = array->buffer_end;
530 array->buffer[id % CRYPTO_PACKET_BUFFER_SIZE] = new_d;
531 ++array->buffer_end;
532 return id;
207} 533}
208 534
535/* Read data from begginning of array.
536 *
537 * return -1 on failure.
538 * return packet number on success.
539 */
540static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
541{
542 if (array->buffer_end == array->buffer_start)
543 return -1;
209 544
210/* return 0 if there is no received data in the buffer. 545 uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE;
211 * return -1 if the packet was discarded. 546
212 * return length of received data if successful. 547 if (!array->buffer[num])
548 return -1;
549
550 memcpy(data, array->buffer[num], sizeof(Packet_Data));
551 uint32_t id = array->buffer_start;
552 ++array->buffer_start;
553 free(array->buffer[num]);
554 array->buffer[num] = NULL;
555 return id;
556}
557
558/* Delete all packets in array before number (but not number)
559 *
560 * return -1 on failure.
561 * return 0 on success
213 */ 562 */
214int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data) 563static int clear_buffer_until(Packets_Array *array, uint32_t number)
215{ 564{
216 if (crypt_connection_id_not_valid(c, crypt_connection_id)) 565 uint32_t num_spots = array->buffer_end - array->buffer_start;
217 return 0;
218 566
219 if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED) 567 if (array->buffer_end - number >= num_spots || number - array->buffer_start > num_spots)
220 return 0; 568 return -1;
569
570 uint32_t i;
221 571
222 uint8_t temp_data[MAX_DATA_SIZE]; 572 for (i = array->buffer_start; i != number; ++i) {
223 int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data); 573 uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
224 574
225 if (length == 0) 575 if (array->buffer[num]) {
226 return 0; 576 free(array->buffer[num]);
577 array->buffer[num] = NULL;
578 }
579 }
580
581 array->buffer_start = i;
582 return 0;
583}
227 584
228 if (temp_data[0] != 3) 585/* Set array buffer end to number.
586 *
587 * return -1 on failure.
588 * return 0 on success.
589 */
590static int set_buffer_end(Packets_Array *array, uint32_t number)
591{
592 if ((number - array->buffer_start) > CRYPTO_PACKET_BUFFER_SIZE)
593 return -1;
594
595 if ((number - array->buffer_end) > CRYPTO_PACKET_BUFFER_SIZE)
229 return -1; 596 return -1;
230 597
231 int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, 598 array->buffer_end = number;
232 c->crypto_connections[crypt_connection_id].recv_nonce, 599 return 0;
233 temp_data + 1, length - 1, data); 600}
601
602/* Create a packet request packet from recv_array and send_buffer_end into
603 * data of length.
604 *
605 * return -1 on failure.
606 * return length of packet on success.
607 */
608static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array *recv_array, uint32_t send_buffer_end)
609{
610 if (length <= (sizeof(uint32_t) * 2))
611 return -1;
612
613 uint32_t recv_buffer_start = htonl(recv_array->buffer_start);
614 send_buffer_end = htonl(send_buffer_end);
615 memcpy(data, &recv_buffer_start, sizeof(uint32_t));
616 memcpy(data + sizeof(uint32_t), &send_buffer_end, sizeof(uint32_t));
617 data[sizeof(uint32_t) * 2] = PACKET_ID_REQUEST;
618
619 uint16_t cur_len = sizeof(uint32_t) * 2 + 1;
620
621 if (recv_array->buffer_start == recv_array->buffer_end)
622 return cur_len;
623
624 if (length <= cur_len)
625 return cur_len;
626
627 uint32_t i, n = 1;
628
629 for (i = recv_array->buffer_start; i != recv_array->buffer_end; ++i) {
630 uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
631
632 if (!recv_array->buffer[num]) {
633 data[cur_len] = n;
634 n = 0;
635 ++cur_len;
636
637 if (length <= cur_len)
638 return cur_len;
639
640 } else if (n == 255) {
641 data[cur_len] = 0;
642 n = 0;
643 ++cur_len;
644
645 if (length <= cur_len)
646 return cur_len;
647 }
234 648
235 if (len != -1) { 649 ++n;
236 increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce);
237 return len;
238 } 650 }
239 651
240 return -1; 652 return cur_len;
241} 653}
242 654
243/* returns the number of packet slots left in the sendbuffer. 655/* Handle a request data packet.
244 * return 0 if failure. 656 * Remove all the packets the other recieved from the array.
657 *
658 * return -1 on failure.
659 * return number of requested packets on success.
245 */ 660 */
246uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) 661static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint16_t length)
247{ 662{
248 if (crypt_connection_id_not_valid(c, crypt_connection_id)) 663 if (length < 1)
664 return -1;
665
666 if (data[0] != PACKET_ID_REQUEST)
667 return -1;
668
669 if (length == 1)
249 return 0; 670 return 0;
250 671
251 return num_free_sendqueue_slots(c->lossless_udp, c->crypto_connections[crypt_connection_id].number); 672 ++data;
673 --length;
674
675 uint32_t i, n = 1;
676 uint32_t requested = 0;
677
678 for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) {
679 if (length == 0)
680 break;
681
682 uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
683
684 if (n == data[0]) {
685 if (send_array->buffer[num]) {
686 send_array->buffer[num]->time = 0;
687 }
688
689 ++data;
690 --length;
691 n = 0;
692 ++requested;
693 } else {
694 free(send_array->buffer[num]);
695 send_array->buffer[num] = NULL;
696 }
697
698 if (n == 255) {
699 n = 1;
700
701 if (data[0] != 0)
702 return -1;
703
704 ++data;
705 --length;
706 } else {
707 ++n;
708 }
709 }
710
711 return requested;
252} 712}
253 713
254/* return 0 if data could not be put in packet queue. 714/** END: Array Related functions **/
255 * return 1 if data was put into the queue. 715
716#define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
717
718/* Creates and sends a data packet to the peer using the fastest route.
719 *
720 * return -1 on failure.
721 * return 0 on success.
256 */ 722 */
257int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) 723static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length)
258{ 724{
259 if (crypt_connection_id_not_valid(c, crypt_connection_id)) 725 if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE)
260 return 0; 726 return -1;
261 727
262 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) 728 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
263 return 0;
264 729
265 if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED) 730 if (conn == 0)
266 return 0; 731 return -1;
267 732
268 uint8_t temp_data[MAX_DATA_SIZE]; 733 uint8_t packet[1 + sizeof(uint16_t) + length + crypto_box_MACBYTES];
269 int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, 734 packet[0] = NET_PACKET_CRYPTO_DATA;
270 c->crypto_connections[crypt_connection_id].sent_nonce, 735 memcpy(packet + 1, conn->sent_nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t));
271 data, length, temp_data + 1); 736 int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
272 737
273 if (len == -1) 738 if (len + 1 + sizeof(uint16_t) != sizeof(packet))
274 return 0; 739 return -1;
275 740
276 temp_data[0] = 3; 741 increment_nonce(conn->sent_nonce);
742 return send_packet_to(c, crypt_connection_id, packet, sizeof(packet));
743}
277 744
278 if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) 745/* Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
279 return 0; 746 *
747 * return -1 on failure.
748 * return 0 on success.
749 */
750static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
751 uint8_t *data, uint32_t length)
752{
753 num = htonl(num);
754 buffer_start = htonl(buffer_start);
755 uint8_t packet[sizeof(uint32_t) + sizeof(uint32_t) + length];
756 memcpy(packet, &buffer_start, sizeof(uint32_t));
757 memcpy(packet + sizeof(uint32_t), &num, sizeof(uint32_t));
758 memcpy(packet + (sizeof(uint32_t) * 2), data, length);
759
760 return send_data_packet(c, crypt_connection_id, packet, sizeof(packet));
761}
280 762
281 increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce); 763/* return -1 if data could not be put in packet queue.
282 return 1; 764 * return positive packet number if data was put into the queue.
765 */
766static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
767{
768 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
769 return -1;
770
771 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
772
773 if (conn == 0)
774 return -1;
775
776 Packet_Data dt;
777 dt.time = current_time_monotonic();
778 dt.length = length;
779 memcpy(dt.data, data, length);
780 int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
781
782 if (packet_num == -1)
783 return -1;
784
785 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0)
786 fprintf(stderr, "send_data_packet failed\n");
787
788 return packet_num;
789}
790
791/* Get the lowest 2 bytes from the nonce and convert
792 * them to host byte format before returning them.
793 */
794static uint16_t get_nonce_uint16(uint8_t *nonce)
795{
796 uint16_t num;
797 memcpy(&num, nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t));
798 return ntohs(num);
283} 799}
284 800
285/* Create a request to peer. 801#define DATA_NUM_THRESHOLD 21845
286 * send_public_key and send_secret_key are the pub/secret keys of the sender. 802
287 * recv_public_key is public key of reciever. 803/* Handle a data packet.
288 * packet must be an array of MAX_DATA_SIZE big. 804 * Decrypt packet of length and put it into data.
289 * Data represents the data we send with the request with length being the length of the data. 805 * data must be at least MAX_DATA_DATA_PACKET_SIZE big.
290 * request_id is the id of the request (32 = friend request, 254 = ping request).
291 * 806 *
292 * return -1 on failure. 807 * return -1 on failure.
293 * return the length of the created packet on success. 808 * return length of data on success.
294 */ 809 */
295int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, 810static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint8_t *packet, uint16_t length)
296 uint8_t *data, uint32_t length, uint8_t request_id)
297{ 811{
298 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES) 812 if (length <= (1 + sizeof(uint16_t) + crypto_box_MACBYTES) || length > MAX_CRYPTO_PACKET_SIZE)
813 return -1;
814
815 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
816
817 if (conn == 0)
299 return -1; 818 return -1;
300 819
301 uint8_t nonce[crypto_box_NONCEBYTES]; 820 uint8_t nonce[crypto_box_NONCEBYTES];
302 uint8_t temp[MAX_DATA_SIZE]; 821 memcpy(nonce, conn->recv_nonce, crypto_box_NONCEBYTES);
303 memcpy(temp + 1, data, length); 822 uint16_t num_cur_nonce = get_nonce_uint16(nonce);
304 temp[0] = request_id; 823 uint16_t num;
305 new_nonce(nonce); 824 memcpy(&num, packet + 1, sizeof(uint16_t));
306 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, 825 num = ntohs(num);
307 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 826 uint16_t diff = num - num_cur_nonce;
827 increment_nonce_number(nonce, diff);
828 int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
829 length - (1 + sizeof(uint16_t)), data);
830
831 if ((unsigned int)len != length - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
832 return -1;
308 833
309 if (len == -1) 834 if (diff > DATA_NUM_THRESHOLD * 2) {
835 increment_nonce_number(conn->recv_nonce, DATA_NUM_THRESHOLD);
836 }
837
838 return len;
839}
840
841/* Send a request packet.
842 *
843 * return -1 on failure.
844 * return 0 on success.
845 */
846static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
847{
848 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
849
850 if (conn == 0)
310 return -1; 851 return -1;
311 852
312 packet[0] = NET_PACKET_CRYPTO; 853 uint8_t packet[MAX_DATA_DATA_PACKET_SIZE];
313 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); 854 int len = generate_request_packet(packet, sizeof(packet), &conn->recv_array, conn->send_array.buffer_end);
314 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
315 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
316 855
317 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; 856 if (len == -1)
857 return -1;
858
859 return send_data_packet(c, crypt_connection_id, packet, len);
318} 860}
319 861
320/* Puts the senders public key in the request in public_key, the data from the request 862/* Send up to max num previously requested data packets.
321 * in data if a friend or ping request was sent to us and returns the length of the data.
322 * packet is the request packet and length is its length.
323 * 863 *
324 * return -1 if not valid request. 864 * return -1 on failure.
865 * return number of packets sent on success.
325 */ 866 */
326int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, 867static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num)
327 uint8_t *request_id, uint8_t *packet, uint16_t length)
328{ 868{
329 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES && 869 if (max_num == 0)
330 length <= MAX_DATA_SIZE) { 870 return -1;
331 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
332 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
333 uint8_t nonce[crypto_box_NONCEBYTES];
334 uint8_t temp[MAX_DATA_SIZE];
335 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
336 int len1 = decrypt_data(public_key, self_secret_key, nonce,
337 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
338 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
339 871
340 if (len1 == -1 || len1 == 0) 872 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
341 return -1; 873
874 if (conn == 0)
875 return -1;
876
877 uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array);
342 878
343 request_id[0] = temp[0]; 879 for (i = 0; i < array_size; ++i) {
344 --len1; 880 Packet_Data *dt;
345 memcpy(data, temp + 1, len1); 881 uint32_t packet_num = (i + conn->send_array.buffer_start);
346 return len1; 882 int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
883
884 if (ret == -1) {
885 return -1;
886 } else if (ret == 0) {
887 continue;
888 }
889
890 if (dt->time != 0) {
891 continue;
347 } 892 }
893
894 dt->time = current_time_monotonic();
895
896 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
897 dt->length) == 0)
898 ++num_sent;
899
900 if (num_sent >= max_num)
901 break;
348 } 902 }
349 903
350 return -1; 904 return num_sent;
351} 905}
352 906
353void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object) 907
908/* Add a new temp packet to send repeatedly.
909 *
910 * return -1 on failure.
911 * return 0 on success.
912 */
913static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length)
354{ 914{
355 c->cryptopackethandlers[byte].function = cb; 915 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
356 c->cryptopackethandlers[byte].object = object; 916 return -1;
917
918 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
919
920 if (conn == 0)
921 return -1;
922
923 uint8_t *temp_packet = malloc(length);
924
925 if (temp_packet == 0)
926 return -1;
927
928 if (conn->temp_packet)
929 free(conn->temp_packet);
930
931 memcpy(temp_packet, packet, length);
932 conn->temp_packet = temp_packet;
933 conn->temp_packet_length = length;
934 conn->temp_packet_sent_time = 0;
935 conn->temp_packet_num_sent = 0;
936 return 0;
357} 937}
358 938
359static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) 939/* Clear the temp packet.
940 *
941 * return -1 on failure.
942 * return 0 on success.
943 */
944static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id)
360{ 945{
361 DHT *dht = object; 946 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
362 947
363 if (packet[0] == NET_PACKET_CRYPTO) { 948 if (conn == 0)
364 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || 949 return -1;
365 length > MAX_DATA_SIZE + crypto_box_MACBYTES)
366 return 1;
367 950
368 if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. 951 if (conn->temp_packet)
369 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 952 free(conn->temp_packet);
370 uint8_t data[MAX_DATA_SIZE];
371 uint8_t number;
372 int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
373 953
374 if (len == -1 || len == 0) 954 conn->temp_packet = 0;
375 return 1; 955 conn->temp_packet_length = 0;
956 conn->temp_packet_sent_time = 0;
957 conn->temp_packet_num_sent = 0;
958 return 0;
959}
376 960
377 if (!dht->c->cryptopackethandlers[number].function) return 1;
378 961
379 return dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, 962/* Send the temp packet.
380 data, len); 963 *
964 * return -1 on failure.
965 * return 0 on success.
966 */
967static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
968{
969 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
381 970
382 } else { /* If request is not for us, try routing it. */ 971 if (conn == 0)
383 int retval = route_packet(dht, packet + 1, packet, length); 972 return -1;
384 973
385 if ((unsigned int)retval == length) 974 if (!conn->temp_packet)
386 return 0; 975 return -1;
387 }
388 }
389 976
390 return 1; 977 if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0)
978 return -1;
979
980 conn->temp_packet_sent_time = current_time_monotonic();
981 ++conn->temp_packet_num_sent;
982 return 0;
391} 983}
392 984
393/* Send a crypto handshake packet containing an encrypted secret nonce and session public key 985/* Create a handshake packet and set it as a temp packet.
394 * to peer with connection_id and public_key. 986 * cookie must be COOKIE_LENGTH.
395 * The packet is encrypted with a random nonce which is sent in plain text with the packet. 987 *
988 * return -1 on failure.
989 * return 0 on success.
396 */ 990 */
397static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, 991static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, uint8_t *cookie, uint8_t *dht_public_key)
398 uint8_t *session_key)
399{ 992{
400 uint8_t temp_data[MAX_DATA_SIZE]; 993 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
401 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
402 uint8_t nonce[crypto_box_NONCEBYTES];
403 994
404 new_nonce(nonce); 995 if (conn == 0)
405 memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); 996 return -1;
406 memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);
407 997
408 int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 998 uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH];
409 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
410 999
411 if (len == -1) 1000 if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionpublic_key,
412 return 0; 1001 conn->public_key, dht_public_key) != sizeof(handshake_packet))
1002 return -1;
1003
1004 if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0)
1005 return -1;
413 1006
414 temp_data[0] = 2; 1007 send_temp_packet(c, crypt_connection_id);
415 memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); 1008 return 0;
416 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
417 return write_packet(c->lossless_udp, connection_id, temp_data,
418 len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
419} 1009}
420 1010
421/* Extract secret nonce, session public key and public_key from a packet(data) with length length. 1011/* Send a kill packet.
422 * 1012 *
423 * return 1 if successful. 1013 * return -1 on failure.
424 * return 0 if failure. 1014 * return 0 on success.
425 */ 1015 */
426static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, 1016static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
427 uint8_t *session_key, uint8_t *data, uint16_t length)
428{ 1017{
429 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); 1018 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
430 1019
431 if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES 1020 if (conn == 0)
432 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) { 1021 return -1;
433 return 0; 1022
1023 uint8_t kill_packet = PACKET_ID_KILL;
1024 return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end,
1025 &kill_packet, sizeof(kill_packet));
1026}
1027
1028/* Handle a recieved data packet.
1029 *
1030 * return -1 on failure.
1031 * return 0 on success.
1032 */
1033static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length)
1034{
1035 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
1036 return -1;
1037
1038 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1039
1040 if (conn == 0)
1041 return -1;
1042
1043 uint8_t data[MAX_DATA_DATA_PACKET_SIZE];
1044 int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
1045
1046 if (len <= (int)(sizeof(uint32_t) * 2))
1047 return -1;
1048
1049 uint32_t buffer_start, num;
1050 memcpy(&buffer_start, data, sizeof(uint32_t));
1051 memcpy(&num, data + sizeof(uint32_t), sizeof(uint32_t));
1052 buffer_start = ntohl(buffer_start);
1053 num = ntohl(num);
1054
1055 if (buffer_start != conn->send_array.buffer_start && clear_buffer_until(&conn->send_array, buffer_start) != 0)
1056 return -1;
1057
1058 uint8_t *real_data = data + (sizeof(uint32_t) * 2);
1059 uint16_t real_length = len - (sizeof(uint32_t) * 2);
1060
1061 while (real_data[0] == 0) { /* Remove Padding */
1062 ++real_data;
1063 --real_length;
1064
1065 if (real_length == 0)
1066 return -1;
434 } 1067 }
435 1068
436 if (data[0] != 2) 1069 if (real_data[0] == PACKET_ID_REQUEST) {
1070 int requested = handle_request_packet(&conn->send_array, real_data, real_length);
1071
1072 if (requested == -1) {
1073 return -1;
1074 } else {
1075 //TODO?
1076 }
1077
1078 set_buffer_end(&conn->recv_array, num);
1079 } else if (real_data[0] == PACKET_ID_KILL) {
1080 conn->killed = 1;
437 return 0; 1081 return 0;
1082 } else {
1083 Packet_Data dt;
1084 dt.time = current_time_monotonic();
1085 dt.length = real_length;
1086 memcpy(dt.data, real_data, real_length);
438 1087
439 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 1088 if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0)
1089 return -1;
440 1090
441 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); 1091 while (read_data_beg_buffer(&conn->recv_array, &dt) != -1) {
1092 if (conn->connection_data_callback)
1093 conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data,
1094 dt.length);
1095 }
442 1096
443 int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, 1097 /* Packet counter. */
444 data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, 1098 ++conn->packet_counter;
445 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); 1099 }
446 1100
447 if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) 1101 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
448 return 0; 1102 if (conn->connection_status_callback)
1103 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
449 1104
450 memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); 1105 clear_temp_packet(c, crypt_connection_id);
451 memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); 1106 conn->status = CRYPTO_CONN_ESTABLISHED;
452 return 1; 1107 }
1108
1109 return 0;
453} 1110}
454 1111
455/* Get crypto connection id from public key of peer. 1112/* Handle a packet that was recieved for the connection.
456 * 1113 *
457 * return -1 if there are no connections like we are looking for. 1114 * return -1 on failure.
458 * return id if it found it. 1115 * return 0 on success.
459 */ 1116 */
460static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) 1117static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length)
461{ 1118{
462 uint32_t i; 1119 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1120 return -1;
463 1121
464 for (i = 0; i < c->crypto_connections_length; ++i) { 1122 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
465 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) 1123
466 if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) 1124 if (conn == 0)
467 return i; 1125 return -1;
1126
1127 switch (packet[0]) {
1128 case NET_PACKET_COOKIE_RESPONSE: {
1129 if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING)
1130 return -1;
1131
1132 uint8_t cookie[COOKIE_LENGTH];
1133 uint64_t number;
1134
1135 if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie))
1136 return -1;
1137
1138 if (number != conn->cookie_request_number)
1139 return -1;
1140
1141 if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0)
1142 return -1;
1143
1144 conn->status = CRYPTO_CONN_HANDSHAKE_SENT;
1145 return 0;
1146 }
1147
1148 case NET_PACKET_CRYPTO_HS: {
1149 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT) {
1150 uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES];
1151 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
1152 uint8_t cookie[COOKIE_LENGTH];
1153
1154 if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie,
1155 packet, length, conn->public_key) != 0)
1156 return -1;
1157
1158 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1159
1160 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1161 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1162 return -1;
1163 }
1164
1165 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1166 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1167 set_connection_dht_public_key(c, crypt_connection_id, dht_public_key, current_time_monotonic());
1168 } else {
1169 return -1;
1170 }
1171
1172 return 0;
1173 }
1174
1175 case NET_PACKET_CRYPTO_DATA: {
1176 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) {
1177 return handle_data_packet_helper(c, crypt_connection_id, packet, length);
1178 } else {
1179 return -1;
1180 }
1181
1182 return 0;
1183 }
1184
1185 default: {
1186 return -1;
1187 }
468 } 1188 }
469 1189
470 return -1; 1190 return 0;
471} 1191}
472 1192
473/* Set the size of the friend list to numfriends. 1193/* Set the size of the friend list to numfriends.
@@ -492,326 +1212,1100 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
492 return 0; 1212 return 0;
493} 1213}
494 1214
495/* Start a secure connection with other peer who has public_key and ip_port. 1215
1216/* Create a new empty crypto connection.
496 * 1217 *
497 * return -1 if failure. 1218 * return -1 on failure.
498 * return crypt_connection_id of the initialized connection if everything went well. 1219 * return connection id on success.
499 */ 1220 */
500int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) 1221static int create_crypto_connection(Net_Crypto *c)
501{ 1222{
502 uint32_t i; 1223 uint32_t i;
503 int id_existing = getcryptconnection_id(c, public_key);
504 1224
505 if (id_existing != -1) { 1225 for (i = 0; i < c->crypto_connections_length; ++i) {
506 IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id_existing].number); 1226 if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION)
507 1227 return i;
508 if (ipport_equal(&c_ip, &ip_port))
509 return -1;
510 } 1228 }
511 1229
512 if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 1230 if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1)
513 || c->crypto_connections == NULL)
514 return -1; 1231 return -1;
515 1232
516 memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); 1233 memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
517 c->crypto_connections[c->crypto_connections_length].number = ~0; 1234 int id = c->crypto_connections_length;
1235 ++c->crypto_connections_length;
1236 return id;
1237}
518 1238
519 for (i = 0; i <= c->crypto_connections_length; ++i) { 1239/* Wipe a crypto connection.
520 if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { 1240 *
521 int id_new = new_connection(c->lossless_udp, ip_port); 1241 * return -1 on failure.
1242 * return 0 on success.
1243 */
1244static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
1245{
1246 if (crypt_connection_id_not_valid(c, crypt_connection_id))
1247 return -1;
522 1248
523 if (id_new == -1) 1249 uint32_t i;
524 return -1; 1250 memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection));
525 1251
526 c->crypto_connections[i].number = id_new; 1252 for (i = c->crypto_connections_length; i != 0; --i) {
527 c->crypto_connections[i].status = CRYPTO_CONN_HANDSHAKE_SENT; 1253 if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION)
528 random_nonce(c->crypto_connections[i].recv_nonce); 1254 break;
529 memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); 1255 }
530 crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key);
531 c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT;
532 1256
533 if (c->crypto_connections_length == i) 1257 if (c->crypto_connections_length != i) {
534 ++c->crypto_connections_length; 1258 c->crypto_connections_length = i;
1259 realloc_cryptoconnection(c, c->crypto_connections_length);
1260 }
535 1261
536 if (send_cryptohandshake(c, id_new, public_key, c->crypto_connections[i].recv_nonce, 1262 return 0;
537 c->crypto_connections[i].sessionpublic_key) == 1) { 1263}
538 increment_nonce(c->crypto_connections[i].recv_nonce); 1264
1265/* Get crypto connection id from public key of peer.
1266 *
1267 * return -1 if there are no connections like we are looking for.
1268 * return id if it found it.
1269 */
1270static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key)
1271{
1272 uint32_t i;
1273
1274 for (i = 0; i < c->crypto_connections_length; ++i) {
1275 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION)
1276 if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
539 return i; 1277 return i;
540 } 1278 }
541 1279
542 return -1; /* This should never happen. */ 1280 return -1;
543 } 1281}
1282
1283/* Get crypto connection id from public key of peer.
1284 *
1285 * return -1 if there are no connections like we are looking for.
1286 * return id if it found it.
1287 */
1288static int getcryptconnection_id_dht_pubkey(Net_Crypto *c, uint8_t *dht_public_key)
1289{
1290 uint32_t i;
1291
1292 for (i = 0; i < c->crypto_connections_length; ++i) {
1293 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set)
1294 if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1295 return i;
544 } 1296 }
545 1297
546 return -1; 1298 return -1;
547} 1299}
548 1300
549/* Handle an incoming connection. 1301/* Add a source to the crypto connection.
1302 * This is to be used only when we have recieved a packet from that source.
550 * 1303 *
551 * return -1 if no crypto inbound connection. 1304 * return -1 on failure.
552 * return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection. 1305 * return positive number on success.
1306 * 0 if source was a direct UDP connection.
1307 * TODO
1308 */
1309static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source)
1310{
1311 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1312
1313 if (conn == 0)
1314 return -1;
1315
1316 if (source.ip.family == AF_INET || source.ip.family == AF_INET6) {
1317 conn->ip_port = source;
1318 conn->direct_lastrecv_time = current_time_monotonic();
1319 return 0;
1320 }
1321
1322 return -1;
1323}
1324
1325
1326/* Set function to be called when someone requests a new connection to us.
553 * 1327 *
554 * Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce 1328 * The set function should return -1 on failure and 0 on success.
555 * and the session public key for the connection in session_key. 1329 *
556 * to accept it see: accept_crypto_inbound(...). 1330 * n_c is only valid for the duration of the function call.
557 * to refuse it just call kill_connection(...) on the connection id.
558 */ 1331 */
559int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) 1332void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
1333 void *object)
560{ 1334{
561 while (1) { 1335 c->new_connection_callback = new_connection_callback;
562 int incoming_con = incoming_connection(c->lossless_udp, 1); 1336 c->new_connection_callback_object = object;
1337}
563 1338
564 if (incoming_con != -1) { 1339/* Handle a handshake packet by someone who wants to initiate a new connection with us.
565 if (is_connected(c->lossless_udp, incoming_con) == LUDP_TIMED_OUT) { 1340 * This calls the callback set by new_connection_handler() if the handshake is ok.
566 kill_connection(c->lossless_udp, incoming_con); 1341 *
567 continue; 1342 * return -1 on failure.
568 } 1343 * return 0 on success.
1344 */
1345static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, uint8_t *data, uint16_t length)
1346{
1347 New_Connection n_c;
1348 n_c.cookie = malloc(COOKIE_LENGTH);
569 1349
570 if (id_packet(c->lossless_udp, incoming_con) == 2) { 1350 if (n_c.cookie == NULL)
571 uint8_t temp_data[MAX_DATA_SIZE]; 1351 return -1;
572 uint16_t len = read_packet_silent(c->lossless_udp, incoming_con, temp_data);
573 1352
574 if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { 1353 n_c.source = source;
575 return incoming_con; 1354 n_c.cookie_length = COOKIE_LENGTH;
576 } else { 1355
577 kill_connection(c->lossless_udp, incoming_con); 1356 if (handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
578 } 1357 n_c.cookie, data, length, 0) != 0) {
579 } else { 1358 free(n_c.cookie);
580 kill_connection(c->lossless_udp, incoming_con); 1359 return -1;
1360 }
1361
1362 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key);
1363
1364 if (crypt_connection_id != -1) {
1365 int ret = -1;
1366 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1367
1368 if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) {
1369 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES);
1370 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1371 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1372
1373 crypto_connection_add_source(c, crypt_connection_id, source);
1374
1375 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
1376 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1377 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1378 set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key, current_time_monotonic());
1379 ret = 0;
581 } 1380 }
582 } else {
583 break;
584 } 1381 }
1382
1383 free(n_c.cookie);
1384 return ret;
585 } 1385 }
586 1386
587 return -1; 1387 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
1388 free(n_c.cookie);
1389 return ret;
588} 1390}
589 1391
590/* Kill a crypto connection. 1392/* Accept a crypto connection.
591 * 1393 *
592 * return 0 if killed successfully. 1394 * return -1 on failure.
593 * return 1 if there was a problem. 1395 * return connection id on success.
594 */ 1396 */
595int crypto_kill(Net_Crypto *c, int crypt_connection_id) 1397int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
596{ 1398{
597 if (crypt_connection_id_not_valid(c, crypt_connection_id)) 1399 if (getcryptconnection_id(c, n_c->public_key) != -1)
598 return 1; 1400 return -1;
1401
1402 int crypt_connection_id = create_crypto_connection(c);
1403
1404 if (crypt_connection_id == -1)
1405 return -1;
599 1406
600 if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_NO_CONNECTION) { 1407 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
601 c->crypto_connections[crypt_connection_id].status = CRYPTO_CONN_NO_CONNECTION;
602 kill_connection(c->lossless_udp, c->crypto_connections[crypt_connection_id].number);
603 memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection));
604 c->crypto_connections[crypt_connection_id].number = ~0;
605 uint32_t i;
606 1408
607 for (i = c->crypto_connections_length; i != 0; --i) { 1409 if (conn == 0)
608 if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION) 1410 return -1;
609 break; 1411
1412 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
1413 memcpy(conn->recv_nonce, n_c->recv_nonce, crypto_box_NONCEBYTES);
1414 memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1415 random_nonce(conn->sent_nonce);
1416 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1417 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1418
1419 if (n_c->cookie_length != COOKIE_LENGTH)
1420 return -1;
1421
1422 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0)
1423 return -1;
1424
1425 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1426 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1427 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic());
1428 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1429 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
1430 return crypt_connection_id;
1431}
1432
1433/* Create a crypto connection.
1434 * If one to that real public key already exists, return it.
1435 *
1436 * return -1 on failure.
1437 * return connection id on success.
1438 */
1439int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key)
1440{
1441 int crypt_connection_id = getcryptconnection_id(c, real_public_key);
1442
1443 if (crypt_connection_id != -1)
1444 return crypt_connection_id;
1445
1446 crypt_connection_id = create_crypto_connection(c);
1447
1448 if (crypt_connection_id == -1)
1449 return -1;
1450
1451 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1452
1453 if (conn == 0)
1454 return -1;
1455
1456 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
1457 random_nonce(conn->sent_nonce);
1458 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1459 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1460 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1461 return crypt_connection_id;
1462}
1463
1464/* Disconnect peer from all associated TCP connections.
1465 *
1466 * return -1 on failure.
1467 * return 0 on success.
1468 */
1469static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1470{
1471 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1472
1473 if (conn == 0)
1474 return -1;
1475
1476 uint32_t i;
1477
1478 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1479 if (conn->status_tcp[i] != STATUS_TCP_NULL) {
1480 send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
1481 conn->status_tcp[i] = STATUS_TCP_NULL;
1482 conn->con_number_tcp[i] = 0;
610 } 1483 }
1484 }
611 1485
612 if (c->crypto_connections_length != i) { 1486 return 0;
613 c->crypto_connections_length = i; 1487}
614 realloc_cryptoconnection(c, c->crypto_connections_length); 1488
1489/* Connect peer to all associated TCP connections.
1490 *
1491 * return -1 on failure.
1492 * return 0 on success.
1493 */
1494static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1495{
1496 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1497
1498 if (conn == 0)
1499 return -1;
1500
1501 uint32_t i;
1502
1503 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1504 if (c->tcp_connections[i] == NULL)
1505 continue;
1506
1507 //TODO check function return?
1508 send_routing_request(c->tcp_connections[i], conn->dht_public_key);
1509 }
1510
1511 return 0;
1512}
1513
1514/* Copy friends DHT public key into dht_key.
1515 *
1516 * return 0 on failure (no key copied).
1517 * return timestamp on success (key copied).
1518 */
1519uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
1520{
1521 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1522
1523 if (conn == 0)
1524 return 0;
1525
1526 if (conn->dht_public_key_set == 0)
1527 return 0;
1528
1529 memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES);
1530 return conn->dht_public_key_timestamp;
1531}
1532
1533
1534/* Set the DHT public key of the crypto connection.
1535 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
1536 * the other peer.
1537 *
1538 * return -1 on failure.
1539 * return 0 on success.
1540 */
1541int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp)
1542{
1543 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1544
1545 if (conn == 0)
1546 return -1;
1547
1548 if (timestamp <= conn->dht_public_key_timestamp)
1549 return -1;
1550
1551 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1552 return -1;
1553
1554 if (conn->dht_public_key_set == 1) {
1555 disconnect_peer_tcp(c, crypt_connection_id);
1556 }
1557
1558 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1559 conn->dht_public_key_set = 1;
1560 conn->dht_public_key_timestamp = timestamp;
1561
1562 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1563 conn->cookie_request_number = random_64b();
1564 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1565
1566 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1567 conn->shared_key) != sizeof(cookie_request))
1568 return -1;
1569
1570 if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0)
1571 return -1;
1572 }//TODO
1573
1574 connect_peer_tcp(c, crypt_connection_id);
1575 return 0;
1576}
1577
1578/* Set the direct ip of the crypto connection.
1579 *
1580 * return -1 on failure.
1581 * return 0 on success.
1582 */
1583int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1584{
1585 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1586
1587 if (conn == 0)
1588 return -1;
1589
1590 if (!ipport_equal(&ip_port, &conn->ip_port)) {
1591 conn->ip_port = ip_port;
1592 conn->direct_lastrecv_time = 0;
1593 return 0;
1594 }
1595
1596 return -1;
1597}
1598
1599static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key)
1600{
1601 TCP_Client_Connection *TCP_con = object;
1602 Net_Crypto *c = TCP_con->net_crypto_pointer;
1603
1604 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1605
1606 if (crypt_connection_id == -1)
1607 return -1;
1608
1609 set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id);
1610
1611 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1612
1613 if (conn == 0)
1614 return -1;
1615
1616 uint32_t location = TCP_con->net_crypto_location;
1617
1618 if (location >= MAX_TCP_CONNECTIONS)
1619 return -1;
1620
1621 if (c->tcp_connections[location] != TCP_con)
1622 return -1;
1623
1624 conn->con_number_tcp[location] = connection_id;
1625 uint32_t i;
1626
1627 for (i = 0; i < conn->num_tcp_relays; ++i) {
1628 if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) {
1629 conn->status_tcp[location] = STATUS_TCP_INVISIBLE;
1630 return 0;
1631 }
1632 }
1633
1634 conn->status_tcp[location] = STATUS_TCP_OFFLINE;
1635 return 0;
1636}
1637
1638static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
1639{
1640 TCP_Client_Connection *TCP_con = object;
1641 Net_Crypto *c = TCP_con->net_crypto_pointer;
1642
1643 Crypto_Connection *conn = get_crypto_connection(c, number);
1644
1645 if (conn == 0)
1646 return -1;
1647
1648 uint32_t location = TCP_con->net_crypto_location;
1649
1650 if (location >= MAX_TCP_CONNECTIONS)
1651 return -1;
1652
1653 if (c->tcp_connections[location] != TCP_con)
1654 return -1;
1655
1656 if (status == 1) {
1657 conn->status_tcp[location] = STATUS_TCP_OFFLINE;
1658 } else if (status == 2) {
1659 conn->status_tcp[location] = STATUS_TCP_ONLINE;
1660 }
1661
1662 conn->con_number_tcp[location] = connection_id;
1663 return 0;
1664}
1665
1666static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length)
1667{
1668
1669 if (length == 0)
1670 return -1;
1671
1672 TCP_Client_Connection *TCP_con = object;
1673 Net_Crypto *c = TCP_con->net_crypto_pointer;
1674
1675 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1676 return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length);
1677 }
1678
1679 Crypto_Connection *conn = get_crypto_connection(c, number);
1680
1681 if (conn == 0)
1682 return -1;
1683
1684 if (handle_packet_connection(c, number, data, length) != 0)
1685 return -1;
1686
1687 //TODO detect and kill bad TCP connections.
1688 return 0;
1689}
1690
1691static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length)
1692{
1693 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1694 return -1;
1695
1696 TCP_Client_Connection *TCP_con = object;
1697 Net_Crypto *c = TCP_con->net_crypto_pointer;
1698 uint32_t location = TCP_con->net_crypto_location;
1699
1700 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1701 return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length);
1702 }
1703
1704 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1705
1706 if (crypt_connection_id == -1) {
1707 IP_Port source;
1708 source.ip.family = TCP_FAMILY;
1709 source.ip.ip6.uint32[0] = location;
1710
1711 if (data[0] != NET_PACKET_CRYPTO_HS) {
1712 fprintf(stderr, "tcp snhappen %u\n", data[0]);
1713 return -1;
615 } 1714 }
616 1715
1716 if (handle_new_connection_handshake(c, source, data, length) != 0)
1717 return -1;
1718
617 return 0; 1719 return 0;
618 } 1720 }
619 1721
620 return 1; 1722 if (handle_packet_connection(c, crypt_connection_id, data, length) != 0)
1723 return -1;
1724
1725 return 0;
621} 1726}
622 1727
623/* Accept an incoming connection using the parameters provided by crypto_inbound. 1728/* Check if tcp connection to public key can be created.
624 * 1729 *
625 * return -1 if not successful. 1730 * return -1 if it can't.
626 * return the crypt_connection_id if successful. 1731 * return 0 if it can.
627 */ 1732 */
628int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, 1733static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key)
629 uint8_t *session_key)
630{ 1734{
631 uint32_t i; 1735 uint32_t i;
632 1736
633 if (discard_packet(c->lossless_udp, connection_id) == -1) 1737 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1738 if (c->tcp_connections_new[i] == NULL)
1739 continue;
1740
1741 if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1742 return -1;
1743 }
1744
1745 uint32_t num = 0;
1746
1747 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1748 if (c->tcp_connections[i] == NULL)
1749 continue;
1750
1751 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1752 return -1;
1753
1754 ++num;
1755 }
1756
1757 if (num == MAX_TCP_CONNECTIONS)
634 return -1; 1758 return -1;
635 1759
636 /* 1760 return 0;
637 * if(getcryptconnection_id(public_key) != -1) 1761}
638 * {
639 * return -1;
640 * }
641 */
642 1762
643 if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 1763/* Add a tcp relay, associating it to a crypt_connection_id.
644 || c->crypto_connections == NULL) 1764 *
1765 * return 0 if it was added.
1766 * return -1 if it wasn't.
1767 */
1768int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key)
1769{
1770 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1771
1772 if (conn == 0)
645 return -1; 1773 return -1;
646 1774
647 memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); 1775 if (ip_port.ip.family == TCP_INET) {
648 c->crypto_connections[c->crypto_connections_length].number = ~0; 1776 ip_port.ip.family = AF_INET;
649 1777 } else if (ip_port.ip.family == TCP_INET6) {
650 for (i = 0; i <= c->crypto_connections_length; ++i) { 1778 ip_port.ip.family = AF_INET6;
651 if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { 1779 }
652 c->crypto_connections[i].number = connection_id; 1780
653 c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; 1781 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
654 c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT; 1782 return -1;
655 random_nonce(c->crypto_connections[i].recv_nonce); 1783
656 memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 1784 uint32_t i;
657 memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 1785
658 increment_nonce(c->crypto_connections[i].sent_nonce); 1786 for (i = 0; i < conn->num_tcp_relays; ++i) {
659 memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); 1787 if (memcmp(conn->tcp_relays[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
660 1788 conn->tcp_relays[i].ip_port = ip_port;
661 crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); 1789 return 0;
662 1790 }
663 if (c->crypto_connections_length == i) 1791 }
664 ++c->crypto_connections_length;
665
666 if (send_cryptohandshake(c, connection_id, public_key, c->crypto_connections[i].recv_nonce,
667 c->crypto_connections[i].sessionpublic_key) == 1) {
668 increment_nonce(c->crypto_connections[i].recv_nonce);
669 uint32_t zero = 0;
670 encrypt_precompute(c->crypto_connections[i].peersessionpublic_key,
671 c->crypto_connections[i].sessionsecret_key,
672 c->crypto_connections[i].shared_key);
673 c->crypto_connections[i].status =
674 CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */
675 write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero));
676 c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */
677 return i;
678 }
679 1792
680 return -1; /* This should never happen. */ 1793 if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) {
1794 uint16_t index = rand() % MAX_TCP_RELAYS_PEER;
1795 conn->tcp_relays[index].ip_port = ip_port;
1796 memcpy(conn->tcp_relays[index].client_id, public_key, crypto_box_PUBLICKEYBYTES);
1797 } else {
1798 conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port;
1799 memcpy(conn->tcp_relays[conn->num_tcp_relays].client_id, public_key, crypto_box_PUBLICKEYBYTES);
1800 ++conn->num_tcp_relays;
1801 }
1802
1803 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1804 if (c->tcp_connections[i] == NULL)
1805 continue;
1806
1807 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1808 if (conn->status_tcp[i] == STATUS_TCP_OFFLINE)
1809 conn->status_tcp[i] = STATUS_TCP_INVISIBLE;
1810 }
1811 }
1812
1813 return add_tcp_relay(c, ip_port, public_key);
1814}
1815
1816/* Add a tcp relay to the array.
1817 *
1818 * return 0 if it was added.
1819 * return -1 if it wasn't.
1820 */
1821int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key)
1822{
1823 if (ip_port.ip.family == TCP_INET) {
1824 ip_port.ip.family = AF_INET;
1825 } else if (ip_port.ip.family == TCP_INET6) {
1826 ip_port.ip.family = AF_INET6;
1827 }
1828
1829 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
1830 return -1;
1831
1832 if (tcp_connection_check(c, public_key) != 0)
1833 return -1;
1834
1835 uint32_t i;
1836
1837 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1838 if (c->tcp_connections_new[i] == NULL) {
1839 c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key);
1840 return 0;
681 } 1841 }
682 } 1842 }
683 1843
684 return -1; 1844 return -1;
685} 1845}
686 1846
687/* return 0 if no connection. 1847/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
688 * return 1 we have sent a handshake. 1848 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
689 * return 2 if connection is not confirmed yet (we have received a handshake but no empty data packet). 1849 *
690 * return 3 if the connection is established. 1850 * return number of relays copied to tcp_relays on success.
691 * return 4 if the connection is timed out and waiting to be killed. 1851 * return 0 on failure.
692 */ 1852 */
693int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id) 1853unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
694{ 1854{
695 if ((unsigned int)crypt_connection_id < c->crypto_connections_length) 1855 if (num == 0)
696 return c->crypto_connections[crypt_connection_id].status; 1856 return 0;
1857
1858 uint32_t i;
1859 uint16_t copied = 0;
1860
1861 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1862 if (c->tcp_connections[i] != NULL) {
1863 memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
1864 tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;
1865
1866 if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
1867 tcp_relays[copied].ip_port.ip.family = TCP_INET;
1868 } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
1869 tcp_relays[copied].ip_port.ip.family = TCP_INET6;
1870 }
1871
1872 ++copied;
1873
1874 if (copied == num)
1875 return copied;
1876 }
1877 }
697 1878
698 return CRYPTO_CONN_NO_CONNECTION; 1879 return copied;
699} 1880}
700 1881
701void new_keys(Net_Crypto *c) 1882/* Add a connected tcp connection to the tcp_connections array.
1883 *
1884 * return 0 if it was added.
1885 * return -1 if it wasn't.
1886 */
1887static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
702{ 1888{
703 crypto_box_keypair(c->self_public_key, c->self_secret_key); 1889 uint32_t i;
1890
1891 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1892 if (c->tcp_connections[i] == NULL)
1893 break;
1894 }
1895
1896 if (i == MAX_TCP_CONNECTIONS)
1897 return -1;
1898
1899 uint32_t tcp_num = i;
1900
1901 for (i = 0; i < c->crypto_connections_length; ++i) {
1902 Crypto_Connection *conn = get_crypto_connection(c, i);
1903
1904 if (conn == 0)
1905 return -1;
1906
1907 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
1908 continue;
1909
1910 if (conn->status == CRYPTO_CONN_TIMED_OUT)
1911 continue;
1912
1913 if (conn->dht_public_key_set)
1914 if (send_routing_request(tcp_con, conn->dht_public_key) != 1)
1915 return -1;
1916
1917 }
1918
1919 tcp_con->net_crypto_pointer = c;
1920 tcp_con->net_crypto_location = tcp_num;
1921 routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
1922 routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
1923 routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
1924 oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
1925 c->tcp_connections[tcp_num] = tcp_con;
1926 return 0;
704} 1927}
705 1928
706/* Save the public and private keys to the keys array. 1929static void do_tcp(Net_Crypto *c)
707 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 1930{
1931 uint32_t i;
1932
1933 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1934 if (c->tcp_connections_new[i] == NULL)
1935 continue;
1936
1937 do_TCP_connection(c->tcp_connections_new[i]);
1938
1939 if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) {
1940 if (add_tcp_connected(c, c->tcp_connections_new[i]) == 0) {
1941 c->tcp_connections_new[i] = NULL;
1942 } else {
1943 kill_TCP_connection(c->tcp_connections_new[i]);
1944 c->tcp_connections_new[i] = NULL;
1945 }
1946 }
1947 }
1948
1949 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1950 if (c->tcp_connections[i] == NULL)
1951 continue;
1952
1953 do_TCP_connection(c->tcp_connections[i]);
1954 }
1955}
1956
1957static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number)
1958{
1959 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
1960 return;
1961
1962 if (number >= MAX_TCP_CONNECTIONS)
1963 return;
1964
1965 conn->status_tcp[number] = STATUS_TCP_NULL;
1966 conn->con_number_tcp[number] = 0;
1967}
1968
1969static void clear_disconnected_tcp(Net_Crypto *c)
1970{
1971 uint32_t i, j;
1972
1973 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1974 if (c->tcp_connections_new[i] == NULL)
1975 continue;
1976
1977 if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED)
1978 continue;
1979
1980 kill_TCP_connection(c->tcp_connections_new[i]);
1981 c->tcp_connections_new[i] = NULL;
1982 }
1983
1984 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1985 if (c->tcp_connections[i] == NULL)
1986 continue;
1987
1988 TCP_Client_Connection *tcp_con = c->tcp_connections[i];
1989
1990 if (tcp_con->status != TCP_CLIENT_DISCONNECTED)
1991 continue;
1992
1993 c->tcp_connections[i] = NULL;
1994 kill_TCP_connection(tcp_con);
1995
1996 for (j = 0; j < c->crypto_connections_length; ++j) {
1997 Crypto_Connection *conn = get_crypto_connection(c, j);
1998
1999 if (conn == 0)
2000 return;
2001
2002 clear_disconnected_tcp_peer(conn, i);
2003 }
2004 }
2005}
2006
2007/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
2008 *
2009 * The set function should return -1 on failure and 0 on success.
2010 * Note that if this function is set, the connection will clear itself on disconnect.
2011 * Object and id will be passed to this function untouched.
2012 * status is 1 if the connection is going online, 0 if it is going offline.
2013 *
2014 * return -1 on failure.
2015 * return 0 on success.
708 */ 2016 */
709void save_keys(Net_Crypto *c, uint8_t *keys) 2017int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object,
2018 int id, uint8_t status), void *object, int id)
710{ 2019{
711 memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES); 2020 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
712 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); 2021
2022 if (conn == 0)
2023 return -1;
2024
2025 conn->connection_status_callback = connection_status_callback;
2026 conn->connection_status_callback_object = object;
2027 conn->connection_status_callback_id = id;
2028 return 0;
713} 2029}
714 2030
715/* Load the public and private keys from the keys array. 2031/* Set function to be called when connection with crypt_connection_id receives a data packet of length.
716 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 2032 *
2033 * The set function should return -1 on failure and 0 on success.
2034 * Object and id will be passed to this function untouched.
2035 *
2036 * return -1 on failure.
2037 * return 0 on success.
717 */ 2038 */
718void load_keys(Net_Crypto *c, uint8_t *keys) 2039int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
2040 int id, uint8_t *data, uint16_t length), void *object, int id)
719{ 2041{
720 memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES); 2042 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
721 memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); 2043
2044 if (conn == 0)
2045 return -1;
2046
2047 conn->connection_data_callback = connection_data_callback;
2048 conn->connection_data_callback_object = object;
2049 conn->connection_data_callback_id = id;
2050 return 0;
722} 2051}
723 2052
724/* Handle received packets for not yet established crypto connections. */ 2053/* Get the crypto connection id from the ip_port.
725static void receive_crypto(Net_Crypto *c) 2054 *
2055 * return -1 on failure.
2056 * return connection id on success.
2057 */
2058static int crypto_id_ip_port(Net_Crypto *c, IP_Port ip_port)
726{ 2059{
727 uint32_t i; 2060 uint32_t i;
728 uint64_t temp_time = unix_time();
729 2061
730 for (i = 0; i < c->crypto_connections_length; ++i) { 2062 for (i = 0; i < c->crypto_connections_length; ++i) {
731 if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) 2063 if (is_alive(c->crypto_connections[i].status))
732 continue; 2064 if (ipport_equal(&ip_port, &c->crypto_connections[i].ip_port))
2065 return i;
2066 }
733 2067
734 if (c->crypto_connections[i].status == CRYPTO_CONN_HANDSHAKE_SENT) { 2068 return -1;
735 uint8_t temp_data[MAX_DATA_SIZE]; 2069}
736 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 2070
737 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 2071#define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + crypto_box_MACBYTES)
738 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 2072
739 uint16_t len; 2073/* Handle raw UDP packets coming directly from the socket.
740 2074 *
741 if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* Handle handshake packet. */ 2075 * Handles:
742 len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); 2076 * Cookie response packets.
743 2077 * Crypto handshake packets.
744 if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { 2078 * Crypto data packets.
745 if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { 2079 *
746 memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 2080 */
747 memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 2081static int udp_handle_packet(void *object, IP_Port source, uint8_t *packet, uint32_t length)
748 increment_nonce(c->crypto_connections[i].sent_nonce); 2082{
749 uint32_t zero = 0; 2083 if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE)
750 encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, 2084 return 1;
751 c->crypto_connections[i].sessionsecret_key, 2085
752 c->crypto_connections[i].shared_key); 2086 Net_Crypto *c = object;
753 c->crypto_connections[i].status = 2087 int crypt_connection_id = crypto_id_ip_port(c, source);
754 CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */ 2088
755 write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); 2089 if (crypt_connection_id == -1) {
756 c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */ 2090 if (packet[0] != NET_PACKET_CRYPTO_HS)
757 } else { 2091 return 1;
758 /* This should not happen, timeout the connection if it does. */ 2092
759 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; 2093 if (handle_new_connection_handshake(c, source, packet, length) != 0)
760 } 2094 return 1;
761 } else { 2095
762 /* This should not happen, timeout the connection if it does. */ 2096 return 0;
763 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; 2097 }
764 } 2098
765 } else if (id_packet(c->lossless_udp, 2099 if (handle_packet_connection(c, crypt_connection_id, packet, length) != 0)
766 c->crypto_connections[i].number) != (uint8_t)~0) { 2100 return 1;
767 /* This should not happen, timeout the connection if it does. */ 2101
768 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; 2102 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2103
2104 if (conn == 0)
2105 return -1;
2106
2107 conn->direct_lastrecv_time = current_time_monotonic();
2108 return 0;
2109}
2110
2111/* The dT for the average packet recieving rate calculations.
2112 Also used as the */
2113#define PACKET_COUNTER_AVERAGE_INTERVAL 200
2114
2115/* Ratio of recv queue size / recv packet rate (in seconds) times
2116 * the number of ms between request packets to send at that ratio
2117 */
2118#define REQUEST_PACKETS_COMPARE_CONSTANT (0.5 * 100.0)
2119static void send_crypto_packets(Net_Crypto *c)
2120{
2121 uint32_t i;
2122 uint64_t temp_time = current_time_monotonic();
2123
2124 for (i = 0; i < c->crypto_connections_length; ++i) {
2125 Crypto_Connection *conn = get_crypto_connection(c, i);
2126
2127 if (conn == 0)
2128 return;
2129
2130 if (CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time < temp_time) {
2131 send_temp_packet(c, i);
2132 }
2133
2134 if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED)
2135 && (CRYPTO_SEND_PACKET_INTERVAL + conn->last_request_packet_sent) < temp_time) {
2136 if (send_request_packet(c, i) == 0) {
2137 conn->last_request_packet_sent = temp_time;
769 } 2138 }
2139
770 } 2140 }
771 2141
772 if (c->crypto_connections[i].status == CRYPTO_CONN_NOT_CONFIRMED) { 2142 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
773 if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { 2143 if (((double)num_packets_array(&conn->recv_array) / (conn->packet_recv_rate + 1.0)) * (double)(
774 uint8_t temp_data[MAX_DATA_SIZE]; 2144 temp_time - conn->last_request_packet_sent) > REQUEST_PACKETS_COMPARE_CONSTANT) {
775 uint8_t data[MAX_DATA_SIZE]; 2145 if (send_request_packet(c, i) == 0) {
776 int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); 2146 conn->last_request_packet_sent = temp_time;
777 int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, 2147 }
778 c->crypto_connections[i].sessionsecret_key, 2148 }
779 c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); 2149
780 uint32_t zero = 0; 2150 if ((PACKET_COUNTER_AVERAGE_INTERVAL + conn->packet_counter_set) < temp_time) {
781 2151 conn->packet_recv_rate = (double)conn->packet_counter / ((double)(temp_time - conn->packet_counter_set) / 1000.0);
782 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { 2152 conn->packet_counter = 0;
783 increment_nonce(c->crypto_connections[i].recv_nonce); 2153 conn->packet_counter_set = temp_time;
784 encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, 2154
785 c->crypto_connections[i].sessionsecret_key, 2155 if ((double)num_packets_array(&conn->send_array) < 0.3 * (conn->packet_send_rate)) {
786 c->crypto_connections[i].shared_key); 2156 conn->packet_send_rate *= 1.2;
787 c->crypto_connections[i].status = CRYPTO_CONN_ESTABLISHED; 2157 } else if ((double)num_packets_array(&conn->send_array) > 0.4 * (conn->packet_send_rate)) {
788 c->crypto_connections[i].timeout = ~0; 2158 conn->packet_send_rate *= 0.8;
789 /* Connection is accepted. */ 2159 }
790 confirm_connection(c->lossless_udp, c->crypto_connections[i].number); 2160
2161 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending)
2162 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
2163
2164 if (conn->packet_send_rate > CRYPTO_PACKET_BUFFER_SIZE * 2)
2165 conn->packet_send_rate = CRYPTO_PACKET_BUFFER_SIZE * 2;
2166
2167 }
2168
2169 if (conn->last_packets_left_set == 0) {
2170 conn->last_packets_left_set = temp_time;
2171 conn->packets_left = conn->packet_send_rate;
2172 } else if (((1000.0 / conn->packet_send_rate) + conn->last_packets_left_set) < temp_time) {
2173 uint32_t num_packets = conn->packet_send_rate * ((double)(temp_time - conn->last_packets_left_set) / 1000.0);
2174
2175 if (conn->packets_left > num_packets * 2 + CRYPTO_MIN_QUEUE_LENGTH) {
2176 conn->packets_left = num_packets * 2 + CRYPTO_MIN_QUEUE_LENGTH;
791 } else { 2177 } else {
792 /* This should not happen, timeout the connection if it does. */ 2178 conn->packets_left += num_packets;
793 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
794 } 2179 }
795 } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != (uint8_t)~0) { 2180
796 /* This should not happen, timeout the connection if it does. */ 2181 conn->last_packets_left_set = temp_time;
797 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT;
798 } 2182 }
799 }
800 2183
801 if (temp_time > c->crypto_connections[i].timeout) { 2184 int ret = send_requested_packets(c, i, conn->packets_left);
802 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; 2185
2186 if (ret != -1) {
2187 conn->packets_left -= ret;
2188 }
2189
2190 if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH) {
2191 --conn->sending;
2192 }
803 } 2193 }
804 } 2194 }
805} 2195}
806 2196
2197
2198/* returns the number of packet slots left in the sendbuffer.
2199 * return 0 if failure.
2200 */
2201uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
2202{
2203 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2204
2205 if (conn == 0)
2206 return 0;
2207
2208 return conn->packets_left;
2209}
2210
2211
2212
2213
2214/* return -1 if data could not be put in packet queue.
2215 * return positive packet number if data was put into the queue.
2216 */
2217int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
2218{
2219 if (length == 0)
2220 return -1;
2221
2222 if (data[0] < CRYPTO_RESERVED_PACKETS)
2223 return -1;
2224
2225 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2226
2227 if (conn == 0)
2228 return -1;
2229
2230 if (conn->status != CRYPTO_CONN_ESTABLISHED)
2231 return -1;
2232
2233 if (conn->packets_left == 0)
2234 return -1;
2235
2236 int64_t ret = send_lossless_packet(c, crypt_connection_id, data, length);
2237
2238 if (ret == -1)
2239 return -1;
2240
2241 --conn->packets_left;
2242 conn->sending = CRYPTO_MIN_QUEUE_LENGTH;
2243 return ret;
2244}
2245
2246/* Kill a crypto connection.
2247 *
2248 * return -1 on failure.
2249 * return 0 on success.
2250 */
2251int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2252{
2253 //TODO
2254 send_kill_packet(c, crypt_connection_id);
2255 disconnect_peer_tcp(c, crypt_connection_id);
2256 return wipe_crypto_connection(c, crypt_connection_id);
2257}
2258
2259/* return one of CRYPTO_CONN_* values indicating the state of the connection.
2260 *
2261 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
2262 */
2263unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected)
2264{
2265 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2266
2267 if (conn == 0)
2268 return CRYPTO_CONN_NO_CONNECTION;
2269
2270 *direct_connected = 0;
2271
2272 if ((CRYPTO_SEND_PACKET_INTERVAL * MAX_NUM_SENDPACKET_TRIES + conn->direct_lastrecv_time) > current_time_monotonic())
2273 *direct_connected = 1;
2274
2275 return conn->status;
2276}
2277
2278void new_keys(Net_Crypto *c)
2279{
2280 crypto_box_keypair(c->self_public_key, c->self_secret_key);
2281}
2282
2283/* Save the public and private keys to the keys array.
2284 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
2285 */
2286void save_keys(Net_Crypto *c, uint8_t *keys)
2287{
2288 memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES);
2289 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
2290}
2291
2292/* Load the public and private keys from the keys array.
2293 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
2294 */
2295void load_keys(Net_Crypto *c, uint8_t *keys)
2296{
2297 memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES);
2298 memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES);
2299}
2300
807/* Run this to (re)initialize net_crypto. 2301/* Run this to (re)initialize net_crypto.
808 * Sets all the global connection variables to their default values. 2302 * Sets all the global connection variables to their default values.
809 */ 2303 */
810Net_Crypto *new_net_crypto(Networking_Core *net) 2304Net_Crypto *new_net_crypto(DHT *dht)
811{ 2305{
812 unix_time_update(); 2306 unix_time_update();
813 2307
814 if (net == NULL) 2308 if (dht == NULL)
815 return NULL; 2309 return NULL;
816 2310
817 Net_Crypto *temp = calloc(1, sizeof(Net_Crypto)); 2311 Net_Crypto *temp = calloc(1, sizeof(Net_Crypto));
@@ -819,31 +2313,55 @@ Net_Crypto *new_net_crypto(Networking_Core *net)
819 if (temp == NULL) 2313 if (temp == NULL)
820 return NULL; 2314 return NULL;
821 2315
822 temp->lossless_udp = new_lossless_udp(net); 2316 temp->dht = dht;
823
824 if (temp->lossless_udp == NULL) {
825 free(temp);
826 return NULL;
827 }
828 2317
829 new_keys(temp); 2318 new_keys(temp);
830 return temp; 2319 new_symmetric_key(temp->secret_symmetric_key);
831}
832 2320
833void init_cryptopackets(void *dht) 2321 networking_registerhandler(dht->net, NET_PACKET_COOKIE_REQUEST, &udp_handle_cookie_request, temp);
834{ 2322 networking_registerhandler(dht->net, NET_PACKET_COOKIE_RESPONSE, &udp_handle_packet, temp);
835 DHT *s_dht = dht; 2323 networking_registerhandler(dht->net, NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp);
836 networking_registerhandler(s_dht->c->lossless_udp->net, NET_PACKET_CRYPTO, &cryptopacket_handle, s_dht); 2324 networking_registerhandler(dht->net, NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp);
2325 return temp;
837} 2326}
838 2327
839static void kill_timedout(Net_Crypto *c) 2328static void kill_timedout(Net_Crypto *c)
840{ 2329{
841 uint32_t i; 2330 uint32_t i;
2331 //uint64_t temp_time = current_time_monotonic();
842 2332
843 for (i = 0; i < c->crypto_connections_length; ++i) { 2333 for (i = 0; i < c->crypto_connections_length; ++i) {
844 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION 2334 Crypto_Connection *conn = get_crypto_connection(c, i);
845 && is_connected(c->lossless_udp, c->crypto_connections[i].number) == LUDP_TIMED_OUT) 2335
846 c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; 2336 if (conn == 0)
2337 return;
2338
2339 if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT)
2340 continue;
2341
2342 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
2343 || conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
2344 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES)
2345 continue;
2346
2347 conn->killed = 1;
2348
2349 }
2350
2351 if (conn->killed) {
2352 if (conn->connection_status_callback) {
2353 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
2354 crypto_kill(c, i);
2355 continue;
2356 }
2357
2358 conn->status = CRYPTO_CONN_TIMED_OUT;
2359 continue;
2360 }
2361
2362 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
2363 //TODO: add a timeout here?
2364 }
847 } 2365 }
848} 2366}
849 2367
@@ -851,9 +2369,10 @@ static void kill_timedout(Net_Crypto *c)
851void do_net_crypto(Net_Crypto *c) 2369void do_net_crypto(Net_Crypto *c)
852{ 2370{
853 unix_time_update(); 2371 unix_time_update();
854 do_lossless_udp(c->lossless_udp);
855 kill_timedout(c); 2372 kill_timedout(c);
856 receive_crypto(c); 2373 do_tcp(c);
2374 clear_disconnected_tcp(c);
2375 send_crypto_packets(c);
857} 2376}
858 2377
859void kill_net_crypto(Net_Crypto *c) 2378void kill_net_crypto(Net_Crypto *c)
@@ -864,7 +2383,15 @@ void kill_net_crypto(Net_Crypto *c)
864 crypto_kill(c, i); 2383 crypto_kill(c, i);
865 } 2384 }
866 2385
867 kill_lossless_udp(c->lossless_udp); 2386 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2387 kill_TCP_connection(c->tcp_connections_new[i]);
2388 kill_TCP_connection(c->tcp_connections[i]);
2389 }
2390
2391 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL);
2392 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL);
2393 networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL);
2394 networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_DATA, NULL, NULL);
868 memset(c, 0, sizeof(Net_Crypto)); 2395 memset(c, 0, sizeof(Net_Crypto));
869 free(c); 2396 free(c);
870} 2397}
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index da776527..25f8c2f7 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -24,21 +24,62 @@
24#ifndef NET_CRYPTO_H 24#ifndef NET_CRYPTO_H
25#define NET_CRYPTO_H 25#define NET_CRYPTO_H
26 26
27#include "Lossless_UDP.h" 27#include "DHT.h"
28 28#include "TCP_client.h"
29#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
30#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
31#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
32#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */
33#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */
34#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */
35#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
36 29
37#define CRYPTO_CONN_NO_CONNECTION 0 30#define CRYPTO_CONN_NO_CONNECTION 0
38#define CRYPTO_CONN_HANDSHAKE_SENT 1 31#define CRYPTO_CONN_COOKIE_REQUESTING 1 //send cookie request packets
39#define CRYPTO_CONN_NOT_CONFIRMED 2 32#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
40#define CRYPTO_CONN_ESTABLISHED 3 33#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets
41#define CRYPTO_CONN_TIMED_OUT 4 34#define CRYPTO_CONN_ESTABLISHED 4
35#define CRYPTO_CONN_TIMED_OUT 5
36
37#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */
38
39/* Minimum packet rate per second. */
40#define CRYPTO_PACKET_MIN_RATE 40.0
41
42/* Minimum packet queue max length. */
43#define CRYPTO_MIN_QUEUE_LENGTH 8
44
45#define MAX_CRYPTO_PACKET_SIZE 1400
46
47#define CRYPTO_DATA_PACKET_MIN_SIZE (1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + crypto_box_MACBYTES)
48
49/* Max size of data in packets TODO*/
50#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE)
51
52/* Interval in ms between sending cookie request/handshake packets. */
53#define CRYPTO_SEND_PACKET_INTERVAL 500
54/* The maximum number of times we try to send the cookie request and handshake
55 before giving up. */
56#define MAX_NUM_SENDPACKET_TRIES 8
57
58#define PACKET_ID_PADDING 0
59#define PACKET_ID_REQUEST 1
60#define PACKET_ID_KILL 2
61
62#define CRYPTO_RESERVED_PACKETS 16
63
64#define MAX_TCP_CONNECTIONS 32
65#define MAX_TCP_RELAYS_PEER 4
66
67#define STATUS_TCP_NULL 0
68#define STATUS_TCP_OFFLINE 1
69#define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */
70#define STATUS_TCP_ONLINE 3
71
72typedef struct {
73 uint64_t time;
74 uint16_t length;
75 uint8_t data[MAX_CRYPTO_DATA_SIZE];
76} Packet_Data;
77
78typedef struct {
79 Packet_Data *buffer[CRYPTO_PACKET_BUFFER_SIZE];
80 uint32_t buffer_start;
81 uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */
82} Packets_Array;
42 83
43typedef struct { 84typedef struct {
44 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 85 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
@@ -48,27 +89,73 @@ typedef struct {
48 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* Our private key for this session. */ 89 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* Our private key for this session. */
49 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ 90 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
50 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* The precomputed shared key from encrypt_precompute. */ 91 uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* The precomputed shared key from encrypt_precompute. */
51 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet 92 uint8_t status; /* 0 if no connection, 1 we are sending cookie request packets,
52 * (we have received a handshake but no empty data packet), 3 if the connection is established. 93 * 2 if we are sending handshake packets
53 * 4 if the connection is timed out. 94 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet),
95 * 4 if the connection is established.
96 * 5 if the connection is timed out.
54 */ 97 */
55 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ 98 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
56 uint64_t timeout; 99 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
100 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
101 uint64_t dht_public_key_timestamp; /* Timestamp of the last time we confirmed the key was correct. */
57 102
58} Crypto_Connection; 103 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
104 uint16_t temp_packet_length;
105 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */
106 uint32_t temp_packet_num_sent;
107
108 IP_Port ip_port; /* The ip and port to contact this guy directly.*/
109 uint64_t direct_lastrecv_time; /* The Time at which we last received a direct packet in ms. */
110
111 Packets_Array send_array;
112 Packets_Array recv_array;
113
114 int (*connection_status_callback)(void *object, int id, uint8_t status);
115 void *connection_status_callback_object;
116 int connection_status_callback_id;
117
118 int (*connection_data_callback)(void *object, int id, uint8_t *data, uint16_t length);
119 void *connection_data_callback_object;
120 int connection_data_callback_id;
121
122 uint64_t last_request_packet_sent;
123
124 uint32_t packet_counter;
125 double packet_recv_rate;
126 uint64_t packet_counter_set;
127
128 double packet_send_rate;
129 uint32_t packets_left;
130 uint64_t last_packets_left_set;
131
132 uint8_t sending; /* indicates if data is being sent or not. */
59 133
60typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, 134 uint8_t killed; /* set to 1 to kill the connection. */
61 uint32_t len); 135
136 uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */
137 uint8_t con_number_tcp[MAX_TCP_CONNECTIONS];
138
139 Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
140 uint16_t num_tcp_relays;
141} Crypto_Connection;
62 142
63typedef struct { 143typedef struct {
64 cryptopacket_handler_callback function; 144 IP_Port source;
65 void *object; 145 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
66} Cryptopacket_Handles; 146 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer. */
147 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
148 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
149 uint8_t *cookie;
150 uint8_t cookie_length;
151} New_Connection;
67 152
68typedef struct { 153typedef struct {
69 Lossless_UDP *lossless_udp; 154 DHT *dht;
70 155
71 Crypto_Connection *crypto_connections; 156 Crypto_Connection *crypto_connections;
157 TCP_Client_Connection *tcp_connections_new[MAX_TCP_CONNECTIONS];
158 TCP_Client_Connection *tcp_connections[MAX_TCP_CONNECTIONS];
72 159
73 uint32_t crypto_connections_length; /* Length of connections array. */ 160 uint32_t crypto_connections_length; /* Length of connections array. */
74 161
@@ -76,154 +163,131 @@ typedef struct {
76 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 163 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
77 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 164 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
78 165
79 Cryptopacket_Handles cryptopackethandlers[256]; 166 /* The secret key used for cookies */
80} Net_Crypto; 167 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
81 168
82#include "DHT.h" 169 int (*new_connection_callback)(void *object, New_Connection *n_c);
170 void *new_connection_callback_object;
171} Net_Crypto;
83 172
84/* return zero if the buffer contains only zeros. */
85uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
86 173
87/* Encrypts plain of length length to encrypted of length + 16 using the 174/* Set function to be called when someone requests a new connection to us.
88 * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce. 175 *
176 * The set function should return -1 on failure and 0 on success.
89 * 177 *
90 * return -1 if there was a problem. 178 * n_c is only valid for the duration of the function call.
91 * return length of encrypted data if everything was fine.
92 */ 179 */
93int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 180void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
94 uint8_t *plain, uint32_t length, uint8_t *encrypted); 181 void *object);
95
96 182
97/* Decrypts encrypted of length length to plain of length length - 16 using the 183/* Accept a crypto connection.
98 * public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce.
99 * 184 *
100 * return -1 if there was a problem (decryption failed). 185 * return -1 on failure.
101 * return length of plain data if everything was fine. 186 * return connection id on success.
102 */ 187 */
103int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 188int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
104 uint8_t *encrypted, uint32_t length, uint8_t *plain);
105
106/* Fast encrypt/decrypt operations. Use if this is not a one-time communication.
107 encrypt_precompute does the shared-key generation once so it does not have
108 to be preformed on every encrypt/decrypt. */
109void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key);
110 189
111/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ 190/* Create a crypto connection.
112int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 191 * If one to that real public key already exists, return it.
113 uint8_t *plain, uint32_t length, uint8_t *encrypted);
114
115/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */
116int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
117 uint8_t *encrypted, uint32_t length, uint8_t *plain);
118
119/* Encrypts plain of length length to encrypted of length + 16 using a
120 * secret key crypto_secretbox_KEYBYTES big and a 24 byte nonce.
121 * 192 *
122 * return -1 if there was a problem. 193 * return -1 on failure.
123 * return length of encrypted data if everything was fine. 194 * return connection id on success.
124 */ 195 */
125int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted); 196int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key);
126 197
127/* Decrypts encrypted of length length to plain of length length - 16 using a 198/* Copy friends DHT public key into dht_key.
128 * secret key crypto_secretbox_KEYBYTES big and a 24 byte nonce.
129 * 199 *
130 * return -1 if there was a problem (decryption failed). 200 * return 0 on failure (no key copied).
131 * return length of plain data if everything was fine. 201 * return timestamp on success (key copied).
132 */ 202 */
133int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain); 203uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
134
135/* Increment the given nonce by 1. */
136void increment_nonce(uint8_t *nonce);
137 204
138/* Fill the given nonce with random bytes. */ 205/* Set the DHT public key of the crypto connection.
139void random_nonce(uint8_t *nonce); 206 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
207 * the other peer.
208 *
209 * return -1 on failure.
210 * return 0 on success.
211 */
212int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp);
140 213
141/* Fill a key crypto_secretbox_KEYBYTES big with random bytes */ 214/* Set the direct ip of the crypto connection.
142void new_symmetric_key(uint8_t *key); 215 *
216 * return -1 on failure.
217 * return 0 on success.
218 */
219int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port);
143 220
144/*Gives a nonce guaranteed to be different from previous ones.*/ 221/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
145void new_nonce(uint8_t *nonce); 222 *
223 * The set function should return -1 on failure and 0 on success.
224 * Note that if this function is set, the connection will clear itself on disconnect.
225 * Object and id will be passed to this function untouched.
226 * status is 1 if the connection is going online, 0 if it is going offline.
227 *
228 * return -1 on failure.
229 * return 0 on success.
230 */
231int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object,
232 int id, uint8_t status), void *object, int id);
146 233
147/* return 0 if there is no received data in the buffer. 234/* Set function to be called when connection with crypt_connection_id receives a data packet of length.
148 * return -1 if the packet was discarded. 235 *
149 * return length of received data if successful. 236 * The set function should return -1 on failure and 0 on success.
237 * Object and id will be passed to this function untouched.
238 *
239 * return -1 on failure.
240 * return 0 on success.
150 */ 241 */
151int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data); 242int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
243 int id, uint8_t *data, uint16_t length), void *object, int id);
244
152 245
153/* returns the number of packet slots left in the sendbuffer. 246/* returns the number of packet slots left in the sendbuffer.
154 * return 0 if failure. 247 * return 0 if failure.
155 */ 248 */
156uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); 249uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id);
157 250
158/* return 0 if data could not be put in packet queue. 251/* return -1 if data could not be put in packet queue.
159 * return 1 if data was put into the queue. 252 * return positive packet number if data was put into the queue.
160 */ 253 */
161int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); 254int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length);
162 255
163/* Create a request to peer. 256/* Add a tcp relay, associating it to a crypt_connection_id.
164 * send_public_key and send_secret_key are the pub/secret keys of the sender.
165 * recv_public_key is public key of reciever.
166 * packet must be an array of MAX_DATA_SIZE big.
167 * Data represents the data we send with the request with length being the length of the data.
168 * request_id is the id of the request (32 = friend request, 254 = ping request).
169 * 257 *
170 * return -1 on failure. 258 * return 0 if it was added.
171 * return the length of the created packet on success. 259 * return -1 if it wasn't.
172 */ 260 */
173int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, 261int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key);
174 uint8_t *data, uint32_t length, uint8_t request_id);
175 262
176/* puts the senders public key in the request in public_key, the data from the request 263/* Add a tcp relay to the array.
177 in data if a friend or ping request was sent to us and returns the length of the data. 264 *
178 packet is the request packet and length is its length 265 * return 0 if it was added.
179 return -1 if not valid request. */ 266 * return -1 if it wasn't.
180int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, 267 */
181 uint8_t *request_id, uint8_t *packet, uint16_t length); 268int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key);
182
183/* Function to call when request beginning with byte is received. */
184void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object);
185 269
186/* Start a secure connection with other peer who has public_key and ip_port. 270/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
271 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
187 * 272 *
188 * return -1 if failure. 273 * return number of relays copied to tcp_relays on success.
189 * return crypt_connection_id of the initialized connection if everything went well. 274 * return 0 on failure.
190 */ 275 */
191int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port); 276unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
192 277
193/* Kill a crypto connection. 278/* Kill a crypto connection.
194 * 279 *
195 * return 0 if killed successfully. 280 * return -1 on failure.
196 * return 1 if there was a problem. 281 * return 0 on success.
197 */ 282 */
198int crypto_kill(Net_Crypto *c, int crypt_connection_id); 283int crypto_kill(Net_Crypto *c, int crypt_connection_id);
199 284
200/* Handle an incoming connection.
201 *
202 * return -1 if no crypto inbound connection.
203 * return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection.
204 *
205 * Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
206 * and the session public key for the connection in session_key.
207 * to accept it see: accept_crypto_inbound(...).
208 * to refuse it just call kill_connection(...) on the connection id.
209 */
210int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
211 285
212/* Accept an incoming connection using the parameters provided by crypto_inbound. 286/* return one of CRYPTO_CONN_* values indicating the state of the connection.
213 * 287 *
214 * return -1 if not successful. 288 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
215 * return crypt_connection_id if successful.
216 */
217int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce,
218 uint8_t *session_key);
219
220/* return 0 if no connection.
221 * return 1 we have sent a handshake
222 * return 2 if connexion is not confirmed yet (we have received a handshake but no empty data packet).
223 * return 3 if the connection is established.
224 * return 4 if the connection is timed out and waiting to be killed.
225 */ 289 */
226int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id); 290unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected);
227 291
228 292
229/* Generate our public and private keys. 293/* Generate our public and private keys.
@@ -244,15 +308,13 @@ void load_keys(Net_Crypto *c, uint8_t *keys);
244/* Create new instance of Net_Crypto. 308/* Create new instance of Net_Crypto.
245 * Sets all the global connection variables to their default values. 309 * Sets all the global connection variables to their default values.
246 */ 310 */
247Net_Crypto *new_net_crypto(Networking_Core *net); 311Net_Crypto *new_net_crypto(DHT *dht);
248 312
249/* Main loop. */ 313/* Main loop. */
250void do_net_crypto(Net_Crypto *c); 314void do_net_crypto(Net_Crypto *c);
251 315
252void kill_net_crypto(Net_Crypto *c); 316void kill_net_crypto(Net_Crypto *c);
253 317
254/* Initialize the cryptopacket handling. */
255void init_cryptopackets(void *dht);
256 318
257 319
258#endif 320#endif
diff --git a/toxcore/network.c b/toxcore/network.c
index 5980abe3..a8ed4294 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -29,13 +29,17 @@
29#include "config.h" 29#include "config.h"
30#endif 30#endif
31 31
32#define LOGGING
33#include "logger.h" 32#include "logger.h"
34 33
35#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) 34#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
36#include <errno.h> 35#include <errno.h>
37#endif 36#endif
38 37
38#ifdef __APPLE__
39#include <mach/clock.h>
40#include <mach/mach.h>
41#endif
42
39#include "network.h" 43#include "network.h"
40#include "util.h" 44#include "util.h"
41 45
@@ -153,6 +157,21 @@ int set_socket_nonblock(sock_t sock)
153#endif 157#endif
154} 158}
155 159
160/* Set socket to not emit SIGPIPE
161 *
162 * return 1 on success
163 * return 0 on failure
164 */
165int set_socket_nosigpipe(sock_t sock)
166{
167#if defined(__MACH__)
168 int set = 1;
169 return (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)) == 0);
170#else
171 return 1;
172#endif
173}
174
156/* Set socket to dual (IPv4 + IPv6 socket) 175/* Set socket to dual (IPv4 + IPv6 socket)
157 * 176 *
158 * return 1 on success 177 * return 1 on success
@@ -160,7 +179,7 @@ int set_socket_nonblock(sock_t sock)
160 */ 179 */
161int set_socket_dualstack(sock_t sock) 180int set_socket_dualstack(sock_t sock)
162{ 181{
163 char ipv6only = 0; 182 int ipv6only = 0;
164 socklen_t optsize = sizeof(ipv6only); 183 socklen_t optsize = sizeof(ipv6only);
165 int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize); 184 int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize);
166 185
@@ -171,8 +190,9 @@ int set_socket_dualstack(sock_t sock)
171 return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)) == 0); 190 return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)) == 0);
172} 191}
173 192
193
174/* return current UNIX time in microseconds (us). */ 194/* return current UNIX time in microseconds (us). */
175uint64_t current_time(void) 195static uint64_t current_time_actual(void)
176{ 196{
177 uint64_t time; 197 uint64_t time;
178#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 198#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
@@ -192,29 +212,52 @@ uint64_t current_time(void)
192#endif 212#endif
193} 213}
194 214
195/* return a random number.
196 */
197uint32_t random_int(void)
198{
199 uint32_t randnum;
200 randombytes((uint8_t *)&randnum , sizeof(randnum));
201 return randnum;
202}
203 215
204uint64_t random_64b(void) 216#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
217static uint64_t last_monotime;
218static uint64_t add_monotime;
219#endif
220
221/* return current monotonic time in milliseconds (ms). */
222uint64_t current_time_monotonic(void)
205{ 223{
206 uint64_t randnum; 224 uint64_t time;
207 randombytes((uint8_t *)&randnum, sizeof(randnum)); 225#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
208 return randnum; 226 time = (uint64_t)GetTickCount() + add_monotime;
227
228 if (time < last_monotime) { /* Prevent time from ever decreasing because of 32 bit wrap. */
229 uint32_t add = ~0;
230 add_monotime += add;
231 time += add;
232 }
233
234 last_monotime = time;
235#else
236 struct timespec monotime;
237#if defined(__linux__)
238 clock_gettime(CLOCK_MONOTONIC_RAW, &monotime);
239#elif defined(__APPLE__)
240 clock_serv_t muhclock;
241 mach_timespec_t machtime;
242
243 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock);
244 clock_get_time(muhclock, &machtime);
245 mach_port_deallocate(mach_task_self(), muhclock);
246
247 monotime.tv_sec = machtime.tv_sec;
248 monotime.tv_nsec = machtime.tv_nsec;
249#else
250 clock_gettime(CLOCK_MONOTONIC, &monotime);
251#endif
252 time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL);
253#endif
254 return time;
209} 255}
210 256
211/* In case no logging */ 257/* In case no logging */
212#ifndef LOGGING 258#ifndef LOGGING
213
214#define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__) 259#define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__)
215 260#else
216#else
217
218#define data_0(__buflen__, __buffer__) __buflen__ > 4 ? ntohl(*(uint32_t *)&__buffer__[1]) : 0 261#define data_0(__buflen__, __buffer__) __buflen__ > 4 ? ntohl(*(uint32_t *)&__buffer__[1]) : 0
219#define data_1(__buflen__, __buffer__) __buflen__ > 7 ? ntohl(*(uint32_t *)&__buffer__[5]) : 0 262#define data_1(__buflen__, __buffer__) __buflen__ > 7 ? ntohl(*(uint32_t *)&__buffer__[5]) : 0
220 263
@@ -299,7 +342,7 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
299 if ((res >= 0) && ((uint32_t)res == length)) 342 if ((res >= 0) && ((uint32_t)res == length))
300 net->send_fail_eagain = 0; 343 net->send_fail_eagain = 0;
301 else if ((res < 0) && (errno == EWOULDBLOCK)) 344 else if ((res < 0) && (errno == EWOULDBLOCK))
302 net->send_fail_eagain = current_time(); 345 net->send_fail_eagain = current_time_monotonic();
303 346
304 return res; 347 return res;
305} 348}
@@ -308,7 +351,6 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
308 * ip and port of sender is put into ip_port. 351 * ip and port of sender is put into ip_port.
309 * Packet data is put into data. 352 * Packet data is put into data.
310 * Packet length is put into length. 353 * Packet length is put into length.
311 * Dump all empty packets.
312 */ 354 */
313static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) 355static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
314{ 356{
@@ -322,7 +364,7 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t
322 *length = 0; 364 *length = 0;
323 int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); 365 int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
324 366
325 if (fail_or_len <= 0) { 367 if (fail_or_len < 0) {
326 368
327 LOGGER_SCOPE( if ((fail_or_len < 0) && (errno != EWOULDBLOCK)) 369 LOGGER_SCOPE( if ((fail_or_len < 0) && (errno != EWOULDBLOCK))
328 LOGGER_ERROR("Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); ); 370 LOGGER_ERROR("Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); );
@@ -438,13 +480,13 @@ int networking_wait_execute(uint8_t *data, long seconds, long microseconds)
438 * that code) 480 * that code)
439 */ 481 */
440 if (s->send_fail_eagain != 0) { 482 if (s->send_fail_eagain != 0) {
441 // current_time(): microseconds 483 // current_time(): milliseconds
442 uint64_t now = current_time(); 484 uint64_t now = current_time_monotonic();
443 485
444 /* s->sendqueue_length: might be used to guess how long we keep checking */ 486 /* s->sendqueue_length: might be used to guess how long we keep checking */
445 /* for now, threshold is hardcoded to 250ms, too long for a really really 487 /* for now, threshold is hardcoded to 250ms, too long for a really really
446 * fast link, but too short for a sloooooow link... */ 488 * fast link, but too short for a sloooooow link... */
447 if (now - s->send_fail_eagain < 250000) { 489 if (now - s->send_fail_eagain < 250) {
448 writefds_add = 1; 490 writefds_add = 1;
449 } 491 }
450 } 492 }
@@ -508,6 +550,11 @@ int networking_wait_cleanup(Networking_Core *net, uint8_t *data)
508 return 1; 550 return 1;
509} 551}
510 552
553#ifndef VANILLA_NACL
554/* Used for sodium_init() */
555#include <sodium.h>
556#endif
557
511uint8_t at_startup_ran = 0; 558uint8_t at_startup_ran = 0;
512int networking_at_startup(void) 559int networking_at_startup(void)
513{ 560{
@@ -531,9 +578,9 @@ int networking_at_startup(void)
531 return -1; 578 return -1;
532 579
533#else 580#else
534 srandom((uint32_t)current_time()); 581 srandom((uint32_t)current_time_actual());
535#endif 582#endif
536 srand((uint32_t)current_time()); 583 srand((uint32_t)current_time_actual());
537 at_startup_ran = 1; 584 at_startup_ran = 1;
538 return 0; 585 return 0;
539} 586}
@@ -637,7 +684,6 @@ Networking_Core *new_networking(IP ip, uint16_t port)
637 } 684 }
638 685
639 if (ip.family == AF_INET6) { 686 if (ip.family == AF_INET6) {
640
641#ifdef LOGGING 687#ifdef LOGGING
642 int is_dualstack = 688 int is_dualstack =
643#endif /* LOGGING */ 689#endif /* LOGGING */
@@ -650,7 +696,6 @@ Networking_Core *new_networking(IP ip, uint16_t port)
650 mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02; 696 mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
651 mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01; 697 mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
652 mreq.ipv6mr_interface = 0; 698 mreq.ipv6mr_interface = 0;
653
654#ifdef LOGGING 699#ifdef LOGGING
655 int res = 700 int res =
656#endif /* LOGGING */ 701#endif /* LOGGING */
@@ -829,6 +874,31 @@ void ipport_copy(IP_Port *target, IP_Port *source)
829 memcpy(target, source, sizeof(IP_Port)); 874 memcpy(target, source, sizeof(IP_Port));
830}; 875};
831 876
877/* packing and unpacking functions */
878void ip_pack(uint8_t *data, IP *source)
879{
880 data[0] = source->family;
881 memcpy(data + 1, &source->ip6, SIZE_IP6);
882}
883
884void ip_unpack(IP *target, uint8_t *data)
885{
886 target->family = data[0];
887 memcpy(&target->ip6, data + 1, SIZE_IP6);
888}
889
890void ipport_pack(uint8_t *data, IP_Port *source)
891{
892 ip_pack(data, &source->ip);
893 memcpy(data + SIZE_IP, &source->port, SIZE_PORT);
894}
895
896void ipport_unpack(IP_Port *target, uint8_t *data)
897{
898 ip_unpack(&target->ip, data);
899 memcpy(&target->port, data + SIZE_IP, SIZE_PORT);
900}
901
832/* ip_ntoa 902/* ip_ntoa
833 * converts ip into a string 903 * converts ip into a string
834 * uses a static buffer, so mustn't used multiple times in the same output 904 * uses a static buffer, so mustn't used multiple times in the same output
diff --git a/toxcore/network.h b/toxcore/network.h
index 42ade800..0eb7bbd0 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -89,7 +89,7 @@ typedef int sock_t;
89#endif 89#endif
90 90
91#if defined(__sun__) 91#if defined(__sun__)
92#define __EXTENSIONS__ 1 // SunOS! 92#define __EXTENSIONS__ 1 // SunOS!
93#if defined(__SunOS5_6__) || defined(__SunOS5_7__) || defined(__SunOS5_8__) || defined(__SunOS5_9__) || defined(__SunOS5_10__) 93#if defined(__SunOS5_6__) || defined(__SunOS5_7__) || defined(__SunOS5_8__) || defined(__SunOS5_9__) || defined(__SunOS5_10__)
94//Nothing needed 94//Nothing needed
95#else 95#else
@@ -97,21 +97,6 @@ typedef int sock_t;
97#endif 97#endif
98#endif 98#endif
99 99
100#ifndef VANILLA_NACL
101/* We use libsodium by default. */
102#include <sodium.h>
103#else
104#include <crypto_box.h>
105#include <crypto_secretbox.h>
106#include <randombytes.h>
107#include <crypto_hash_sha256.h>
108#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
109#endif
110
111#ifndef crypto_secretbox_MACBYTES
112#define crypto_secretbox_MACBYTES (crypto_secretbox_ZEROBYTES - crypto_secretbox_BOXZEROBYTES)
113#endif
114
115#ifndef IPV6_ADD_MEMBERSHIP 100#ifndef IPV6_ADD_MEMBERSHIP
116#ifdef IPV6_JOIN_GROUP 101#ifdef IPV6_JOIN_GROUP
117#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 102#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
@@ -129,6 +114,10 @@ typedef int sock_t;
129#define NET_PACKET_HANDSHAKE 16 /* Handshake packet ID. */ 114#define NET_PACKET_HANDSHAKE 16 /* Handshake packet ID. */
130#define NET_PACKET_SYNC 17 /* SYNC packet ID. */ 115#define NET_PACKET_SYNC 17 /* SYNC packet ID. */
131#define NET_PACKET_DATA 18 /* Data packet ID. */ 116#define NET_PACKET_DATA 18 /* Data packet ID. */
117#define NET_PACKET_COOKIE_REQUEST 24 /* Cookie request packet */
118#define NET_PACKET_COOKIE_RESPONSE 25 /* Cookie response packet */
119#define NET_PACKET_CRYPTO_HS 26 /* Crypto handshake packet */
120#define NET_PACKET_CRYPTO_DATA 27 /* Crypto data packet */
132#define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */ 121#define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */
133#define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */ 122#define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */
134#define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */ 123#define NET_PACKET_GROUP_CHATS 48 /* Group chats packet ID. */
@@ -161,8 +150,11 @@ typedef int sock_t;
161#define TOX_PORTRANGE_TO 33545 150#define TOX_PORTRANGE_TO 33545
162#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM 151#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
163 152
164 153/* TCP related */
165/* TODO: remove padding bytes next time we need to break compatibility with old versions of core. */ 154#define TCP_ONION_FAMILY (AF_INET6 + 1)
155#define TCP_INET (AF_INET6 + 2)
156#define TCP_INET6 (AF_INET6 + 3)
157#define TCP_FAMILY (AF_INET6 + 4)
166 158
167typedef union __attribute__ ((__packed__)) 159typedef union __attribute__ ((__packed__))
168{ 160{
@@ -186,8 +178,6 @@ IP6;
186typedef struct __attribute__ ((__packed__)) 178typedef struct __attribute__ ((__packed__))
187{ 179{
188 uint8_t family; 180 uint8_t family;
189 /* Not used for anything right now. */
190 uint8_t padding[3];
191 union { 181 union {
192 IP4 ip4; 182 IP4 ip4;
193 IP6 ip6; 183 IP6 ip6;
@@ -195,23 +185,19 @@ typedef struct __attribute__ ((__packed__))
195} 185}
196IP; 186IP;
197 187
198typedef union __attribute__ ((__packed__)) 188typedef struct __attribute__ ((__packed__)) __attribute__((gcc_struct))
199{ 189{
200 struct {
201 IP4 ip;
202 uint16_t port;
203 /* Not used for anything right now. */
204 uint16_t padding;
205 };
206 uint8_t uint8[8];
207}
208IP4_Port;
209
210typedef struct __attribute__ ((__packed__)) IP_Port {
211 IP ip; 190 IP ip;
212 uint16_t port; 191 uint16_t port;
213 uint16_t padding; 192}
214} IP_Port; 193IP_Port;
194
195
196#define SIZE_IP4 4
197#define SIZE_IP6 16
198#define SIZE_IP (1 + SIZE_IP6)
199#define SIZE_PORT 2
200#define SIZE_IPPORT (SIZE_IP + SIZE_PORT)
215 201
216#define TOX_ENABLE_IPV6_DEFAULT 1 202#define TOX_ENABLE_IPV6_DEFAULT 1
217 203
@@ -250,6 +236,16 @@ void ip_copy(IP *target, IP *source);
250/* copies an ip_port structure */ 236/* copies an ip_port structure */
251void ipport_copy(IP_Port *target, IP_Port *source); 237void ipport_copy(IP_Port *target, IP_Port *source);
252 238
239
240/* packs IP into data, writes SIZE_IP bytes to data */
241void ip_pack(uint8_t *data, IP *source);
242/* unpacks IP from data, reads SIZE_IP bytes from data */
243void ip_unpack(IP *target, uint8_t *data);
244/* packs IP_Port into data, writes SIZE_IPPORT bytes to data */
245void ipport_pack(uint8_t *data, IP_Port *source);
246/* unpacks IP_Port from data, reads SIZE_IPPORT bytes to data */
247void ipport_unpack(IP_Port *target, uint8_t *data);
248
253/* 249/*
254 * addr_resolve(): 250 * addr_resolve():
255 * uses getaddrinfo to resolve an address into an IP address 251 * uses getaddrinfo to resolve an address into an IP address
@@ -332,6 +328,13 @@ void kill_sock(sock_t sock);
332 */ 328 */
333int set_socket_nonblock(sock_t sock); 329int set_socket_nonblock(sock_t sock);
334 330
331/* Set socket to not emit SIGPIPE
332 *
333 * return 1 on success
334 * return 0 on failure
335 */
336int set_socket_nosigpipe(sock_t sock);
337
335/* Set socket to dual (IPv4 + IPv6 socket) 338/* Set socket to dual (IPv4 + IPv6 socket)
336 * 339 *
337 * return 1 on success 340 * return 1 on success
@@ -339,13 +342,8 @@ int set_socket_nonblock(sock_t sock);
339 */ 342 */
340int set_socket_dualstack(sock_t sock); 343int set_socket_dualstack(sock_t sock);
341 344
342/* return current time in milleseconds since the epoch. */ 345/* return current monotonic time in milliseconds (ms). */
343uint64_t current_time(void); 346uint64_t current_time_monotonic(void);
344
345/* return a random number.
346 */
347uint32_t random_int(void);
348uint64_t random_64b(void);
349 347
350/* Basic network functions: */ 348/* Basic network functions: */
351 349
diff --git a/toxcore/onion.c b/toxcore/onion.c
index ccb729f3..479c6209 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -26,8 +26,6 @@
26#include "onion.h" 26#include "onion.h"
27#include "util.h" 27#include "util.h"
28 28
29#define MAX_ONION_SIZE MAX_DATA_SIZE
30
31#define RETURN_1 ONION_RETURN_1 29#define RETURN_1 ONION_RETURN_1
32#define RETURN_2 ONION_RETURN_2 30#define RETURN_2 ONION_RETURN_2
33#define RETURN_3 ONION_RETURN_3 31#define RETURN_3 ONION_RETURN_3
@@ -89,41 +87,43 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes)
89/* Create and send a onion packet. 87/* Create and send a onion packet.
90 * 88 *
91 * Use Onion_Path path to send data of length to dest. 89 * Use Onion_Path path to send data of length to dest.
90 * Maximum length of data is ONION_MAX_DATA_SIZE.
92 * 91 *
93 * return -1 on failure. 92 * return -1 on failure.
94 * return 0 on success. 93 * return 0 on success.
95 */ 94 */
96int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length) 95int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length)
97{ 96{
98 if (1 + length + SEND_1 > MAX_ONION_SIZE || length == 0) 97 if (1 + length + SEND_1 > ONION_MAX_PACKET_SIZE || length == 0)
99 return -1; 98 return -1;
100 99
101 to_net_family(&dest.ip); 100 to_net_family(&dest.ip);
102 uint8_t step1[sizeof(IP_Port) + length]; 101 uint8_t step1[SIZE_IPPORT + length];
102
103 103
104 memcpy(step1, &dest, sizeof(IP_Port)); 104 ipport_pack(step1, &dest);
105 memcpy(step1 + sizeof(IP_Port), data, length); 105 memcpy(step1 + SIZE_IPPORT, data, length);
106 106
107 uint8_t nonce[crypto_box_NONCEBYTES]; 107 uint8_t nonce[crypto_box_NONCEBYTES];
108 random_nonce(nonce); 108 random_nonce(nonce);
109 109
110 uint8_t step2[sizeof(IP_Port) + SEND_BASE + length]; 110 uint8_t step2[SIZE_IPPORT + SEND_BASE + length];
111 memcpy(step2, &path->ip_port3, sizeof(IP_Port)); 111 ipport_pack(step2, &path->ip_port3);
112 memcpy(step2 + sizeof(IP_Port), path->public_key3, crypto_box_PUBLICKEYBYTES); 112 memcpy(step2 + SIZE_IPPORT, path->public_key3, crypto_box_PUBLICKEYBYTES);
113 113
114 int len = encrypt_data_fast(path->shared_key3, nonce, step1, sizeof(step1), 114 int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, sizeof(step1),
115 step2 + sizeof(IP_Port) + crypto_box_PUBLICKEYBYTES); 115 step2 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES);
116 116
117 if ((uint32_t)len != sizeof(IP_Port) + length + crypto_box_MACBYTES) 117 if ((uint32_t)len != SIZE_IPPORT + length + crypto_box_MACBYTES)
118 return -1; 118 return -1;
119 119
120 uint8_t step3[sizeof(IP_Port) + SEND_BASE * 2 + length]; 120 uint8_t step3[SIZE_IPPORT + SEND_BASE * 2 + length];
121 memcpy(step3, &path->ip_port2, sizeof(IP_Port)); 121 ipport_pack(step3, &path->ip_port2);
122 memcpy(step3 + sizeof(IP_Port), path->public_key2, crypto_box_PUBLICKEYBYTES); 122 memcpy(step3 + SIZE_IPPORT, path->public_key2, crypto_box_PUBLICKEYBYTES);
123 len = encrypt_data_fast(path->shared_key2, nonce, step2, sizeof(step2), 123 len = encrypt_data_symmetric(path->shared_key2, nonce, step2, sizeof(step2),
124 step3 + sizeof(IP_Port) + crypto_box_PUBLICKEYBYTES); 124 step3 + SIZE_IPPORT + crypto_box_PUBLICKEYBYTES);
125 125
126 if ((uint32_t)len != sizeof(IP_Port) + SEND_BASE + length + crypto_box_MACBYTES) 126 if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES)
127 return -1; 127 return -1;
128 128
129 uint8_t packet[1 + length + SEND_1]; 129 uint8_t packet[1 + length + SEND_1];
@@ -131,10 +131,10 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
131 memcpy(packet + 1, nonce, crypto_box_NONCEBYTES); 131 memcpy(packet + 1, nonce, crypto_box_NONCEBYTES);
132 memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES); 132 memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES);
133 133
134 len = encrypt_data_fast(path->shared_key1, nonce, step3, sizeof(step3), 134 len = encrypt_data_symmetric(path->shared_key1, nonce, step3, sizeof(step3),
135 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 135 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
136 136
137 if ((uint32_t)len != sizeof(IP_Port) + SEND_BASE * 2 + length + crypto_box_MACBYTES) 137 if ((uint32_t)len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES)
138 return -1; 138 return -1;
139 139
140 if ((uint32_t)sendpacket(net, path->ip_port1, packet, sizeof(packet)) != sizeof(packet)) 140 if ((uint32_t)sendpacket(net, path->ip_port1, packet, sizeof(packet)) != sizeof(packet))
@@ -142,13 +142,18 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
142 142
143 return 0; 143 return 0;
144} 144}
145
145/* Create and send a onion response sent initially to dest with. 146/* Create and send a onion response sent initially to dest with.
147 * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
146 * 148 *
147 * return -1 on failure. 149 * return -1 on failure.
148 * return 0 on success. 150 * return 0 on success.
149 */ 151 */
150int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint32_t length, uint8_t *ret) 152int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint32_t length, uint8_t *ret)
151{ 153{
154 if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0)
155 return -1;
156
152 uint8_t packet[1 + RETURN_3 + length]; 157 uint8_t packet[1 + RETURN_3 + length];
153 packet[0] = NET_PACKET_ONION_RECV_3; 158 packet[0] = NET_PACKET_ONION_RECV_3;
154 memcpy(packet + 1, ret, RETURN_3); 159 memcpy(packet + 1, ret, RETURN_3);
@@ -164,7 +169,7 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui
164{ 169{
165 Onion *onion = object; 170 Onion *onion = object;
166 171
167 if (length > MAX_ONION_SIZE) 172 if (length > ONION_MAX_PACKET_SIZE)
168 return 1; 173 return 1;
169 174
170 if (length <= 1 + SEND_1) 175 if (length <= 1 + SEND_1)
@@ -172,11 +177,11 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui
172 177
173 change_symmetric_key(onion); 178 change_symmetric_key(onion);
174 179
175 uint8_t plain[MAX_ONION_SIZE]; 180 uint8_t plain[ONION_MAX_PACKET_SIZE];
176 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 181 uint8_t shared_key[crypto_box_BEFORENMBYTES];
177 get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES); 182 get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
178 int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 183 int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
179 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain); 184 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), plain);
180 185
181 if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)) 186 if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES))
182 return 1; 187 return 1;
@@ -187,23 +192,26 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui
187int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, uint8_t *nonce) 192int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, uint8_t *nonce)
188{ 193{
189 IP_Port send_to; 194 IP_Port send_to;
190 memcpy(&send_to, plain, sizeof(IP_Port)); 195 ipport_unpack(&send_to, plain);
191 to_host_family(&send_to.ip); 196 to_host_family(&send_to.ip);
192 197
193 uint8_t data[MAX_ONION_SIZE]; 198 uint8_t ip_port[SIZE_IPPORT];
199 ipport_pack(ip_port, &source);
200
201 uint8_t data[ONION_MAX_PACKET_SIZE];
194 data[0] = NET_PACKET_ONION_SEND_1; 202 data[0] = NET_PACKET_ONION_SEND_1;
195 memcpy(data + 1, nonce, crypto_box_NONCEBYTES); 203 memcpy(data + 1, nonce, crypto_box_NONCEBYTES);
196 memcpy(data + 1 + crypto_box_NONCEBYTES, plain + sizeof(IP_Port), len - sizeof(IP_Port)); 204 memcpy(data + 1 + crypto_box_NONCEBYTES, plain + SIZE_IPPORT, len - SIZE_IPPORT);
197 uint32_t data_len = 1 + crypto_box_NONCEBYTES + (len - sizeof(IP_Port)); 205 uint32_t data_len = 1 + crypto_box_NONCEBYTES + (len - SIZE_IPPORT);
198 uint8_t *ret_part = data + data_len; 206 uint8_t *ret_part = data + data_len;
199 new_nonce(ret_part); 207 new_nonce(ret_part);
200 len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, (uint8_t *)&source, sizeof(IP_Port), 208 len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
201 ret_part + crypto_secretbox_NONCEBYTES); 209 ret_part + crypto_box_NONCEBYTES);
202 210
203 if (len != sizeof(IP_Port) + crypto_secretbox_MACBYTES) 211 if (len != SIZE_IPPORT + crypto_box_MACBYTES)
204 return 1; 212 return 1;
205 213
206 data_len += crypto_secretbox_NONCEBYTES + len; 214 data_len += crypto_box_NONCEBYTES + len;
207 215
208 if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) 216 if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
209 return 1; 217 return 1;
@@ -215,7 +223,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t
215{ 223{
216 Onion *onion = object; 224 Onion *onion = object;
217 225
218 if (length > MAX_ONION_SIZE) 226 if (length > ONION_MAX_PACKET_SIZE)
219 return 1; 227 return 1;
220 228
221 if (length <= 1 + SEND_2) 229 if (length <= 1 + SEND_2)
@@ -223,36 +231,36 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t
223 231
224 change_symmetric_key(onion); 232 change_symmetric_key(onion);
225 233
226 uint8_t plain[MAX_ONION_SIZE]; 234 uint8_t plain[ONION_MAX_PACKET_SIZE];
227 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 235 uint8_t shared_key[crypto_box_BEFORENMBYTES];
228 get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES); 236 get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
229 int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 237 int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
230 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain); 238 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1), plain);
231 239
232 if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES)) 240 if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_1 + crypto_box_MACBYTES))
233 return 1; 241 return 1;
234 242
235 IP_Port send_to; 243 IP_Port send_to;
236 memcpy(&send_to, plain, sizeof(IP_Port)); 244 ipport_unpack(&send_to, plain);
237 to_host_family(&send_to.ip); 245 to_host_family(&send_to.ip);
238 246
239 uint8_t data[MAX_ONION_SIZE]; 247 uint8_t data[ONION_MAX_PACKET_SIZE];
240 data[0] = NET_PACKET_ONION_SEND_2; 248 data[0] = NET_PACKET_ONION_SEND_2;
241 memcpy(data + 1, packet + 1, crypto_box_NONCEBYTES); 249 memcpy(data + 1, packet + 1, crypto_box_NONCEBYTES);
242 memcpy(data + 1 + crypto_box_NONCEBYTES, plain + sizeof(IP_Port), len - sizeof(IP_Port)); 250 memcpy(data + 1 + crypto_box_NONCEBYTES, plain + SIZE_IPPORT, len - SIZE_IPPORT);
243 uint32_t data_len = 1 + crypto_box_NONCEBYTES + (len - sizeof(IP_Port)); 251 uint32_t data_len = 1 + crypto_box_NONCEBYTES + (len - SIZE_IPPORT);
244 uint8_t *ret_part = data + data_len; 252 uint8_t *ret_part = data + data_len;
245 new_nonce(ret_part); 253 new_nonce(ret_part);
246 uint8_t ret_data[RETURN_1 + sizeof(IP_Port)]; 254 uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
247 memcpy(ret_data, &source, sizeof(IP_Port)); 255 ipport_pack(ret_data, &source);
248 memcpy(ret_data + sizeof(IP_Port), packet + (length - RETURN_1), RETURN_1); 256 memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
249 len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), 257 len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
250 ret_part + crypto_secretbox_NONCEBYTES); 258 ret_part + crypto_box_NONCEBYTES);
251 259
252 if (len != RETURN_2 - crypto_secretbox_NONCEBYTES) 260 if (len != RETURN_2 - crypto_box_NONCEBYTES)
253 return 1; 261 return 1;
254 262
255 data_len += crypto_secretbox_NONCEBYTES + len; 263 data_len += crypto_box_NONCEBYTES + len;
256 264
257 if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) 265 if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len)
258 return 1; 266 return 1;
@@ -264,7 +272,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t
264{ 272{
265 Onion *onion = object; 273 Onion *onion = object;
266 274
267 if (length > MAX_ONION_SIZE) 275 if (length > ONION_MAX_PACKET_SIZE)
268 return 1; 276 return 1;
269 277
270 if (length <= 1 + SEND_3) 278 if (length <= 1 + SEND_3)
@@ -272,31 +280,31 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t
272 280
273 change_symmetric_key(onion); 281 change_symmetric_key(onion);
274 282
275 uint8_t plain[MAX_ONION_SIZE]; 283 uint8_t plain[ONION_MAX_PACKET_SIZE];
276 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 284 uint8_t shared_key[crypto_box_BEFORENMBYTES];
277 get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES); 285 get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES);
278 int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 286 int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
279 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain); 287 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2), plain);
280 288
281 if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES)) 289 if ((uint32_t)len != length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + RETURN_2 + crypto_box_MACBYTES))
282 return 1; 290 return 1;
283 291
284 IP_Port send_to; 292 IP_Port send_to;
285 memcpy(&send_to, plain, sizeof(IP_Port)); 293 ipport_unpack(&send_to, plain);
286 to_host_family(&send_to.ip); 294 to_host_family(&send_to.ip);
287 295
288 uint8_t data[MAX_ONION_SIZE]; 296 uint8_t data[ONION_MAX_PACKET_SIZE];
289 memcpy(data, plain + sizeof(IP_Port), len - sizeof(IP_Port)); 297 memcpy(data, plain + SIZE_IPPORT, len - SIZE_IPPORT);
290 uint32_t data_len = (len - sizeof(IP_Port)); 298 uint32_t data_len = (len - SIZE_IPPORT);
291 uint8_t *ret_part = data + (len - sizeof(IP_Port)); 299 uint8_t *ret_part = data + (len - SIZE_IPPORT);
292 new_nonce(ret_part); 300 new_nonce(ret_part);
293 uint8_t ret_data[RETURN_2 + sizeof(IP_Port)]; 301 uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
294 memcpy(ret_data, &source, sizeof(IP_Port)); 302 ipport_pack(ret_data, &source);
295 memcpy(ret_data + sizeof(IP_Port), packet + (length - RETURN_2), RETURN_2); 303 memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
296 len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), 304 len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
297 ret_part + crypto_secretbox_NONCEBYTES); 305 ret_part + crypto_box_NONCEBYTES);
298 306
299 if (len != RETURN_3 - crypto_secretbox_NONCEBYTES) 307 if (len != RETURN_3 - crypto_box_NONCEBYTES)
300 return 1; 308 return 1;
301 309
302 data_len += RETURN_3; 310 data_len += RETURN_3;
@@ -312,7 +320,7 @@ static int handle_recv_3(void *object, IP_Port source, uint8_t *packet, uint32_t
312{ 320{
313 Onion *onion = object; 321 Onion *onion = object;
314 322
315 if (length > MAX_ONION_SIZE) 323 if (length > ONION_MAX_PACKET_SIZE)
316 return 1; 324 return 1;
317 325
318 if (length <= 1 + RETURN_3) 326 if (length <= 1 + RETURN_3)
@@ -320,19 +328,19 @@ static int handle_recv_3(void *object, IP_Port source, uint8_t *packet, uint32_t
320 328
321 change_symmetric_key(onion); 329 change_symmetric_key(onion);
322 330
323 uint8_t plain[sizeof(IP_Port) + RETURN_2]; 331 uint8_t plain[SIZE_IPPORT + RETURN_2];
324 int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_secretbox_NONCEBYTES, 332 int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
325 sizeof(IP_Port) + RETURN_2 + crypto_secretbox_MACBYTES, plain); 333 SIZE_IPPORT + RETURN_2 + crypto_box_MACBYTES, plain);
326 334
327 if ((uint32_t)len != sizeof(plain)) 335 if ((uint32_t)len != sizeof(plain))
328 return 1; 336 return 1;
329 337
330 IP_Port send_to; 338 IP_Port send_to;
331 memcpy(&send_to, plain, sizeof(IP_Port)); 339 ipport_unpack(&send_to, plain);
332 340
333 uint8_t data[MAX_ONION_SIZE]; 341 uint8_t data[ONION_MAX_PACKET_SIZE];
334 data[0] = NET_PACKET_ONION_RECV_2; 342 data[0] = NET_PACKET_ONION_RECV_2;
335 memcpy(data + 1, plain + sizeof(IP_Port), RETURN_2); 343 memcpy(data + 1, plain + SIZE_IPPORT, RETURN_2);
336 memcpy(data + 1 + RETURN_2, packet + 1 + RETURN_3, length - (1 + RETURN_3)); 344 memcpy(data + 1 + RETURN_2, packet + 1 + RETURN_3, length - (1 + RETURN_3));
337 uint32_t data_len = 1 + RETURN_2 + (length - (1 + RETURN_3)); 345 uint32_t data_len = 1 + RETURN_2 + (length - (1 + RETURN_3));
338 346
@@ -346,7 +354,7 @@ static int handle_recv_2(void *object, IP_Port source, uint8_t *packet, uint32_t
346{ 354{
347 Onion *onion = object; 355 Onion *onion = object;
348 356
349 if (length > MAX_ONION_SIZE) 357 if (length > ONION_MAX_PACKET_SIZE)
350 return 1; 358 return 1;
351 359
352 if (length <= 1 + RETURN_2) 360 if (length <= 1 + RETURN_2)
@@ -354,19 +362,19 @@ static int handle_recv_2(void *object, IP_Port source, uint8_t *packet, uint32_t
354 362
355 change_symmetric_key(onion); 363 change_symmetric_key(onion);
356 364
357 uint8_t plain[sizeof(IP_Port) + RETURN_1]; 365 uint8_t plain[SIZE_IPPORT + RETURN_1];
358 int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_secretbox_NONCEBYTES, 366 int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
359 sizeof(IP_Port) + RETURN_1 + crypto_secretbox_MACBYTES, plain); 367 SIZE_IPPORT + RETURN_1 + crypto_box_MACBYTES, plain);
360 368
361 if ((uint32_t)len != sizeof(plain)) 369 if ((uint32_t)len != sizeof(plain))
362 return 1; 370 return 1;
363 371
364 IP_Port send_to; 372 IP_Port send_to;
365 memcpy(&send_to, plain, sizeof(IP_Port)); 373 ipport_unpack(&send_to, plain);
366 374
367 uint8_t data[MAX_ONION_SIZE]; 375 uint8_t data[ONION_MAX_PACKET_SIZE];
368 data[0] = NET_PACKET_ONION_RECV_1; 376 data[0] = NET_PACKET_ONION_RECV_1;
369 memcpy(data + 1, plain + sizeof(IP_Port), RETURN_1); 377 memcpy(data + 1, plain + SIZE_IPPORT, RETURN_1);
370 memcpy(data + 1 + RETURN_1, packet + 1 + RETURN_2, length - (1 + RETURN_2)); 378 memcpy(data + 1 + RETURN_1, packet + 1 + RETURN_2, length - (1 + RETURN_2));
371 uint32_t data_len = 1 + RETURN_1 + (length - (1 + RETURN_2)); 379 uint32_t data_len = 1 + RETURN_1 + (length - (1 + RETURN_2));
372 380
@@ -380,7 +388,7 @@ static int handle_recv_1(void *object, IP_Port source, uint8_t *packet, uint32_t
380{ 388{
381 Onion *onion = object; 389 Onion *onion = object;
382 390
383 if (length > MAX_ONION_SIZE) 391 if (length > ONION_MAX_PACKET_SIZE)
384 return 1; 392 return 1;
385 393
386 if (length <= 1 + RETURN_1) 394 if (length <= 1 + RETURN_1)
@@ -388,14 +396,16 @@ static int handle_recv_1(void *object, IP_Port source, uint8_t *packet, uint32_t
388 396
389 change_symmetric_key(onion); 397 change_symmetric_key(onion);
390 398
391 IP_Port send_to; 399 uint8_t plain[SIZE_IPPORT];
392 400 int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
393 int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + crypto_secretbox_NONCEBYTES, 401 SIZE_IPPORT + crypto_box_MACBYTES, plain);
394 sizeof(IP_Port) + crypto_secretbox_MACBYTES, (uint8_t *) &send_to);
395 402
396 if ((uint32_t)len != sizeof(IP_Port)) 403 if ((uint32_t)len != SIZE_IPPORT)
397 return 1; 404 return 1;
398 405
406 IP_Port send_to;
407 ipport_unpack(&send_to, plain);
408
399 uint32_t data_len = length - (1 + RETURN_1); 409 uint32_t data_len = length - (1 + RETURN_1);
400 410
401 if (onion->recv_1_function && send_to.ip.family != AF_INET && send_to.ip.family != AF_INET6) 411 if (onion->recv_1_function && send_to.ip.family != AF_INET && send_to.ip.family != AF_INET6)
@@ -424,7 +434,7 @@ Onion *new_onion(DHT *dht)
424 return NULL; 434 return NULL;
425 435
426 onion->dht = dht; 436 onion->dht = dht;
427 onion->net = dht->c->lossless_udp->net; 437 onion->net = dht->net;
428 new_symmetric_key(onion->secret_symmetric_key); 438 new_symmetric_key(onion->secret_symmetric_key);
429 onion->timestamp = unix_time(); 439 onion->timestamp = unix_time();
430 440
diff --git a/toxcore/onion.h b/toxcore/onion.h
index 4e363724..13dc8f52 100644
--- a/toxcore/onion.h
+++ b/toxcore/onion.h
@@ -28,7 +28,7 @@
28typedef struct { 28typedef struct {
29 DHT *dht; 29 DHT *dht;
30 Networking_Core *net; 30 Networking_Core *net;
31 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; 31 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
32 uint64_t timestamp; 32 uint64_t timestamp;
33 33
34 Shared_Keys shared_keys_1; 34 Shared_Keys shared_keys_1;
@@ -39,15 +39,20 @@ typedef struct {
39 void *callback_object; 39 void *callback_object;
40} Onion; 40} Onion;
41 41
42#define ONION_RETURN_1 (crypto_secretbox_NONCEBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES) 42#define ONION_MAX_PACKET_SIZE 1400
43#define ONION_RETURN_2 (crypto_secretbox_NONCEBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES + ONION_RETURN_1)
44#define ONION_RETURN_3 (crypto_secretbox_NONCEBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES + ONION_RETURN_2)
45 43
46#define ONION_SEND_BASE (crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_box_MACBYTES) 44#define ONION_RETURN_1 (crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_MACBYTES)
45#define ONION_RETURN_2 (crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_MACBYTES + ONION_RETURN_1)
46#define ONION_RETURN_3 (crypto_box_NONCEBYTES + SIZE_IPPORT + crypto_box_MACBYTES + ONION_RETURN_2)
47
48#define ONION_SEND_BASE (crypto_box_PUBLICKEYBYTES + SIZE_IPPORT + crypto_box_MACBYTES)
47#define ONION_SEND_3 (crypto_box_NONCEBYTES + ONION_SEND_BASE + ONION_RETURN_2) 49#define ONION_SEND_3 (crypto_box_NONCEBYTES + ONION_SEND_BASE + ONION_RETURN_2)
48#define ONION_SEND_2 (crypto_box_NONCEBYTES + ONION_SEND_BASE*2 + ONION_RETURN_1) 50#define ONION_SEND_2 (crypto_box_NONCEBYTES + ONION_SEND_BASE*2 + ONION_RETURN_1)
49#define ONION_SEND_1 (crypto_box_NONCEBYTES + ONION_SEND_BASE*3) 51#define ONION_SEND_1 (crypto_box_NONCEBYTES + ONION_SEND_BASE*3)
50 52
53#define ONION_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1))
54#define ONION_RESPONSE_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (1 + ONION_RETURN_3))
55
51typedef struct { 56typedef struct {
52 uint8_t shared_key1[crypto_box_BEFORENMBYTES]; 57 uint8_t shared_key1[crypto_box_BEFORENMBYTES];
53 uint8_t shared_key2[crypto_box_BEFORENMBYTES]; 58 uint8_t shared_key2[crypto_box_BEFORENMBYTES];
@@ -76,6 +81,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes);
76/* Create and send a onion packet. 81/* Create and send a onion packet.
77 * 82 *
78 * Use Onion_Path path to send data of length to dest. 83 * Use Onion_Path path to send data of length to dest.
84 * Maximum length of data is ONION_MAX_DATA_SIZE.
79 * 85 *
80 * return -1 on failure. 86 * return -1 on failure.
81 * return 0 on success. 87 * return 0 on success.
@@ -83,6 +89,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes);
83int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length); 89int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length);
84 90
85/* Create and send a onion response sent initially to dest with. 91/* Create and send a onion response sent initially to dest with.
92 * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
86 * 93 *
87 * return -1 on failure. 94 * return -1 on failure.
88 * return 0 on success. 95 * return 0 on success.
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 331e54d8..e6489a67 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -32,7 +32,7 @@
32#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) 32#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
33#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) 33#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
34 34
35#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 35#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE
36#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) 36#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3)
37 37
38/* Create and send an onion announce request packet. 38/* Create and send an onion announce request packet.
@@ -50,14 +50,14 @@
50 * return 0 on success. 50 * return 0 on success.
51 */ 51 */
52int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, 52int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key,
53 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data) 53 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint64_t sendback_data)
54{ 54{
55 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 55 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
56 memcpy(plain, ping_id, ONION_PING_ID_SIZE); 56 memcpy(plain, ping_id, ONION_PING_ID_SIZE);
57 memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES); 57 memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
58 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES); 58 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES);
59 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, sendback_data, 59 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, &sendback_data,
60 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); 60 sizeof(sendback_data));
61 uint8_t packet[ANNOUNCE_REQUEST_SIZE]; 61 uint8_t packet[ANNOUNCE_REQUEST_SIZE];
62 packet[0] = NET_PACKET_ANNOUNCE_REQUEST; 62 packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
63 random_nonce(packet + 1); 63 random_nonce(packet + 1);
@@ -90,6 +90,9 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
90int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, 90int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key,
91 uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length) 91 uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length)
92{ 92{
93 if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE)
94 return -1;
95
93 uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; 96 uint8_t packet[DATA_REQUEST_MIN_SIZE + length];
94 packet[0] = NET_PACKET_ONION_DATA_REQUEST; 97 packet[0] = NET_PACKET_ONION_DATA_REQUEST;
95 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 98 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
@@ -115,11 +118,11 @@ static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *pu
115 uint8_t *ping_id) 118 uint8_t *ping_id)
116{ 119{
117 time /= PING_ID_TIMEOUT; 120 time /= PING_ID_TIMEOUT;
118 uint8_t data[crypto_secretbox_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + sizeof(ret_ip_port)]; 121 uint8_t data[crypto_box_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + sizeof(ret_ip_port)];
119 memcpy(data, onion_a->secret_bytes, crypto_secretbox_KEYBYTES); 122 memcpy(data, onion_a->secret_bytes, crypto_box_KEYBYTES);
120 memcpy(data + crypto_secretbox_KEYBYTES, &time, sizeof(time)); 123 memcpy(data + crypto_box_KEYBYTES, &time, sizeof(time));
121 memcpy(data + crypto_secretbox_KEYBYTES + sizeof(time), public_key, crypto_box_PUBLICKEYBYTES); 124 memcpy(data + crypto_box_KEYBYTES + sizeof(time), public_key, crypto_box_PUBLICKEYBYTES);
122 memcpy(data + crypto_secretbox_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES, &ret_ip_port, sizeof(ret_ip_port)); 125 memcpy(data + crypto_box_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES, &ret_ip_port, sizeof(ret_ip_port));
123 crypto_hash_sha256(ping_id, data, sizeof(data)); 126 crypto_hash_sha256(ping_id, data, sizeof(data));
124} 127}
125 128
@@ -221,9 +224,9 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
221 get_shared_key(&onion_a->shared_keys_recv, shared_key, onion_a->dht->self_secret_key, packet_public_key); 224 get_shared_key(&onion_a->shared_keys_recv, shared_key, onion_a->dht->self_secret_key, packet_public_key);
222 225
223 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 226 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
224 int len = decrypt_data_fast(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 227 int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
225 ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + 228 ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH +
226 crypto_box_MACBYTES, plain); 229 crypto_box_MACBYTES, plain);
227 230
228 if ((uint32_t)len != sizeof(plain)) 231 if ((uint32_t)len != sizeof(plain))
229 return 1; 232 return 1;
@@ -247,14 +250,8 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
247 250
248 /*Respond with a announce response packet*/ 251 /*Respond with a announce response packet*/
249 Node_format nodes_list[MAX_SENT_NODES]; 252 Node_format nodes_list[MAX_SENT_NODES];
250 uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, source.ip.family, 253 uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, 0, LAN_ip(source.ip) == 0,
251 LAN_ip(source.ip) == 0, 1); 254 1);
252
253 uint32_t i;
254
255 for (i = 0; i < num_nodes; ++i)
256 to_net_family(&nodes_list[i].ip_port.ip);
257
258 uint8_t nonce[crypto_box_NONCEBYTES]; 255 uint8_t nonce[crypto_box_NONCEBYTES];
259 random_nonce(nonce); 256 random_nonce(nonce);
260 257
@@ -274,13 +271,20 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
274 } 271 }
275 } 272 }
276 273
277 memcpy(pl + 1 + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); 274 int nodes_length = 0;
275
276 if (num_nodes != 0) {
277 nodes_length = pack_nodes(pl + 1 + ONION_PING_ID_SIZE, sizeof(nodes_list), nodes_list, num_nodes);
278
279 if (nodes_length <= 0)
280 return 1;
281 }
278 282
279 uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; 283 uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
280 len = encrypt_data_fast(shared_key, nonce, pl, 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), 284 len = encrypt_data_symmetric(shared_key, nonce, pl, 1 + ONION_PING_ID_SIZE + nodes_length,
281 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); 285 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES);
282 286
283 if ((uint32_t)len != 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) 287 if (len != 1 + ONION_PING_ID_SIZE + nodes_length + crypto_box_MACBYTES)
284 return 1; 288 return 1;
285 289
286 data[0] = NET_PACKET_ANNOUNCE_RESPONSE; 290 data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
@@ -303,7 +307,7 @@ static int handle_data_request(void *object, IP_Port source, uint8_t *packet, ui
303 if (length <= DATA_REQUEST_MIN_SIZE_RECV) 307 if (length <= DATA_REQUEST_MIN_SIZE_RECV)
304 return 1; 308 return 1;
305 309
306 if (length >= MAX_DATA_SIZE) 310 if (length > ONION_MAX_PACKET_SIZE)
307 return 1; 311 return 1;
308 312
309 int index = in_entries(onion_a, packet + 1); 313 int index = in_entries(onion_a, packet + 1);
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index b7e08363..ea320998 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -29,7 +29,7 @@
29#define ONION_ANNOUNCE_TIMEOUT 300 29#define ONION_ANNOUNCE_TIMEOUT 300
30#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES 30#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
31 31
32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES) 32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (sizeof(uint64_t))
33 33
34#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + 1 + ONION_PING_ID_SIZE + crypto_box_MACBYTES) 34#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + 1 + ONION_PING_ID_SIZE + crypto_box_MACBYTES)
35#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) 35#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
@@ -40,6 +40,9 @@
40#error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES 40#error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES
41#endif 41#endif
42 42
43#define ONION_DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
44#define MAX_DATA_REQUEST_SIZE (ONION_MAX_DATA_SIZE - ONION_DATA_REQUEST_MIN_SIZE)
45
43typedef struct { 46typedef struct {
44 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 47 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
45 IP_Port ret_ip_port; 48 IP_Port ret_ip_port;
@@ -52,8 +55,8 @@ typedef struct {
52 DHT *dht; 55 DHT *dht;
53 Networking_Core *net; 56 Networking_Core *net;
54 Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; 57 Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
55 /* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */ 58 /* This is crypto_box_KEYBYTES long just so we can use new_symmetric_key() to fill it */
56 uint8_t secret_bytes[crypto_secretbox_KEYBYTES]; 59 uint8_t secret_bytes[crypto_box_KEYBYTES];
57 60
58 Shared_Keys shared_keys_recv; 61 Shared_Keys shared_keys_recv;
59} Onion_Announce; 62} Onion_Announce;
@@ -73,7 +76,7 @@ typedef struct {
73 * return 0 on success. 76 * return 0 on success.
74 */ 77 */
75int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, 78int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key,
76 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data); 79 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint64_t sendback_data);
77 80
78/* Create and send an onion data request packet. 81/* Create and send an onion data request packet.
79 * 82 *
@@ -86,6 +89,8 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
86 * 89 *
87 * nonce is the nonce to encrypt this packet with 90 * nonce is the nonce to encrypt this packet with
88 * 91 *
92 * The maximum length of data is MAX_DATA_REQUEST_SIZE.
93 *
89 * return -1 on failure. 94 * return -1 on failure.
90 * return 0 on success. 95 * return 0 on success.
91 */ 96 */
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 329b1d13..dfdb1638 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -28,8 +28,37 @@
28#include "util.h" 28#include "util.h"
29#include "LAN_discovery.h" 29#include "LAN_discovery.h"
30 30
31/* defines for the array size and
32 timeout for onion announce packets. */
33#define ANNOUNCE_ARRAY_SIZE 256
31#define ANNOUNCE_TIMEOUT 10 34#define ANNOUNCE_TIMEOUT 10
32 35
36
37/*
38 * return -1 if nodes are suitable for creating a new path.
39 * return path number of already existing similar path if one already exists.
40 */
41static int is_path_used(Onion_Client_Paths *onion_paths, Node_format *nodes)
42{
43 uint32_t i;
44
45 for (i = 0; i < NUMBER_ONION_PATHS; ++i) {
46 if (is_timeout(onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
47 continue;
48 }
49
50 if (is_timeout(onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) {
51 continue;
52 }
53
54 if (ipport_equal(&onion_paths->paths[i].ip_port1, &nodes[0].ip_port)) {
55 return i;
56 }
57 }
58
59 return -1;
60}
61
33/* Create a new path or use an old suitable one (if pathnum is valid) 62/* Create a new path or use an old suitable one (if pathnum is valid)
34 * or a rondom one from onion_paths. 63 * or a rondom one from onion_paths.
35 * 64 *
@@ -51,11 +80,17 @@ static int random_path(DHT *dht, Onion_Client_Paths *onion_paths, uint32_t pathn
51 if (random_nodes_path(dht, nodes, 3) != 3) 80 if (random_nodes_path(dht, nodes, 3) != 3)
52 return -1; 81 return -1;
53 82
54 if (create_onion_path(dht, &onion_paths->paths[pathnum], nodes) == -1) 83 int n = is_path_used(onion_paths, nodes);
55 return -1;
56 84
57 onion_paths->last_path_success[pathnum] = unix_time() + ONION_PATH_FIRST_TIMEOUT - ONION_PATH_TIMEOUT; 85 if (n == -1) {
58 onion_paths->path_creation_time[pathnum] = unix_time(); 86 if (create_onion_path(dht, &onion_paths->paths[pathnum], nodes) == -1)
87 return -1;
88
89 onion_paths->last_path_success[pathnum] = unix_time() + ONION_PATH_FIRST_TIMEOUT - ONION_PATH_TIMEOUT;
90 onion_paths->path_creation_time[pathnum] = unix_time();
91 } else {
92 pathnum = n;
93 }
59 } 94 }
60 95
61 memcpy(path, &onion_paths->paths[pathnum], sizeof(Onion_Path)); 96 memcpy(path, &onion_paths->paths[pathnum], sizeof(Onion_Path));
@@ -105,20 +140,15 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, IP_Port s
105 * return 0 on success 140 * return 0 on success
106 * 141 *
107 */ 142 */
108static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, uint8_t *sendback) 143static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, uint64_t *sendback)
109{ 144{
110 uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)]; 145 uint8_t data[sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)];
111 uint64_t time = unix_time(); 146 memcpy(data, &num, sizeof(uint32_t));
112 random_nonce(sendback); 147 memcpy(data + sizeof(uint32_t), public_key, crypto_box_PUBLICKEYBYTES);
113 memcpy(plain, &num, sizeof(uint32_t)); 148 memcpy(data + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES, &ip_port, sizeof(IP_Port));
114 memcpy(plain + sizeof(uint32_t), &time, sizeof(uint64_t)); 149 *sendback = ping_array_add(&onion_c->announce_ping_array, data, sizeof(data));
115 memcpy(plain + sizeof(uint32_t) + sizeof(uint64_t), public_key, crypto_box_PUBLICKEYBYTES);
116 memcpy(plain + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, &ip_port, sizeof(IP_Port));
117
118 int len = encrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, plain, sizeof(plain),
119 sendback + crypto_secretbox_NONCEBYTES);
120 150
121 if ((uint32_t)len + crypto_secretbox_NONCEBYTES != ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) 151 if (*sendback == 0)
122 return -1; 152 return -1;
123 153
124 return 0; 154 return 0;
@@ -136,24 +166,17 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key
136 */ 166 */
137static uint32_t check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *ret_pubkey, IP_Port *ret_ip_port) 167static uint32_t check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *ret_pubkey, IP_Port *ret_ip_port)
138{ 168{
139 uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)]; 169 uint64_t sback;
140 int len = decrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, sendback + crypto_secretbox_NONCEBYTES, 170 memcpy(&sback, sendback, sizeof(uint64_t));
141 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH - crypto_secretbox_NONCEBYTES, plain); 171 uint8_t data[sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)];
142 172
143 if ((uint32_t)len != sizeof(plain)) 173 if (ping_array_check(data, sizeof(data), &onion_c->announce_ping_array, sback) != sizeof(data))
144 return ~0;
145
146 uint64_t timestamp;
147 memcpy(&timestamp, plain + sizeof(uint32_t), sizeof(uint64_t));
148 uint64_t temp_time = unix_time();
149
150 if (timestamp + ANNOUNCE_TIMEOUT < temp_time || temp_time < timestamp)
151 return ~0; 174 return ~0;
152 175
153 memcpy(ret_pubkey, plain + sizeof(uint32_t) + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES); 176 memcpy(ret_pubkey, data + sizeof(uint32_t), crypto_box_PUBLICKEYBYTES);
154 memcpy(ret_ip_port, plain + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(IP_Port)); 177 memcpy(ret_ip_port, data + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES, sizeof(IP_Port));
155 uint32_t num; 178 uint32_t num;
156 memcpy(&num, plain, sizeof(uint32_t)); 179 memcpy(&num, data, sizeof(uint32_t));
157 return num; 180 return num;
158} 181}
159 182
@@ -163,9 +186,9 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
163 if (num > onion_c->num_friends) 186 if (num > onion_c->num_friends)
164 return -1; 187 return -1;
165 188
166 uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 189 uint64_t sendback;
167 190
168 if (new_sendback(onion_c, num, dest_pubkey, dest, sendback) == -1) 191 if (new_sendback(onion_c, num, dest_pubkey, dest, &sendback) == -1)
169 return -1; 192 return -1;
170 193
171 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0}; 194 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
@@ -183,9 +206,9 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
183 if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1) 206 if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1)
184 return -1; 207 return -1;
185 208
186 return send_announce_request(onion_c->net, &path, dest_node, onion_c->dht->c->self_public_key, 209 return send_announce_request(onion_c->net, &path, dest_node, onion_c->c->self_public_key,
187 onion_c->dht->c->self_secret_key, ping_id, 210 onion_c->c->self_secret_key, ping_id,
188 onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback); 211 onion_c->c->self_public_key, onion_c->temp_public_key, sendback);
189 } else { 212 } else {
190 if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1) 213 if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1)
191 return -1; 214 return -1;
@@ -236,7 +259,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
236 259
237 if (num == 0) { 260 if (num == 0) {
238 list_nodes = onion_c->clients_announce_list; 261 list_nodes = onion_c->clients_announce_list;
239 reference_id = onion_c->dht->c->self_public_key; 262 reference_id = onion_c->c->self_public_key;
240 263
241 if (is_stored && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) { 264 if (is_stored && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
242 is_stored = 0; 265 is_stored = 0;
@@ -253,16 +276,9 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
253 int index = -1; 276 int index = -1;
254 uint32_t i; 277 uint32_t i;
255 278
256 for (i = 0; i < MAX_ONION_CLIENTS; ++i) { 279 if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
257 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT) 280 || id_closest(reference_id, list_nodes[0].client_id, public_key) == 2) {
258 || id_closest(reference_id, list_nodes[i].client_id, public_key) == 2) { 281 index = 0;
259 index = i;
260
261 if (i != 0)
262 break;
263 } else {
264 break;
265 }
266 } 282 }
267 283
268 for (i = 0; i < MAX_ONION_CLIENTS; ++i) { 284 for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
@@ -286,7 +302,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
286 302
287 list_nodes[index].is_stored = is_stored; 303 list_nodes[index].is_stored = is_stored;
288 list_nodes[index].timestamp = unix_time(); 304 list_nodes[index].timestamp = unix_time();
289 list_nodes[index].last_pinged = unix_time(); 305 list_nodes[index].last_pinged = 0;
290 list_nodes[index].path_used = set_path_timeouts(onion_c, num, source); 306 list_nodes[index].path_used = set_path_timeouts(onion_c, num, source);
291 return 0; 307 return 0;
292} 308}
@@ -318,21 +334,18 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
318 334
319 Onion_Node *list_nodes = NULL; 335 Onion_Node *list_nodes = NULL;
320 uint8_t *reference_id = NULL; 336 uint8_t *reference_id = NULL;
321 uint32_t *ping_nodes_sent_second = NULL;
322 337
323 Last_Pinged *last_pinged = NULL; 338 Last_Pinged *last_pinged = NULL;
324 uint8_t *last_pinged_index = NULL; 339 uint8_t *last_pinged_index = NULL;
325 340
326 if (num == 0) { 341 if (num == 0) {
327 list_nodes = onion_c->clients_announce_list; 342 list_nodes = onion_c->clients_announce_list;
328 reference_id = onion_c->dht->c->self_public_key; 343 reference_id = onion_c->c->self_public_key;
329 ping_nodes_sent_second = &onion_c->ping_nodes_sent_second;
330 last_pinged = onion_c->last_pinged; 344 last_pinged = onion_c->last_pinged;
331 last_pinged_index = &onion_c->last_pinged_index; 345 last_pinged_index = &onion_c->last_pinged_index;
332 } else { 346 } else {
333 list_nodes = onion_c->friends_list[num - 1].clients_list; 347 list_nodes = onion_c->friends_list[num - 1].clients_list;
334 reference_id = onion_c->friends_list[num - 1].real_client_id; 348 reference_id = onion_c->friends_list[num - 1].real_client_id;
335 ping_nodes_sent_second = &onion_c->friends_list[num - 1].ping_nodes_sent_second;
336 last_pinged = onion_c->friends_list[num - 1].last_pinged; 349 last_pinged = onion_c->friends_list[num - 1].last_pinged;
337 last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index; 350 last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index;
338 } 351 }
@@ -342,11 +355,6 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
342 355
343 for (i = 0; i < num_nodes; ++i) { 356 for (i = 0; i < num_nodes; ++i) {
344 357
345 if (*ping_nodes_sent_second > MAX_PING_NODES_SECOND_PEER)
346 return 0;
347
348 to_host_family(&nodes[i].ip_port.ip);
349
350 if (!lan_ips_accepted) 358 if (!lan_ips_accepted)
351 if (LAN_ip(nodes[i].ip_port.ip) == 0) 359 if (LAN_ip(nodes[i].ip_port.ip) == 0)
352 continue; 360 continue;
@@ -361,8 +369,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
361 } 369 }
362 370
363 if (j == MAX_ONION_CLIENTS && good_to_ping(last_pinged, last_pinged_index, nodes[i].client_id)) { 371 if (j == MAX_ONION_CLIENTS && good_to_ping(last_pinged, last_pinged_index, nodes[i].client_id)) {
364 if (client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL, ~0) == 0) 372 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL, ~0);
365 ++*ping_nodes_sent_second;
366 } 373 }
367 } 374 }
368 } 375 }
@@ -377,10 +384,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
377 if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) 384 if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE)
378 return 1; 385 return 1;
379 386
380 if ((length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) % sizeof(Node_format) != 0) 387 uint16_t len_nodes = length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
381 return 1;
382
383 uint16_t num_nodes = (length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) / sizeof(Node_format);
384 388
385 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 389 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
386 IP_Port ip_port; 390 IP_Port ip_port;
@@ -389,11 +393,11 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
389 if (num > onion_c->num_friends) 393 if (num > onion_c->num_friends)
390 return 1; 394 return 1;
391 395
392 uint8_t plain[1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; 396 uint8_t plain[1 + ONION_PING_ID_SIZE + len_nodes];
393 int len = -1; 397 int len = -1;
394 398
395 if (num == 0) { 399 if (num == 0) {
396 len = decrypt_data(public_key, onion_c->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, 400 len = decrypt_data(public_key, onion_c->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
397 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, 401 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES,
398 length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain); 402 length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain);
399 } else { 403 } else {
@@ -409,20 +413,24 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
409 if ((uint32_t)len != sizeof(plain)) 413 if ((uint32_t)len != sizeof(plain))
410 return 1; 414 return 1;
411 415
412
413 if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, source) == -1) 416 if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, source) == -1)
414 return 1; 417 return 1;
415 418
416 Node_format nodes[MAX_SENT_NODES]; 419 if (len_nodes != 0) {
417 memcpy(nodes, plain + 1 + ONION_PING_ID_SIZE, num_nodes * sizeof(Node_format)); 420 Node_format nodes[MAX_SENT_NODES];
421 int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, plain + 1 + ONION_PING_ID_SIZE, len_nodes, 0);
418 422
419 if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) 423 if (num_nodes <= 0)
420 return 1; 424 return 1;
425
426 if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1)
427 return 1;
428 }
421 429
422 return 0; 430 return 0;
423} 431}
424 432
425#define DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 433#define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE
426 434
427static int handle_data_response(void *object, IP_Port source, uint8_t *packet, uint32_t length) 435static int handle_data_response(void *object, IP_Port source, uint8_t *packet, uint32_t length)
428{ 436{
@@ -431,7 +439,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
431 if (length <= (ONION_DATA_RESPONSE_MIN_SIZE + DATA_IN_RESPONSE_MIN_SIZE)) 439 if (length <= (ONION_DATA_RESPONSE_MIN_SIZE + DATA_IN_RESPONSE_MIN_SIZE))
432 return 1; 440 return 1;
433 441
434 if (length > MAX_DATA_SIZE) 442 if (length > MAX_DATA_REQUEST_SIZE)
435 return 1; 443 return 1;
436 444
437 uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE]; 445 uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE];
@@ -443,7 +451,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
443 return 1; 451 return 1;
444 452
445 uint8_t plain[sizeof(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE]; 453 uint8_t plain[sizeof(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE];
446 len = decrypt_data(temp_plain, onion_c->dht->c->self_secret_key, packet + 1, temp_plain + crypto_box_PUBLICKEYBYTES, 454 len = decrypt_data(temp_plain, onion_c->c->self_secret_key, packet + 1, temp_plain + crypto_box_PUBLICKEYBYTES,
447 sizeof(temp_plain) - crypto_box_PUBLICKEYBYTES, plain); 455 sizeof(temp_plain) - crypto_box_PUBLICKEYBYTES, plain);
448 456
449 if ((uint32_t)len != sizeof(plain)) 457 if ((uint32_t)len != sizeof(plain))
@@ -469,9 +477,6 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
469 if (length > FAKEID_DATA_MAX_LENGTH) 477 if (length > FAKEID_DATA_MAX_LENGTH)
470 return 1; 478 return 1;
471 479
472 if ((length - FAKEID_DATA_MIN_LENGTH) % sizeof(Node_format) != 0)
473 return 1;
474
475 int friend_num = onion_friend_num(onion_c, source_pubkey); 480 int friend_num = onion_friend_num(onion_c, source_pubkey);
476 481
477 if (friend_num == -1) 482 if (friend_num == -1)
@@ -485,37 +490,42 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
485 return 1; 490 return 1;
486 491
487 onion_c->friends_list[friend_num].last_noreplay = no_replay; 492 onion_c->friends_list[friend_num].last_noreplay = no_replay;
493 onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t), current_time_monotonic());
494 onion_c->friends_list[friend_num].last_seen = unix_time();
488 495
489 if (memcmp(data + 1 + sizeof(uint64_t), onion_c->friends_list[friend_num].fake_client_id, 496 uint16_t len_nodes = length - FAKEID_DATA_MIN_LENGTH;
490 crypto_box_PUBLICKEYBYTES) != 0) {
491 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
492 497
493 onion_c->friends_list[friend_num].last_seen = unix_time(); 498 if (len_nodes != 0) {
499 Node_format nodes[MAX_SENT_NODES];
500 int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES,
501 len_nodes, 1);
494 502
495 if (DHT_addfriend(onion_c->dht, data + 1 + sizeof(uint64_t)) == 1) { 503 if (num_nodes <= 0)
496 return 1; 504 return 1;
497 }
498 505
499 onion_c->friends_list[friend_num].is_fake_clientid = 1; 506 int i;
500 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
501 }
502 507
503 uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format); 508 for (i = 0; i < num_nodes; ++i) {
504 Node_format nodes[num_nodes]; 509 uint8_t family = nodes[i].ip_port.ip.family;
505 memcpy(nodes, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(nodes));
506 uint32_t i;
507 510
508 for (i = 0; i < num_nodes; ++i) { 511 if (family == AF_INET || family == AF_INET6) {
509 to_host_family(&nodes[i].ip_port.ip); 512 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
510 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); 513 } else if (family == TCP_INET || family == TCP_INET6) {
514 if (onion_c->friends_list[friend_num].tcp_relay_node_callback) {
515 void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
516 uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number;
517 onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].client_id);
518 }
519 }
520 }
511 } 521 }
512 522
513 return 0; 523 return 0;
514} 524}
515/* Send data of length length to friendnum. 525/* Send data of length length to friendnum.
516 * This data will be recieved by the friend using the Onion_Data_Handlers callbacks. 526 * This data will be received by the friend using the Onion_Data_Handlers callbacks.
517 * 527 *
518 * Even if this function succeeds, the friend might not recieve any data. 528 * Even if this function succeeds, the friend might not receive any data.
519 * 529 *
520 * return the number of packets sent on success 530 * return the number of packets sent on success
521 * return -1 on failure. 531 * return -1 on failure.
@@ -525,7 +535,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
525 if ((uint32_t)friend_num >= onion_c->num_friends) 535 if ((uint32_t)friend_num >= onion_c->num_friends)
526 return -1; 536 return -1;
527 537
528 if (length + DATA_IN_RESPONSE_MIN_SIZE + ONION_DATA_RESPONSE_MIN_SIZE + ONION_SEND_1 > MAX_DATA_SIZE) 538 if (length + DATA_IN_RESPONSE_MIN_SIZE > MAX_DATA_REQUEST_SIZE)
529 return -1; 539 return -1;
530 540
531 if (length == 0) 541 if (length == 0)
@@ -535,8 +545,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
535 random_nonce(nonce); 545 random_nonce(nonce);
536 546
537 uint8_t packet[DATA_IN_RESPONSE_MIN_SIZE + length]; 547 uint8_t packet[DATA_IN_RESPONSE_MIN_SIZE + length];
538 memcpy(packet, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES); 548 memcpy(packet, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES);
539 int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data, 549 int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data,
540 length, packet + crypto_box_PUBLICKEYBYTES); 550 length, packet + crypto_box_PUBLICKEYBYTES);
541 551
542 if ((uint32_t)len + crypto_box_PUBLICKEYBYTES != sizeof(packet)) 552 if ((uint32_t)len + crypto_box_PUBLICKEYBYTES != sizeof(packet))
@@ -578,7 +588,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
578 588
579/* Try to send the fakeid via the DHT instead of onion 589/* Try to send the fakeid via the DHT instead of onion
580 * 590 *
581 * Even if this function succeeds, the friend might not recieve any data. 591 * Even if this function succeeds, the friend might not receive any data.
582 * 592 *
583 * return the number of packets sent on success 593 * return the number of packets sent on success
584 * return -1 on failure. 594 * return -1 on failure.
@@ -595,15 +605,15 @@ static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data,
595 new_nonce(nonce); 605 new_nonce(nonce);
596 606
597 uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length]; 607 uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length];
598 memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES); 608 memcpy(temp, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES);
599 memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 609 memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
600 int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data, 610 int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data,
601 length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); 611 length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
602 612
603 if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp)) 613 if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp))
604 return -1; 614 return -1;
605 615
606 uint8_t packet[MAX_DATA_SIZE]; 616 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
607 len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet, 617 len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet,
608 onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID); 618 onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID);
609 619
@@ -624,14 +634,14 @@ static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubke
624 return 1; 634 return 1;
625 635
626 uint8_t plain[FAKEID_DATA_MAX_LENGTH]; 636 uint8_t plain[FAKEID_DATA_MAX_LENGTH];
627 int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES, 637 int len = decrypt_data(packet, onion_c->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
628 packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, 638 packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
629 length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain); 639 length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain);
630 640
631 if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)) 641 if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES))
632 return 1; 642 return 1;
633 643
634 if (memcpy(source_pubkey, packet, crypto_box_PUBLICKEYBYTES) != 0) 644 if (memcmp(source_pubkey, plain + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES) != 0)
635 return 1; 645 return 1;
636 646
637 return handle_fakeid_announce(onion_c, packet, plain, len); 647 return handle_fakeid_announce(onion_c, packet, plain, len);
@@ -657,20 +667,26 @@ static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint
657 memcpy(data + 1, &no_replay, sizeof(no_replay)); 667 memcpy(data + 1, &no_replay, sizeof(no_replay));
658 memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); 668 memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
659 Node_format nodes[MAX_SENT_NODES]; 669 Node_format nodes[MAX_SENT_NODES];
660 uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES); 670 uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2));
661 uint32_t i; 671 uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays);
672 num_nodes += num_relays;
673 int nodes_len = 0;
674
675 if (num_nodes != 0) {
676 nodes_len = pack_nodes(data + FAKEID_DATA_MIN_LENGTH, FAKEID_DATA_MAX_LENGTH - FAKEID_DATA_MIN_LENGTH, nodes,
677 num_nodes);
662 678
663 for (i = 0; i < num_nodes; ++i) 679 if (nodes_len <= 0)
664 to_net_family(&nodes[i].ip_port.ip); 680 return -1;
681 }
665 682
666 memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes);
667 int num1 = -1, num2 = -1; 683 int num1 = -1, num2 = -1;
668 684
669 if (onion_dht_both != 1) 685 if (onion_dht_both != 1)
670 num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); 686 num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len);
671 687
672 if (onion_dht_both != 0) 688 if (onion_dht_both != 0)
673 num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); 689 num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + nodes_len);
674 690
675 if (num1 == -1) 691 if (num1 == -1)
676 return num2; 692 return num2;
@@ -788,14 +804,34 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
788 return friend_num; 804 return friend_num;
789} 805}
790 806
791/* Get the ip of friend friendnum and put it in ip_port 807/* Set the function for this friend that will be callbacked with object and number
808 * when that friends gives us one of the TCP relays he is connected to.
792 * 809 *
793 * return -1, -- if client_id does NOT refer to a friend 810 * object and number will be passed as argument to this function.
794 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
795 * return 1, ip if client_id refers to a friend and we found him
796 * 811 *
812 * return -1 on failure.
813 * return 0 on success.
797 */ 814 */
798int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) 815int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
816 uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number)
817{
818 if ((uint32_t)friend_num >= onion_c->num_friends)
819 return -1;
820
821 onion_c->friends_list[friend_num].tcp_relay_node_callback = tcp_relay_node_callback;
822 onion_c->friends_list[friend_num].tcp_relay_node_callback_object = object;
823 onion_c->friends_list[friend_num].tcp_relay_node_callback_number = number;
824 return 0;
825}
826
827/* Set a friends DHT public key.
828 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
829 * the other peer.
830 *
831 * return -1 on failure.
832 * return 0 on success.
833 */
834int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key, uint64_t timestamp)
799{ 835{
800 if ((uint32_t)friend_num >= onion_c->num_friends) 836 if ((uint32_t)friend_num >= onion_c->num_friends)
801 return -1; 837 return -1;
@@ -803,12 +839,67 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
803 if (onion_c->friends_list[friend_num].status == 0) 839 if (onion_c->friends_list[friend_num].status == 0)
804 return -1; 840 return -1;
805 841
842 if (onion_c->friends_list[friend_num].fake_client_id_timestamp >= timestamp)
843 return -1;
844
845 if (onion_c->friends_list[friend_num].is_fake_clientid) {
846 if (memcmp(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES) == 0) {
847 return -1;
848 }
849
850 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
851 }
852
853 if (DHT_addfriend(onion_c->dht, dht_key) == 1) {
854 return -1;
855 }
856
857 onion_c->friends_list[friend_num].last_seen = unix_time();
858 onion_c->friends_list[friend_num].is_fake_clientid = 1;
859 onion_c->friends_list[friend_num].fake_client_id_timestamp = timestamp;
860 memcpy(onion_c->friends_list[friend_num].fake_client_id, dht_key, crypto_box_PUBLICKEYBYTES);
861
862 return 0;
863}
864
865/* Copy friends DHT public key into dht_key.
866 *
867 * return 0 on failure (no key copied).
868 * return timestamp on success (key copied).
869 */
870uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
871{
872 if ((uint32_t)friend_num >= onion_c->num_friends)
873 return 0;
874
875 if (onion_c->friends_list[friend_num].status == 0)
876 return 0;
877
806 if (!onion_c->friends_list[friend_num].is_fake_clientid) 878 if (!onion_c->friends_list[friend_num].is_fake_clientid)
879 return 0;
880
881 memcpy(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES);
882 return onion_c->friends_list[friend_num].fake_client_id_timestamp;
883}
884
885/* Get the ip of friend friendnum and put it in ip_port
886 *
887 * return -1, -- if client_id does NOT refer to a friend
888 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
889 * return 1, ip if client_id refers to a friend and we found him
890 *
891 */
892int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
893{
894 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
895
896 if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) == 0)
807 return -1; 897 return -1;
808 898
809 return DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port); 899 return DHT_getfriendip(onion_c->dht, dht_public_key, ip_port);
810} 900}
811 901
902
812/* Set if friend is online or not. 903/* Set if friend is online or not.
813 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online. 904 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
814 * 905 *
@@ -856,6 +947,11 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
856 947
857 ++count; 948 ++count;
858 949
950 if (list_nodes[i].last_pinged == 0) {
951 list_nodes[i].last_pinged = unix_time();
952 continue;
953 }
954
859 if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) { 955 if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) {
860 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) { 956 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0, ~0) == 0) {
861 list_nodes[i].last_pinged = unix_time(); 957 list_nodes[i].last_pinged = unix_time();
@@ -924,6 +1020,13 @@ static void do_announce(Onion_Client *onion_c)
924 continue; 1020 continue;
925 1021
926 ++count; 1022 ++count;
1023
1024 /* Don't announce ourselves the first time this is run to new peers */
1025 if (list_nodes[i].last_pinged == 0) {
1026 list_nodes[i].last_pinged = 1;
1027 continue;
1028 }
1029
927 uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; 1030 uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
928 1031
929 if (list_nodes[i].is_stored) { 1032 if (list_nodes[i].is_stored) {
@@ -941,7 +1044,7 @@ static void do_announce(Onion_Client *onion_c)
941 if (count != MAX_ONION_CLIENTS) { 1044 if (count != MAX_ONION_CLIENTS) {
942 if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { 1045 if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) {
943 Node_format nodes_list[MAX_SENT_NODES]; 1046 Node_format nodes_list[MAX_SENT_NODES];
944 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list, 1047 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list,
945 rand() % 2 ? AF_INET : AF_INET6, 1, 0); 1048 rand() % 2 ? AF_INET : AF_INET6, 1, 0);
946 1049
947 for (i = 0; i < num_nodes; ++i) { 1050 for (i = 0; i < num_nodes; ++i) {
@@ -963,16 +1066,14 @@ void do_onion_client(Onion_Client *onion_c)
963 for (i = 0; i < onion_c->num_friends; ++i) { 1066 for (i = 0; i < onion_c->num_friends; ++i) {
964 do_friend(onion_c, i); 1067 do_friend(onion_c, i);
965 cleanup_friend(onion_c, i); 1068 cleanup_friend(onion_c, i);
966 onion_c->friends_list[i].ping_nodes_sent_second = 0;
967 } 1069 }
968 1070
969 onion_c->ping_nodes_sent_second = 0;
970 onion_c->last_run = unix_time(); 1071 onion_c->last_run = unix_time();
971} 1072}
972 1073
973Onion_Client *new_onion_client(DHT *dht) 1074Onion_Client *new_onion_client(Net_Crypto *c)
974{ 1075{
975 if (dht == NULL) 1076 if (c == NULL)
976 return NULL; 1077 return NULL;
977 1078
978 Onion_Client *onion_c = calloc(1, sizeof(Onion_Client)); 1079 Onion_Client *onion_c = calloc(1, sizeof(Onion_Client));
@@ -980,14 +1081,20 @@ Onion_Client *new_onion_client(DHT *dht)
980 if (onion_c == NULL) 1081 if (onion_c == NULL)
981 return NULL; 1082 return NULL;
982 1083
983 onion_c->dht = dht; 1084 if (ping_array_init(&onion_c->announce_ping_array, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT) != 0) {
984 onion_c->net = dht->c->lossless_udp->net; 1085 free(onion_c);
1086 return NULL;
1087 }
1088
1089 onion_c->dht = c->dht;
1090 onion_c->net = c->dht->net;
1091 onion_c->c = c;
985 new_symmetric_key(onion_c->secret_symmetric_key); 1092 new_symmetric_key(onion_c->secret_symmetric_key);
986 crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key); 1093 crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
987 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); 1094 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
988 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); 1095 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
989 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); 1096 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c);
990 cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c); 1097 cryptopacket_registerhandler(onion_c->dht, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
991 1098
992 return onion_c; 1099 return onion_c;
993} 1100}
@@ -997,11 +1104,12 @@ void kill_onion_client(Onion_Client *onion_c)
997 if (onion_c == NULL) 1104 if (onion_c == NULL)
998 return; 1105 return;
999 1106
1107 ping_array_free_all(&onion_c->announce_ping_array);
1000 realloc_onion_friends(onion_c, 0); 1108 realloc_onion_friends(onion_c, 0);
1001 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); 1109 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL);
1002 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); 1110 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
1003 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, NULL, NULL); 1111 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, NULL, NULL);
1004 cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, NULL, NULL); 1112 cryptopacket_registerhandler(onion_c->dht, FAKEID_DATA_ID, NULL, NULL);
1005 memset(onion_c, 0, sizeof(Onion_Client)); 1113 memset(onion_c, 0, sizeof(Onion_Client));
1006 free(onion_c); 1114 free(onion_c);
1007} 1115}
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index 4045cc0e..9cf6cf3e 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -25,6 +25,8 @@
25#define ONION_CLIENT_H 25#define ONION_CLIENT_H
26 26
27#include "onion_announce.h" 27#include "onion_announce.h"
28#include "net_crypto.h"
29#include "ping_array.h"
28 30
29#define MAX_ONION_CLIENTS 8 31#define MAX_ONION_CLIENTS 8
30#define ONION_NODE_PING_INTERVAL 30 32#define ONION_NODE_PING_INTERVAL 30
@@ -42,11 +44,6 @@
42#define ONION_PATH_TIMEOUT 30 44#define ONION_PATH_TIMEOUT 30
43#define ONION_PATH_MAX_LIFETIME 600 45#define ONION_PATH_MAX_LIFETIME 600
44 46
45/* A cheap way of making it take less bandwidth at startup:
46 by limiting the number of ping packets we can send per
47 second per peer. */
48#define MAX_PING_NODES_SECOND_PEER 5
49
50#define MAX_STORED_PINGED_NODES 9 47#define MAX_STORED_PINGED_NODES 9
51#define MIN_NODE_PING_TIME 10 48#define MIN_NODE_PING_TIME 10
52 49
@@ -80,6 +77,7 @@ typedef struct {
80 uint8_t is_online; /* Set by the onion_set_friend_status function. */ 77 uint8_t is_online; /* Set by the onion_set_friend_status function. */
81 78
82 uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */ 79 uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
80 uint64_t fake_client_id_timestamp;
83 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES]; 81 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
84 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES]; 82 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
85 83
@@ -95,16 +93,20 @@ typedef struct {
95 uint64_t last_seen; 93 uint64_t last_seen;
96 94
97 Onion_Client_Paths onion_paths; 95 Onion_Client_Paths onion_paths;
98 uint32_t ping_nodes_sent_second;
99 96
100 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; 97 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
101 uint8_t last_pinged_index; 98 uint8_t last_pinged_index;
99
100 int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key);
101 void *tcp_relay_node_callback_object;
102 uint32_t tcp_relay_node_callback_number;
102} Onion_Friend; 103} Onion_Friend;
103 104
104typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); 105typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
105 106
106typedef struct { 107typedef struct {
107 DHT *dht; 108 DHT *dht;
109 Net_Crypto *c;
108 Networking_Core *net; 110 Networking_Core *net;
109 Onion_Friend *friends_list; 111 Onion_Friend *friends_list;
110 uint16_t num_friends; 112 uint16_t num_friends;
@@ -113,15 +115,15 @@ typedef struct {
113 115
114 Onion_Client_Paths onion_paths; 116 Onion_Client_Paths onion_paths;
115 117
116 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; 118 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
117 uint64_t last_run; 119 uint64_t last_run;
118 120
119 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; 121 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
120 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 122 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
121 123
122 uint32_t ping_nodes_sent_second;
123
124 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; 124 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
125
126 Ping_Array announce_ping_array;
125 uint8_t last_pinged_index; 127 uint8_t last_pinged_index;
126 struct { 128 struct {
127 oniondata_handler_callback function; 129 oniondata_handler_callback function;
@@ -170,11 +172,41 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
170 */ 172 */
171int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); 173int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
172 174
175/* Set the function for this friend that will be callbacked with object and number
176 * when that friends gives us one of the TCP relays he is connected to.
177 *
178 * object and number will be passed as argument to this function.
179 *
180 * return -1 on failure.
181 * return 0 on success.
182 */
183int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
184 uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number);
185
186/* Set a friends DHT public key.
187 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
188 * the other peer.
189 *
190 * return -1 on failure.
191 * return 0 on success.
192 */
193int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key, uint64_t timestamp);
194
195/* Copy friends DHT public key into dht_key.
196 *
197 * return 0 on failure (no key copied).
198 * return timestamp on success (key copied).
199 */
200uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
201
202#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
203#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
173 204
174/* Send data of length length to friendnum. 205/* Send data of length length to friendnum.
175 * This data will be recieved by the friend using the Onion_Data_Handlers callbacks. 206 * Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE.
207 * This data will be received by the friend using the Onion_Data_Handlers callbacks.
176 * 208 *
177 * Even if this function succeeds, the friend might not recieve any data. 209 * Even if this function succeeds, the friend might not receive any data.
178 * 210 *
179 * return the number of packets sent on success 211 * return the number of packets sent on success
180 * return -1 on failure. 212 * return -1 on failure.
@@ -186,7 +218,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha
186 218
187void do_onion_client(Onion_Client *onion_c); 219void do_onion_client(Onion_Client *onion_c);
188 220
189Onion_Client *new_onion_client(DHT *dht); 221Onion_Client *new_onion_client(Net_Crypto *c);
190 222
191void kill_onion_client(Onion_Client *onion_c); 223void kill_onion_client(Onion_Client *onion_c);
192 224
diff --git a/toxcore/ping.c b/toxcore/ping.c
index 649d3fff..c01170ab 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -34,118 +34,29 @@
34 34
35#include "network.h" 35#include "network.h"
36#include "util.h" 36#include "util.h"
37#include "ping_array.h"
37 38
38#define PING_NUM_MAX 512 39#define PING_NUM_MAX 512
39 40
40/* Maximum newly announced nodes to ping per TIME_TO_PING seconds. */ 41/* Maximum newly announced nodes to ping per TIME_TO_PING seconds. */
41#define MAX_TO_PING 16 42#define MAX_TO_PING 8
42 43
43/* Ping newly announced nodes to ping per TIME_TO_PING seconds*/ 44/* Ping newly announced nodes to ping per TIME_TO_PING seconds*/
44#define TIME_TO_PING 5 45#define TIME_TO_PING 8
45 46
46typedef struct {
47 IP_Port ip_port;
48 uint64_t id;
49 uint64_t timestamp;
50 uint8_t shared_key[crypto_box_BEFORENMBYTES];
51} pinged_t;
52 47
53struct PING { 48struct PING {
54 DHT *dht; 49 DHT *dht;
55 50
56 pinged_t pings[PING_NUM_MAX]; 51 Ping_Array ping_array;
57 size_t num_pings;
58 size_t pos_pings;
59
60 Node_format to_ping[MAX_TO_PING]; 52 Node_format to_ping[MAX_TO_PING];
61 uint64_t last_to_ping; 53 uint64_t last_to_ping;
62}; 54};
63 55
64static int is_ping_timeout(uint64_t time)
65{
66 return is_timeout(time, PING_TIMEOUT);
67}
68
69static void remove_timeouts(PING *ping) // O(n)
70{
71 size_t i, id;
72 size_t new_pos = ping->pos_pings;
73 size_t new_num = ping->num_pings;
74
75 // Loop through buffer, oldest first.
76 for (i = 0; i < ping->num_pings; i++) {
77 id = (ping->pos_pings + i) % PING_NUM_MAX;
78
79 if (is_ping_timeout(ping->pings[id].timestamp)) {
80 new_pos++;
81 new_num--;
82 }
83 // Break here because list is sorted.
84 else {
85 break;
86 }
87 }
88
89 ping->num_pings = new_num;
90 ping->pos_pings = new_pos % PING_NUM_MAX;
91}
92
93static uint64_t add_ping(PING *ping, IP_Port ipp, uint8_t *shared_encryption_key) // O(n)
94{
95 size_t p;
96
97 remove_timeouts(ping);
98
99 /* Remove oldest ping if full buffer. */
100 if (ping->num_pings == PING_NUM_MAX) {
101 ping->num_pings--;
102 ping->pos_pings = (ping->pos_pings + 1) % PING_NUM_MAX;
103 }
104
105 /* Insert new ping at end of list. */
106 p = (ping->pos_pings + ping->num_pings) % PING_NUM_MAX;
107
108 ping->pings[p].ip_port = ipp;
109 ping->pings[p].timestamp = unix_time();
110 ping->pings[p].id = random_64b();
111 memcpy(ping->pings[p].shared_key, shared_encryption_key, crypto_box_BEFORENMBYTES);
112
113 ping->num_pings++;
114 return ping->pings[p].id;
115}
116
117/* checks if ip/port or ping_id are already in the list to ping
118 * if both are set, both must match, otherwise the set must match
119 *
120 * returns 0 if neither is set or no match was found
121 * returns the (index + 1) of the match if one was found
122 */
123static int is_pinging(PING *ping, IP_Port ipp, uint64_t ping_id)
124{
125 // O(n) TODO: Replace this with something else.
126
127 /* at least one MUST be set */
128 uint8_t ip_valid = ip_isset(&ipp.ip);
129
130 if (!ip_valid && !ping_id)
131 return 0;
132
133 size_t i;
134
135 remove_timeouts(ping);
136
137 for (i = 0; i < ping->num_pings; i++) {
138 size_t id = (ping->pos_pings + i) % PING_NUM_MAX;
139 56
140 if (!ping_id || (ping->pings[id].id == ping_id)) 57#define PING_PLAIN_SIZE (1 + sizeof(uint64_t))
141 if (!ip_valid || ipport_equal(&ping->pings[id].ip_port, &ipp)) 58#define DHT_PING_SIZE (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + PING_PLAIN_SIZE + crypto_box_MACBYTES)
142 return id + 1; 59#define PING_DATA_SIZE (CLIENT_ID_SIZE + sizeof(IP_Port))
143 }
144
145 return 0;
146}
147
148#define DHT_PING_SIZE (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(uint64_t) + crypto_box_MACBYTES)
149 60
150int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id) 61int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
151{ 62{
@@ -153,7 +64,7 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
153 int rc; 64 int rc;
154 uint64_t ping_id; 65 uint64_t ping_id;
155 66
156 if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->dht->self_public_key)) 67 if (id_equal(client_id, ping->dht->self_public_key))
157 return 1; 68 return 1;
158 69
159 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 70 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -161,19 +72,29 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
161 // generate key to encrypt ping_id with recipient privkey 72 // generate key to encrypt ping_id with recipient privkey
162 DHT_get_shared_key_sent(ping->dht, shared_key, client_id); 73 DHT_get_shared_key_sent(ping->dht, shared_key, client_id);
163 // Generate random ping_id. 74 // Generate random ping_id.
164 ping_id = add_ping(ping, ipp, shared_key); 75 uint8_t data[PING_DATA_SIZE];
76 id_copy(data, client_id);
77 memcpy(data + CLIENT_ID_SIZE, &ipp, sizeof(IP_Port));
78 ping_id = ping_array_add(&ping->ping_array, data, sizeof(data));
79
80 if (ping_id == 0)
81 return 1;
82
83 uint8_t ping_plain[PING_PLAIN_SIZE];
84 ping_plain[0] = NET_PACKET_PING_REQUEST;
85 memcpy(ping_plain + 1, &ping_id, sizeof(ping_id));
165 86
166 pk[0] = NET_PACKET_PING_REQUEST; 87 pk[0] = NET_PACKET_PING_REQUEST;
167 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey 88 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
168 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 89 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
169 90
170 91
171 rc = encrypt_data_fast(shared_key, 92 rc = encrypt_data_symmetric(shared_key,
172 pk + 1 + CLIENT_ID_SIZE, 93 pk + 1 + CLIENT_ID_SIZE,
173 (uint8_t *) &ping_id, sizeof(ping_id), 94 ping_plain, sizeof(ping_plain),
174 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 95 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
175 96
176 if (rc != sizeof(ping_id) + crypto_box_MACBYTES) 97 if (rc != PING_PLAIN_SIZE + crypto_box_MACBYTES)
177 return 1; 98 return 1;
178 99
179 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk)); 100 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
@@ -188,17 +109,21 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
188 if (id_equal(client_id, ping->dht->self_public_key)) 109 if (id_equal(client_id, ping->dht->self_public_key))
189 return 1; 110 return 1;
190 111
112 uint8_t ping_plain[PING_PLAIN_SIZE];
113 ping_plain[0] = NET_PACKET_PING_RESPONSE;
114 memcpy(ping_plain + 1, &ping_id, sizeof(ping_id));
115
191 pk[0] = NET_PACKET_PING_RESPONSE; 116 pk[0] = NET_PACKET_PING_RESPONSE;
192 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey 117 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
193 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 118 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
194 119
195 // Encrypt ping_id using recipient privkey 120 // Encrypt ping_id using recipient privkey
196 rc = encrypt_data_fast(shared_encryption_key, 121 rc = encrypt_data_symmetric(shared_encryption_key,
197 pk + 1 + CLIENT_ID_SIZE, 122 pk + 1 + CLIENT_ID_SIZE,
198 (uint8_t *) &ping_id, sizeof(ping_id), 123 ping_plain, sizeof(ping_plain),
199 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES ); 124 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES );
200 125
201 if (rc != sizeof(ping_id) + crypto_box_MACBYTES) 126 if (rc != PING_PLAIN_SIZE + crypto_box_MACBYTES)
202 return 1; 127 return 1;
203 128
204 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk)); 129 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
@@ -208,7 +133,6 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
208{ 133{
209 DHT *dht = _dht; 134 DHT *dht = _dht;
210 int rc; 135 int rc;
211 uint64_t ping_id;
212 136
213 if (length != DHT_PING_SIZE) 137 if (length != DHT_PING_SIZE)
214 return 1; 138 return 1;
@@ -220,17 +144,23 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
220 144
221 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 145 uint8_t shared_key[crypto_box_BEFORENMBYTES];
222 146
147 uint8_t ping_plain[PING_PLAIN_SIZE];
223 // Decrypt ping_id 148 // Decrypt ping_id
224 DHT_get_shared_key_recv(dht, shared_key, packet + 1); 149 DHT_get_shared_key_recv(dht, shared_key, packet + 1);
225 rc = decrypt_data_fast(shared_key, 150 rc = decrypt_data_symmetric(shared_key,
226 packet + 1 + CLIENT_ID_SIZE, 151 packet + 1 + CLIENT_ID_SIZE,
227 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 152 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
228 sizeof(ping_id) + crypto_box_MACBYTES, 153 PING_PLAIN_SIZE + crypto_box_MACBYTES,
229 (uint8_t *) &ping_id ); 154 ping_plain );
155
156 if (rc != sizeof(ping_plain))
157 return 1;
230 158
231 if (rc != sizeof(ping_id)) 159 if (ping_plain[0] != NET_PACKET_PING_REQUEST)
232 return 1; 160 return 1;
233 161
162 uint64_t ping_id;
163 memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
234 // Send response 164 // Send response
235 send_ping_response(ping, source, packet + 1, ping_id, shared_key); 165 send_ping_response(ping, source, packet + 1, ping_id, shared_key);
236 add_to_ping(ping, packet + 1, source); 166 add_to_ping(ping, packet + 1, source);
@@ -242,7 +172,6 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
242{ 172{
243 DHT *dht = _dht; 173 DHT *dht = _dht;
244 int rc; 174 int rc;
245 uint64_t ping_id;
246 175
247 if (length != DHT_PING_SIZE) 176 if (length != DHT_PING_SIZE)
248 return 1; 177 return 1;
@@ -252,30 +181,71 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
252 if (id_equal(packet + 1, ping->dht->self_public_key)) 181 if (id_equal(packet + 1, ping->dht->self_public_key))
253 return 1; 182 return 1;
254 183
255 int ping_index = is_pinging(ping, source, 0); 184 uint8_t shared_key[crypto_box_BEFORENMBYTES];
256 185
257 if (!ping_index) 186 // generate key to encrypt ping_id with recipient privkey
258 return 1; 187 DHT_get_shared_key_sent(ping->dht, shared_key, packet + 1);
259 188
260 --ping_index; 189 uint8_t ping_plain[PING_PLAIN_SIZE];
261 // Decrypt ping_id 190 // Decrypt ping_id
262 rc = decrypt_data_fast(ping->pings[ping_index].shared_key, 191 rc = decrypt_data_symmetric(shared_key,
263 packet + 1 + CLIENT_ID_SIZE, 192 packet + 1 + CLIENT_ID_SIZE,
264 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 193 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
265 sizeof(ping_id) + crypto_box_MACBYTES, 194 PING_PLAIN_SIZE + crypto_box_MACBYTES,
266 (uint8_t *) &ping_id); 195 ping_plain);
267 196
268 if (rc != sizeof(ping_id)) 197 if (rc != sizeof(ping_plain))
269 return 1; 198 return 1;
270 199
271 if (ping->pings[ping_index].id != ping_id) 200 if (ping_plain[0] != NET_PACKET_PING_RESPONSE)
272 return 1; 201 return 1;
273 202
274 addto_lists(dht, source, packet + 1); 203 uint64_t ping_id;
204 memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
205 uint8_t data[PING_DATA_SIZE];
275 206
207 if (ping_array_check(data, sizeof(data), &ping->ping_array, ping_id) != sizeof(data))
208 return 1;
209
210 if (!id_equal(packet + 1, data))
211 return 1;
212
213 IP_Port ipp;
214 memcpy(&ipp, data + CLIENT_ID_SIZE, sizeof(IP_Port));
215
216 if (!ipport_equal(&ipp, &source))
217 return 1;
218
219 addto_lists(dht, source, packet + 1);
276 return 0; 220 return 0;
277} 221}
278 222
223/* Check if client_id with ip_port is in the list.
224 *
225 * return 1 if it is.
226 * return 0 if it isn't.
227 */
228static int in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port)
229{
230 uint32_t i;
231
232 for (i = 0; i < length; ++i) {
233 if (id_equal(list[i].client_id, client_id)) {
234 IPPTsPng *ipptp;
235
236 if (ip_port.ip.family == AF_INET) {
237 ipptp = &list[i].assoc4;
238 } else {
239 ipptp = &list[i].assoc6;
240 }
241
242 if (!is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT) && ipport_equal(&ipptp->ip_port, &ip_port))
243 return 1;
244 }
245 }
246
247 return 0;
248}
279 249
280/* Add nodes to the to_ping list. 250/* Add nodes to the to_ping list.
281 * All nodes in this list are pinged every TIME_TO_PING seconds 251 * All nodes in this list are pinged every TIME_TO_PING seconds
@@ -292,6 +262,9 @@ int add_to_ping(PING *ping, uint8_t *client_id, IP_Port ip_port)
292 if (!ip_isset(&ip_port.ip)) 262 if (!ip_isset(&ip_port.ip))
293 return -1; 263 return -1;
294 264
265 if (in_list(ping->dht->close_clientlist, LCLIENT_LIST, client_id, ip_port))
266 return -1;
267
295 uint32_t i; 268 uint32_t i;
296 269
297 for (i = 0; i < MAX_TO_PING; ++i) { 270 for (i = 0; i < MAX_TO_PING; ++i) {
@@ -300,12 +273,18 @@ int add_to_ping(PING *ping, uint8_t *client_id, IP_Port ip_port)
300 ipport_copy(&ping->to_ping[i].ip_port, &ip_port); 273 ipport_copy(&ping->to_ping[i].ip_port, &ip_port);
301 return 0; 274 return 0;
302 } 275 }
276
277 if (memcmp(ping->to_ping[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
278 return -1;
279 }
303 } 280 }
304 281
282 uint32_t r = rand();
283
305 for (i = 0; i < MAX_TO_PING; ++i) { 284 for (i = 0; i < MAX_TO_PING; ++i) {
306 if (id_closest(ping->dht->self_public_key, ping->to_ping[i].client_id, client_id) == 2) { 285 if (id_closest(ping->dht->self_public_key, ping->to_ping[(i + r) % MAX_TO_PING].client_id, client_id) == 2) {
307 memcpy(ping->to_ping[i].client_id, client_id, CLIENT_ID_SIZE); 286 memcpy(ping->to_ping[(i + r) % MAX_TO_PING].client_id, client_id, CLIENT_ID_SIZE);
308 ipport_copy(&ping->to_ping[i].ip_port, &ip_port); 287 ipport_copy(&ping->to_ping[(i + r) % MAX_TO_PING].ip_port, &ip_port);
309 return 0; 288 return 0;
310 } 289 }
311 } 290 }
@@ -342,6 +321,11 @@ PING *new_ping(DHT *dht)
342 if (ping == NULL) 321 if (ping == NULL)
343 return NULL; 322 return NULL;
344 323
324 if (ping_array_init(&ping->ping_array, PING_NUM_MAX, PING_TIMEOUT) != 0) {
325 free(ping);
326 return NULL;
327 }
328
345 ping->dht = dht; 329 ping->dht = dht;
346 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht); 330 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
347 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht); 331 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
@@ -353,6 +337,7 @@ void kill_ping(PING *ping)
353{ 337{
354 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL); 338 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL);
355 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL); 339 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
340 ping_array_free_all(&ping->ping_array);
356 341
357 free(ping); 342 free(ping);
358} 343}
diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c
new file mode 100644
index 00000000..e6f684ef
--- /dev/null
+++ b/toxcore/ping_array.c
@@ -0,0 +1,162 @@
1/* ping_array.c
2 *
3 * Implementation of an efficient array to store that we pinged something.
4 *
5 *
6 * Copyright (C) 2014 Tox project All Rights Reserved.
7 *
8 * This file is part of Tox.
9 *
10 * Tox is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * Tox is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include "ping_array.h"
30#include "crypto_core.h"
31#include "util.h"
32
33static void clear_entry(Ping_Array *array, uint32_t index)
34{
35 free(array->entries[index].data);
36 array->entries[index].data = NULL;
37 array->entries[index].length =
38 array->entries[index].time =
39 array->entries[index].ping_id = 0;
40}
41
42/* Clear timed out entries.
43 */
44static void ping_array_clear_timedout(Ping_Array *array)
45{
46 while (array->last_deleted != array->last_added) {
47 uint32_t index = array->last_deleted % array->total_size;
48
49 if (!is_timeout(array->entries[index].time, array->timeout))
50 break;
51
52 clear_entry(array, index);
53 ++array->last_deleted;
54 }
55}
56
57/* Add a data with length to the Ping_Array list and return a ping_id.
58 *
59 * return ping_id on success.
60 * return 0 on failure.
61 */
62uint64_t ping_array_add(Ping_Array *array, uint8_t *data, uint32_t length)
63{
64 ping_array_clear_timedout(array);
65 uint32_t index = array->last_added % array->total_size;
66
67 if (array->entries[index].data != NULL) {
68 array->last_deleted = array->last_added - array->total_size;
69 clear_entry(array, index);
70 }
71
72 array->entries[index].data = malloc(length);
73
74 if (array->entries[index].data == NULL)
75 return 0;
76
77 memcpy(array->entries[index].data, data, length);
78 array->entries[index].length = length;
79 array->entries[index].time = unix_time();
80 ++array->last_added;
81 uint64_t ping_id = random_64b();
82 ping_id /= array->total_size;
83 ping_id *= array->total_size;
84 ping_id += index;
85
86 if (ping_id == 0)
87 ping_id += array->total_size;
88
89 array->entries[index].ping_id = ping_id;
90 return ping_id;
91}
92
93
94/* Check if ping_id is valid and not timed out.
95 *
96 * On success, copies the data into data of length,
97 *
98 * return length of data copied on success.
99 * return -1 on failure.
100 */
101int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t ping_id)
102{
103 if (ping_id == 0)
104 return -1;
105
106 uint32_t index = ping_id % array->total_size;
107
108 if (array->entries[index].ping_id != ping_id)
109 return -1;
110
111 if (is_timeout(array->entries[index].time, array->timeout))
112 return -1;
113
114 if (array->entries[index].length > length)
115 return -1;
116
117 if (array->entries[index].data == NULL)
118 return -1;
119
120 memcpy(data, array->entries[index].data, array->entries[index].length);
121 uint32_t len = array->entries[index].length;
122 clear_entry(array, index);
123 return len;
124}
125
126/* Initialize a Ping_Array.
127 * size represents the total size of the array and should be a power of 2.
128 * timeout represents the maximum timeout in seconds for the entry.
129 *
130 * return 0 on success.
131 * return -1 on failure.
132 */
133int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout)
134{
135 if (size == 0 || timeout == 0 || empty_array == NULL)
136 return -1;
137
138 empty_array->entries = calloc(size * sizeof(Ping_Array_Entry), 1);
139
140 if (empty_array->entries == NULL)
141 return -1;
142
143 empty_array->last_deleted = empty_array->last_added = 0;
144 empty_array->total_size = size;
145 empty_array->timeout = timeout;
146 return 0;
147}
148
149/* Free all the allocated memory in a Ping_Array.
150 */
151void ping_array_free_all(Ping_Array *array)
152{
153 while (array->last_deleted != array->last_added) {
154 uint32_t index = array->last_deleted % array->total_size;
155 clear_entry(array, index);
156 ++array->last_deleted;
157 }
158
159 free(array->entries);
160 array->entries = NULL;
161}
162
diff --git a/toxcore/ping_array.h b/toxcore/ping_array.h
new file mode 100644
index 00000000..c5811b16
--- /dev/null
+++ b/toxcore/ping_array.h
@@ -0,0 +1,75 @@
1/* ping_array.h
2 *
3 * Implementation of an efficient array to store that we pinged something.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23#ifndef PING_ARRAY_H
24#define PING_ARRAY_H
25
26#include "network.h"
27
28typedef struct {
29 void *data;
30 uint32_t length;
31 uint64_t time;
32 uint64_t ping_id;
33} Ping_Array_Entry;
34
35
36typedef struct {
37 Ping_Array_Entry *entries;
38
39 uint32_t last_deleted; /* number representing the next entry to be deleted. */
40 uint32_t last_added; /* number representing the last entry to be added. */
41 uint32_t total_size; /* The length of entries */
42 uint32_t timeout; /* The timeout after which entries are cleared. */
43} Ping_Array;
44
45
46/* Add a data with length to the Ping_Array list and return a ping_id.
47 *
48 * return ping_id on success.
49 * return 0 on failure.
50 */
51uint64_t ping_array_add(Ping_Array *array, uint8_t *data, uint32_t length);
52
53/* Check if ping_id is valid and not timed out.
54 *
55 * On success, copies the data into data of length,
56 *
57 * return length of data copied on success.
58 * return -1 on failure.
59 */
60int ping_array_check(uint8_t *data, uint32_t length, Ping_Array *array, uint64_t ping_id);
61
62/* Initialize a Ping_Array.
63 * size represents the total size of the array and should be a power of 2.
64 * timeout represents the maximum timeout in seconds for the entry.
65 *
66 * return 0 on success.
67 * return -1 on failure.
68 */
69int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout);
70
71/* Free all the allocated memory in a Ping_Array.
72 */
73void ping_array_free_all(Ping_Array *array);
74
75#endif
diff --git a/toxcore/tox.c b/toxcore/tox.c
index 9b99174c..884223ff 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -187,7 +187,7 @@ int tox_set_name(Tox *tox, uint8_t *name, uint16_t length)
187} 187}
188 188
189/* Get your nickname. 189/* Get your nickname.
190 * m - The messanger context to use. 190 * m - The messenger context to use.
191 * name - Pointer to a string for the name. (must be at least MAX_NAME_LENGTH) 191 * name - Pointer to a string for the name. (must be at least MAX_NAME_LENGTH)
192 * 192 *
193 * return length of the name. 193 * return length of the name.
@@ -722,7 +722,7 @@ int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8
722 */ 722 */
723int tox_file_data_size(Tox *tox, int32_t friendnumber) 723int tox_file_data_size(Tox *tox, int32_t friendnumber)
724{ 724{
725 return MAX_DATA_SIZE - crypto_box_MACBYTES - 3; 725 return MAX_CRYPTO_DATA_SIZE - 2;
726} 726}
727 727
728/* Give the number of bytes left to be sent/received. 728/* Give the number of bytes left to be sent/received.
@@ -740,23 +740,38 @@ uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenum
740 740
741/***************END OF FILE SENDING FUNCTIONS******************/ 741/***************END OF FILE SENDING FUNCTIONS******************/
742 742
743/* Use these functions to bootstrap the client. 743/* TODO: expose this properly. */
744 * Sends a get nodes request to the given node with ip port and public_key. 744static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
745 */
746void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port _ip_port, uint8_t *public_key)
747{ 745{
748 Messenger *m = tox; 746 Messenger *m = tox;
749 IP_Port ip_port; 747 IP_Port ip_port_v64;
750 memcpy(&ip_port, &_ip_port, sizeof(IP_Port)); 748 IP *ip_extra = NULL;
751 DHT_bootstrap(m->dht, ip_port, public_key); 749 IP_Port ip_port_v4;
750 ip_init(&ip_port_v64.ip, ipv6enabled);
751
752 if (ipv6enabled) {
753 /* setup for getting BOTH: an IPv6 AND an IPv4 address */
754 ip_port_v64.ip.family = AF_UNSPEC;
755 ip_reset(&ip_port_v4.ip);
756 ip_extra = &ip_port_v4.ip;
757 }
758
759 if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) {
760 ip_port_v64.port = port;
761 add_tcp_relay(m->net_crypto, ip_port_v64, public_key);
762 return 1;
763 } else {
764 return 0;
765 }
752} 766}
753 767
754int tox_bootstrap_from_address(Tox *tox, const char *address, 768int tox_bootstrap_from_address(Tox *tox, const char *address,
755 uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) 769 uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
756{ 770{
757 Messenger *m = tox; 771 Messenger *m = tox;
772 tox_add_tcp_relay(tox, address, ipv6enabled, port, public_key);
758 return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key); 773 return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key);
759}; 774}
760 775
761/* return 0 if we are not connected to the DHT. 776/* return 0 if we are not connected to the DHT.
762 * return 1 if we are. 777 * return 1 if we are.
@@ -842,33 +857,3 @@ int tox_load(Tox *tox, uint8_t *data, uint32_t length)
842 Messenger *m = tox; 857 Messenger *m = tox;
843 return messenger_load(m, data, length); 858 return messenger_load(m, data, length);
844} 859}
845
846/* return the size of data to pass to messenger_save_encrypted(...)
847 */
848uint32_t tox_size_encrypted(Tox *tox)
849{
850 Messenger *m = tox;
851 return messenger_size_encrypted(m);
852}
853
854/* Save the messenger, encrypting the data with key of length key_length
855 *
856 * return 0 on success.
857 * return -1 on failure.
858 */
859int tox_save_encrypted(Tox *tox, uint8_t *data, uint8_t *key, uint16_t key_length)
860{
861 Messenger *m = tox;
862 return messenger_save_encrypted(m, data, key, key_length);
863}
864
865/* Load the messenger from data of size length encrypted with key of key_length.
866 *
867 * return 0 on success.
868 * return -1 on failure.
869 */
870int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length)
871{
872 Messenger *m = tox;
873 return messenger_load_encrypted(m, data, length, key, key_length);
874}
diff --git a/toxcore/tox.h b/toxcore/tox.h
index d94c0e13..111b2634 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -210,7 +210,7 @@ int tox_set_name(Tox *tox, uint8_t *name, uint16_t length);
210 210
211/* 211/*
212 * Get your nickname. 212 * Get your nickname.
213 * m - The messanger context to use. 213 * m - The messenger context to use.
214 * name - needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 214 * name - needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
215 * 215 *
216 * return length of name. 216 * return length of name.
@@ -515,11 +515,11 @@ uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size);
515 * tox_file_data_remaining(...) can be used to know how many bytes are left to send/receive. 515 * tox_file_data_remaining(...) can be used to know how many bytes are left to send/receive.
516 * 516 *
517 * If the connection breaks during file sending (The other person goes offline without pausing the sending and then comes back) 517 * If the connection breaks during file sending (The other person goes offline without pausing the sending and then comes back)
518 * the reciever must send a control packet with receive_send == 0 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being 518 * the receiver must send a control packet with receive_send == 0 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being
519 * a uint64_t (in host byte order) containing the number of bytes recieved. 519 * a uint64_t (in host byte order) containing the number of bytes received.
520 * 520 *
521 * If the sender recieves this packet, he must send a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT 521 * If the sender receives this packet, he must send a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT
522 * then he must start sending file data from the position (data , uint64_t in host byte order) recieved in the TOX_FILECONTROL_RESUME_BROKEN packet. 522 * then he must start sending file data from the position (data , uint64_t in host byte order) received in the TOX_FILECONTROL_RESUME_BROKEN packet.
523 * 523 *
524 * More to come... 524 * More to come...
525 */ 525 */
@@ -601,43 +601,6 @@ uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenum
601 601
602/***************END OF FILE SENDING FUNCTIONS******************/ 602/***************END OF FILE SENDING FUNCTIONS******************/
603 603
604/* WARNING: DEPRECATED, DO NOT USE. */
605typedef union {
606 uint8_t c[4];
607 uint16_t s[2];
608 uint32_t i;
609} tox_IP4;
610
611typedef union {
612 uint8_t uint8[16];
613 uint16_t uint16[8];
614 uint32_t uint32[4];
615 struct in6_addr in6_addr;
616} tox_IP6;
617
618typedef struct {
619 uint8_t family;
620 /* Not used for anything right now. */
621 uint8_t padding[3];
622 union {
623 tox_IP4 ip4;
624 tox_IP6 ip6;
625 };
626} tox_IP;
627
628/* will replace IP_Port as soon as the complete infrastructure is in place
629 * removed the unused union and padding also */
630typedef struct {
631 tox_IP ip;
632 uint16_t port;
633} tox_IP_Port;
634/* WARNING: DEPRECATED, DO NOT USE. */
635/* Sends a "get nodes" request to the given node with ip, port and public_key
636 * to setup connections
637 */
638void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key);
639
640
641/* 604/*
642 * Use this function to bootstrap the client. 605 * Use this function to bootstrap the client.
643 */ 606 */
@@ -739,32 +702,6 @@ void tox_save(Tox *tox, uint8_t *data);
739 */ 702 */
740int tox_load(Tox *tox, uint8_t *data, uint32_t length); 703int tox_load(Tox *tox, uint8_t *data, uint32_t length);
741 704
742/**/
743
744/* return the size of data to pass to messenger_save_encrypted(...)
745 */
746uint32_t tox_size_encrypted(Tox *tox);
747
748/* Save the messenger, encrypting the data with key of length key_length
749 *
750 * This functions simply calls and then encrypt the output of tox_save(..)
751 * with crypto_secretbox(...) from NaCl/libsodium with the key
752 * given to crypto_secretbox(...) being the SHA256 sum of the key
753 * passed to this function.
754 *
755 * return 0 on success.
756 * return -1 on failure.
757 */
758int tox_save_encrypted(Tox *tox, uint8_t *data, uint8_t *key, uint16_t key_length);
759
760/* Load the messenger from data of size length encrypted with key of key_length.
761 *
762 * return 0 on success.
763 * return -1 on failure.
764 */
765int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length);
766
767
768#ifdef __cplusplus 705#ifdef __cplusplus
769} 706}
770#endif 707#endif
diff --git a/toxcore/util.c b/toxcore/util.c
index edc611ec..7a2db450 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -36,10 +36,14 @@
36 36
37/* don't call into system billions of times for no reason */ 37/* don't call into system billions of times for no reason */
38static uint64_t unix_time_value; 38static uint64_t unix_time_value;
39static uint64_t unix_base_time_value;
39 40
40void unix_time_update() 41void unix_time_update()
41{ 42{
42 unix_time_value = (uint64_t)time(NULL); 43 if (unix_base_time_value == 0)
44 unix_base_time_value = ((uint64_t)time(NULL) - (current_time_monotonic() / 1000ULL));
45
46 unix_time_value = (current_time_monotonic() / 1000ULL) + unix_base_time_value;
43} 47}
44 48
45uint64_t unix_time() 49uint64_t unix_time()
@@ -49,7 +53,7 @@ uint64_t unix_time()
49 53
50int is_timeout(uint64_t timestamp, uint64_t timeout) 54int is_timeout(uint64_t timestamp, uint64_t timeout)
51{ 55{
52 return timestamp + timeout <= unix_time_value; 56 return timestamp + timeout <= unix_time();
53} 57}
54 58
55 59
@@ -67,22 +71,17 @@ uint32_t id_copy(uint8_t *dest, uint8_t *src)
67 71
68void host_to_net(uint8_t *num, uint16_t numbytes) 72void host_to_net(uint8_t *num, uint16_t numbytes)
69{ 73{
70 union { 74#ifndef WORDS_BIGENDIAN
71 uint32_t i; 75 uint32_t i;
72 uint8_t c[4]; 76 uint8_t buff[numbytes];
73 } a;
74 a.i = 1;
75
76 if (a.c[0] == 1) {
77 uint32_t i;
78 uint8_t buff[numbytes];
79
80 for (i = 0; i < numbytes; ++i) {
81 buff[i] = num[numbytes - i - 1];
82 }
83 77
84 memcpy(num, buff, numbytes); 78 for (i = 0; i < numbytes; ++i) {
79 buff[i] = num[numbytes - i - 1];
85 } 80 }
81
82 memcpy(num, buff, numbytes);
83#endif
84 return;
86} 85}
87 86
88/* state load/save */ 87/* state load/save */
@@ -99,11 +98,11 @@ int load_state(load_state_callback_func load_state_callback, void *outer,
99 98
100 uint16_t type; 99 uint16_t type;
101 uint32_t length_sub, cookie_type; 100 uint32_t length_sub, cookie_type;
102 uint32_t size32 = sizeof(uint32_t), size_head = size32 * 2; 101 uint32_t size_head = sizeof(uint32_t) * 2;
103 102
104 while (length >= size_head) { 103 while (length >= size_head) {
105 length_sub = *(uint32_t *)data; 104 memcpy(&length_sub, data, sizeof(length_sub));
106 cookie_type = *(uint32_t *)(data + size32); 105 memcpy(&cookie_type, data + sizeof(length_sub), sizeof(cookie_type));
107 data += size_head; 106 data += size_head;
108 length -= size_head; 107 length -= size_head;
109 108