summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/DHT.c331
-rw-r--r--core/DHT.h148
-rw-r--r--core/LAN_discovery.c6
-rw-r--r--core/LAN_discovery.h22
-rw-r--r--core/Lossless_UDP.c78
-rw-r--r--core/Lossless_UDP.h112
-rw-r--r--core/Messenger.c124
-rw-r--r--core/Messenger.h216
-rw-r--r--core/friend_requests.c33
-rw-r--r--core/friend_requests.h30
-rw-r--r--core/net_crypto.c138
-rw-r--r--core/net_crypto.h194
-rw-r--r--core/network.c64
-rw-r--r--core/network.h124
14 files changed, 804 insertions, 816 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 71abea2a..014ec588 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -1,5 +1,5 @@
1/* DHT.c 1/* DHT.c
2 * 2 *
3 * An implementation of the DHT as seen in docs/DHT.txt 3 * An implementation of the DHT as seen in docs/DHT.txt
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -18,52 +18,48 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#include "DHT.h" 24#include "DHT.h"
25 25
26typedef struct 26typedef struct {
27{
28 uint8_t client_id[CLIENT_ID_SIZE]; 27 uint8_t client_id[CLIENT_ID_SIZE];
29 IP_Port ip_port; 28 IP_Port ip_port;
30 uint32_t timestamp; 29 uint32_t timestamp;
31 uint32_t last_pinged; 30 uint32_t last_pinged;
32 IP_Port ret_ip_port;/* The ip_port returned by this node for the friend 31 IP_Port ret_ip_port;/* The ip_port returned by this node for the friend
33 (for nodes in friends_list) or us (for nodes in close_clientlist) */ 32 (for nodes in friends_list) or us (for nodes in close_clientlist) */
34 uint32_t ret_timestamp; 33 uint32_t ret_timestamp;
35}Client_data; 34} Client_data;
36 35
37/* maximum number of clients stored per friend. */ 36/* maximum number of clients stored per friend. */
38#define MAX_FRIEND_CLIENTS 8 37#define MAX_FRIEND_CLIENTS 8
39 38
40typedef struct 39typedef struct {
41{
42 uint8_t client_id[CLIENT_ID_SIZE]; 40 uint8_t client_id[CLIENT_ID_SIZE];
43 Client_data client_list[MAX_FRIEND_CLIENTS]; 41 Client_data client_list[MAX_FRIEND_CLIENTS];
44 uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ 42 uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */
45 43
46 /*Symetric NAT hole punching stuff*/ 44 /*Symetric NAT hole punching stuff*/
47 uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */ 45 uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */
48 uint32_t punching_index; 46 uint32_t punching_index;
49 uint32_t punching_timestamp; 47 uint32_t punching_timestamp;
50 uint64_t NATping_id; 48 uint64_t NATping_id;
51 uint32_t NATping_timestamp; 49 uint32_t NATping_timestamp;
52}Friend; 50} Friend;
53 51
54typedef struct 52typedef struct {
55{
56 uint8_t client_id[CLIENT_ID_SIZE]; 53 uint8_t client_id[CLIENT_ID_SIZE];
57 IP_Port ip_port; 54 IP_Port ip_port;
58}Node_format; 55} Node_format;
59 56
60typedef struct 57typedef struct {
61{
62 IP_Port ip_port; 58 IP_Port ip_port;
63 uint64_t ping_id; 59 uint64_t ping_id;
64 uint32_t timestamp; 60 uint32_t timestamp;
65 61
66}Pinged; 62} Pinged;
67 63
68/* Our client id/public key */ 64/* Our client id/public key */
69uint8_t self_public_key[CLIENT_ID_SIZE]; 65uint8_t self_public_key[CLIENT_ID_SIZE];
@@ -115,7 +111,7 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
115 for(i = 0; i < length; ++i) { 111 for(i = 0; i < length; ++i) {
116 /*If ip_port is assigned to a different client_id replace it*/ 112 /*If ip_port is assigned to a different client_id replace it*/
117 if(list[i].ip_port.ip.i == ip_port.ip.i && 113 if(list[i].ip_port.ip.i == ip_port.ip.i &&
118 list[i].ip_port.port == ip_port.port) { 114 list[i].ip_port.port == ip_port.port) {
119 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 115 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
120 } 116 }
121 117
@@ -167,39 +163,38 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
167 int num_nodes=0; 163 int num_nodes=0;
168 uint32_t temp_time = unix_time(); 164 uint32_t temp_time = unix_time();
169 for(i = 0; i < LCLIENT_LIST; ++i) 165 for(i = 0; i < LCLIENT_LIST; ++i)
170 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 166 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
171 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { 167 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
172 /* if node is good and not already in list. */ 168 /* if node is good and not already in list. */
173 if(num_nodes < MAX_SENT_NODES) { 169 if(num_nodes < MAX_SENT_NODES) {
174 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 170 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
175 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 171 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
176 num_nodes++; 172 num_nodes++;
177 } 173 } else for(j = 0; j < MAX_SENT_NODES; ++j)
178 else for(j = 0; j < MAX_SENT_NODES; ++j) 174 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
179 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { 175 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
180 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 176 nodes_list[j].ip_port = close_clientlist[i].ip_port;
181 nodes_list[j].ip_port = close_clientlist[i].ip_port; 177 break;
182 break; 178 }
183 }
184 } 179 }
185 180
186 for(i = 0; i < num_friends; ++i) 181 for(i = 0; i < num_friends; ++i)
187 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 182 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
188 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && 183 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
189 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) { 184 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
190 /* if node is good and not already in list. */ 185 /* if node is good and not already in list. */
191 if(num_nodes < MAX_SENT_NODES) { 186 if(num_nodes < MAX_SENT_NODES) {
192 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 187 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
193 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 188 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
194 num_nodes++; 189 num_nodes++;
195 } else for(k = 0; k < MAX_SENT_NODES; ++k) 190 } else for(k = 0; k < MAX_SENT_NODES; ++k)
196 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) { 191 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
197 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 192 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
198 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 193 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
199 break; 194 break;
200 } 195 }
201 } 196 }
202 return num_nodes; 197 return num_nodes;
203} 198}
204 199
205/* replace first bad (or empty) node with this one 200/* replace first bad (or empty) node with this one
@@ -210,7 +205,7 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
210 uint32_t i; 205 uint32_t i;
211 uint32_t temp_time = unix_time(); 206 uint32_t temp_time = unix_time();
212 for(i = 0; i < length; ++i) 207 for(i = 0; i < length; ++i)
213 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ { 208 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */
214 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 209 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
215 list[i].ip_port = ip_port; 210 list[i].ip_port = ip_port;
216 list[i].timestamp = temp_time; 211 list[i].timestamp = temp_time;
@@ -228,7 +223,7 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
228{ 223{
229 uint32_t i; 224 uint32_t i;
230 uint32_t temp_time = unix_time(); 225 uint32_t temp_time = unix_time();
231 226
232 for(i = 0; i < length; ++i) 227 for(i = 0; i < length; ++i)
233 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { 228 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
234 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 229 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
@@ -247,7 +242,7 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
247void addto_lists(IP_Port ip_port, uint8_t * client_id) 242void addto_lists(IP_Port ip_port, uint8_t * client_id)
248{ 243{
249 uint32_t i; 244 uint32_t i;
250 245
251 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ 246 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */
252 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 247 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port))
253 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 248 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port))
@@ -261,7 +256,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
261 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); 256 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id);
262} 257}
263 258
264/* If client_id is a friend or us, update ret_ip_port 259/* If client_id is a friend or us, update ret_ip_port
265 nodeclient_id is the id of the node that sent us this info */ 260 nodeclient_id is the id of the node that sent us this info */
266void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) 261void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
267{ 262{
@@ -275,14 +270,14 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
275 return; 270 return;
276 } 271 }
277 } else 272 } else
278 for(i = 0; i < num_friends; ++i) 273 for(i = 0; i < num_friends; ++i)
279 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) 274 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0)
280 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 275 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
281 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { 276 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
282 friends_list[i].client_list[j].ret_ip_port = ip_port; 277 friends_list[i].client_list[j].ret_ip_port = ip_port;
283 friends_list[i].client_list[j].ret_timestamp = temp_time; 278 friends_list[i].client_list[j].ret_timestamp = temp_time;
284 return; 279 return;
285 } 280 }
286} 281}
287 282
288/* ping timeout in seconds */ 283/* ping timeout in seconds */
@@ -304,13 +299,13 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
304 pinging = 0; 299 pinging = 0;
305 if(ip_port.ip.i != 0) 300 if(ip_port.ip.i != 0)
306 if(pings[i].ip_port.ip.i == ip_port.ip.i && 301 if(pings[i].ip_port.ip.i == ip_port.ip.i &&
307 pings[i].ip_port.port == ip_port.port) 302 pings[i].ip_port.port == ip_port.port)
308 ++pinging; 303 ++pinging;
309 if(ping_id != 0) 304 if(ping_id != 0)
310 if(pings[i].ping_id == ping_id) 305 if(pings[i].ping_id == ping_id)
311 ++pinging; 306 ++pinging;
312 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 307 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
313 return 1; 308 return 1;
314 } 309 }
315 310
316 return 0; 311 return 0;
@@ -328,14 +323,14 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
328 pinging = 0; 323 pinging = 0;
329 if(ip_port.ip.i != 0) 324 if(ip_port.ip.i != 0)
330 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && 325 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
331 send_nodes[i].ip_port.port == ip_port.port) 326 send_nodes[i].ip_port.port == ip_port.port)
332 ++pinging; 327 ++pinging;
333 if(ping_id != 0) 328 if(ping_id != 0)
334 if(send_nodes[i].ping_id == ping_id) 329 if(send_nodes[i].ping_id == ping_id)
335 ++pinging; 330 ++pinging;
336 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 331 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
337 return 1; 332 return 1;
338 333
339 } 334 }
340 335
341 return 0; 336 return 0;
@@ -354,10 +349,10 @@ uint64_t add_pinging(IP_Port ip_port)
354 for(i = 0; i < PING_TIMEOUT; ++i ) 349 for(i = 0; i < PING_TIMEOUT; ++i )
355 for(j = 0; j < LPING_ARRAY; ++j ) 350 for(j = 0; j < LPING_ARRAY; ++j )
356 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { 351 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
357 pings[j].timestamp = temp_time; 352 pings[j].timestamp = temp_time;
358 pings[j].ip_port = ip_port; 353 pings[j].ip_port = ip_port;
359 pings[j].ping_id = ping_id; 354 pings[j].ping_id = ping_id;
360 return ping_id; 355 return ping_id;
361 } 356 }
362 357
363 return 0; 358 return 0;
@@ -373,10 +368,10 @@ uint64_t add_gettingnodes(IP_Port ip_port)
373 for(i = 0; i < PING_TIMEOUT; ++i ) 368 for(i = 0; i < PING_TIMEOUT; ++i )
374 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) 369 for(j = 0; j < LSEND_NODES_ARRAY; ++j )
375 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { 370 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
376 send_nodes[j].timestamp = temp_time; 371 send_nodes[j].timestamp = temp_time;
377 send_nodes[j].ip_port = ip_port; 372 send_nodes[j].ip_port = ip_port;
378 send_nodes[j].ping_id = ping_id; 373 send_nodes[j].ping_id = ping_id;
379 return ping_id; 374 return ping_id;
380 } 375 }
381 376
382 return 0; 377 return 0;
@@ -415,7 +410,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
415/* send a ping response */ 410/* send a ping response */
416static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) 411static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
417{ 412{
418 /* check if packet is gonna be sent to ourself */ 413 /* check if packet is gonna be sent to ourself */
419 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) 414 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
420 return 1; 415 return 1;
421 416
@@ -431,7 +426,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
431 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 426 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
432 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 427 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
433 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 428 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
434 429
435 return sendpacket(ip_port, data, sizeof(data)); 430 return sendpacket(ip_port, data, sizeof(data));
436} 431}
437 432
@@ -441,26 +436,26 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
441 /* check if packet is gonna be sent to ourself */ 436 /* check if packet is gonna be sent to ourself */
442 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) 437 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
443 return 1; 438 return 1;
444 439
445 if(is_gettingnodes(ip_port, 0)) 440 if(is_gettingnodes(ip_port, 0))
446 return 1; 441 return 1;
447 442
448 uint64_t ping_id = add_gettingnodes(ip_port); 443 uint64_t ping_id = add_gettingnodes(ip_port);
449 444
450 if(ping_id == 0) 445 if(ping_id == 0)
451 return 1; 446 return 1;
452 447
453 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 448 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
454 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 449 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
455 uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 450 uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
456 uint8_t nonce[crypto_box_NONCEBYTES]; 451 uint8_t nonce[crypto_box_NONCEBYTES];
457 random_nonce(nonce); 452 random_nonce(nonce);
458 453
459 memcpy(plain, &ping_id, sizeof(ping_id)); 454 memcpy(plain, &ping_id, sizeof(ping_id));
460 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 455 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
461 456
462 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); 457 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
463 458
464 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 459 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
465 return -1; 460 return -1;
466 data[0] = 2; 461 data[0] = 2;
@@ -476,8 +471,8 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
476 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 471 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */
477 return 1; 472 return 1;
478 473
479 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 474 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
480 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; 475 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
481 476
482 Node_format nodes_list[MAX_SENT_NODES]; 477 Node_format nodes_list[MAX_SENT_NODES];
483 int num_nodes = get_close_nodes(client_id, nodes_list); 478 int num_nodes = get_close_nodes(client_id, nodes_list);
@@ -489,16 +484,16 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
489 uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; 484 uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
490 uint8_t nonce[crypto_box_NONCEBYTES]; 485 uint8_t nonce[crypto_box_NONCEBYTES];
491 random_nonce(nonce); 486 random_nonce(nonce);
492 487
493 memcpy(plain, &ping_id, sizeof(ping_id)); 488 memcpy(plain, &ping_id, sizeof(ping_id));
494 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 489 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
495 490
496 int len = encrypt_data(public_key, self_secret_key, nonce, plain, 491 int len = encrypt_data(public_key, self_secret_key, nonce, plain,
497 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); 492 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
498 493
499 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 494 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
500 return -1; 495 return -1;
501 496
502 data[0] = 3; 497 data[0] = 3;
503 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 498 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
504 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 499 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
@@ -515,13 +510,13 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
515 uint64_t ping_id; 510 uint64_t ping_id;
516 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 511 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
517 return 1; 512 return 1;
518 /* check if packet is from ourself. */ 513 /* check if packet is from ourself. */
519 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 514 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
520 return 1; 515 return 1;
521 516
522 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 517 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
523 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 518 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
524 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 519 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
525 if(len != sizeof(ping_id)) 520 if(len != sizeof(ping_id))
526 return 1; 521 return 1;
527 522
@@ -540,18 +535,18 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
540 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 535 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */
541 return 1; 536 return 1;
542 537
543 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 538 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
544 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 539 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
545 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 540 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
546 if(len != sizeof(ping_id)) 541 if(len != sizeof(ping_id))
547 return 1; 542 return 1;
548 543
549 if(is_pinging(source, ping_id)) { 544 if(is_pinging(source, ping_id)) {
550 addto_lists(source, packet + 1); 545 addto_lists(source, packet + 1);
551 return 0; 546 return 0;
552 } 547 }
553 return 1; 548 return 1;
554 549
555} 550}
556 551
557int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 552int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
@@ -559,15 +554,15 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
559 uint64_t ping_id; 554 uint64_t ping_id;
560 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 555 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
561 return 1; 556 return 1;
562 /* check if packet is from ourself. */ 557 /* check if packet is from ourself. */
563 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 558 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
564 return 1; 559 return 1;
565 560
566 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 561 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
567 562
568 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 563 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
569 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 564 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
570 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); 565 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
571 566
572 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) 567 if(len != sizeof(ping_id) + CLIENT_ID_SIZE)
573 return 1; 568 return 1;
@@ -578,7 +573,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
578 pingreq(source, packet + 1); /* TODO: make this smarter? */ 573 pingreq(source, packet + 1); /* TODO: make this smarter? */
579 574
580 return 0; 575 return 0;
581 576
582} 577}
583 578
584int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) 579int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
@@ -586,21 +581,21 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
586 uint64_t ping_id; 581 uint64_t ping_id;
587 /* TODO: make this more readable */ 582 /* TODO: make this more readable */
588 if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 583 if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
589 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || 584 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) ||
590 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 585 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
591 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || 586 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
592 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 587 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
593 + sizeof(Node_format) + ENCRYPTION_PADDING) { 588 + sizeof(Node_format) + ENCRYPTION_PADDING) {
594 return 1; 589 return 1;
595 } 590 }
596 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 591 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
597 + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); 592 + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
598 593
599 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 594 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
600 595
601 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 596 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
602 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 597 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
603 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); 598 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
604 599
605 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 600 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
606 return 1; 601 return 1;
@@ -648,7 +643,7 @@ int DHT_delfriend(uint8_t * client_id)
648 uint32_t i; 643 uint32_t i;
649 Friend * temp; 644 Friend * temp;
650 for(i = 0; i < num_friends; ++i) 645 for(i = 0; i < num_friends; ++i)
651 /* Equal */ 646 /* Equal */
652 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 647 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
653 --num_friends; 648 --num_friends;
654 if(num_friends != i) 649 if(num_friends != i)
@@ -669,18 +664,18 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
669 IP_Port empty = {{{0}}, 0}; 664 IP_Port empty = {{{0}}, 0};
670 uint32_t temp_time = unix_time(); 665 uint32_t temp_time = unix_time();
671 for(i = 0; i < num_friends; ++i) 666 for(i = 0; i < num_friends; ++i)
672 /* Equal */ 667 /* Equal */
673 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 668 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
674 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 669 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
675 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && 670 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
676 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) 671 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
677 return friends_list[i].client_list[j].ip_port; 672 return friends_list[i].client_list[j].ip_port;
678 673
679 return empty; 674 return empty;
680 } 675 }
681 empty.ip.i = 1; 676 empty.ip.i = 1;
682 return empty; 677 return empty;
683 678
684} 679}
685 680
686/* The timeout after which a node is discarded completely. */ 681/* The timeout after which a node is discarded completely. */
@@ -700,24 +695,24 @@ void doDHTFriends()
700 uint32_t temp_time = unix_time(); 695 uint32_t temp_time = unix_time();
701 uint32_t rand_node; 696 uint32_t rand_node;
702 uint32_t index[MAX_FRIEND_CLIENTS]; 697 uint32_t index[MAX_FRIEND_CLIENTS];
703 698
704 for(i = 0; i < num_friends; ++i) { 699 for(i = 0; i < num_friends; ++i) {
705 uint32_t num_nodes = 0; 700 uint32_t num_nodes = 0;
706 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 701 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
707 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ { 702 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { /* if node is not dead. */
708 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 703 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
709 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); 704 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
710 friends_list[i].client_list[j].last_pinged = temp_time; 705 friends_list[i].client_list[j].last_pinged = temp_time;
711 } 706 }
712 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ { 707 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { /* if node is good. */
713 index[num_nodes] = j; 708 index[num_nodes] = j;
714 ++num_nodes; 709 ++num_nodes;
715 } 710 }
716 } 711 }
717 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 712 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
718 rand_node = rand() % num_nodes; 713 rand_node = rand() % num_nodes;
719 getnodes(friends_list[i].client_list[index[rand_node]].ip_port, 714 getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
720 friends_list[i].client_list[index[rand_node]].client_id, 715 friends_list[i].client_list[index[rand_node]].client_id,
721 friends_list[i].client_id); 716 friends_list[i].client_id);
722 friends_list[i].lastgetnode = temp_time; 717 friends_list[i].lastgetnode = temp_time;
723 } 718 }
@@ -735,25 +730,25 @@ void doClose() /* tested */
735 uint32_t num_nodes = 0; 730 uint32_t num_nodes = 0;
736 uint32_t rand_node; 731 uint32_t rand_node;
737 uint32_t index[LCLIENT_LIST]; 732 uint32_t index[LCLIENT_LIST];
738 733
739 for(i = 0; i < LCLIENT_LIST; ++i) 734 for(i = 0; i < LCLIENT_LIST; ++i)
740 /* if node is not dead. */ 735 /* if node is not dead. */
741 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { 736 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
742 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 737 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
743 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); 738 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
744 close_clientlist[i].last_pinged = temp_time; 739 close_clientlist[i].last_pinged = temp_time;
745 } 740 }
746 /* if node is good. */ 741 /* if node is good. */
747 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { 742 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
748 index[num_nodes] = i; 743 index[num_nodes] = i;
749 ++num_nodes; 744 ++num_nodes;
750 } 745 }
751 } 746 }
752 747
753 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 748 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
754 rand_node = rand() % num_nodes; 749 rand_node = rand() % num_nodes;
755 getnodes(close_clientlist[index[rand_node]].ip_port, 750 getnodes(close_clientlist[index[rand_node]].ip_port,
756 close_clientlist[index[rand_node]].client_id, 751 close_clientlist[index[rand_node]].client_id,
757 self_public_key); 752 self_public_key);
758 close_lastgetnodes = temp_time; 753 close_lastgetnodes = temp_time;
759 } 754 }
@@ -761,7 +756,7 @@ void doClose() /* tested */
761 756
762void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) 757void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
763{ 758{
764 getnodes(ip_port, public_key, self_public_key); 759 getnodes(ip_port, public_key, self_public_key);
765} 760}
766 761
767/* send the given packet to node with client_id 762/* send the given packet to node with client_id
@@ -775,7 +770,7 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
775 return -1; 770 return -1;
776} 771}
777 772
778/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist 773/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
779 ip_portlist must be at least MAX_FRIEND_CLIENTS big 774 ip_portlist must be at least MAX_FRIEND_CLIENTS big
780 returns the number of ips returned 775 returns the number of ips returned
781 return 0 if we are connected to friend or if no ips were found. 776 return 0 if we are connected to friend or if no ips were found.
@@ -788,9 +783,9 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
788 if(friend_num >= num_friends) 783 if(friend_num >= num_friends)
789 return -1; 784 return -1;
790 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 785 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
791 /*If ip is not zero and node is good */ 786 /*If ip is not zero and node is good */
792 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && 787 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
793 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { 788 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
794 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) 789 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 )
795 return 0; 790 return 0;
796 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; 791 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port;
@@ -807,11 +802,11 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
807 uint32_t sent = 0; 802 uint32_t sent = 0;
808 uint32_t temp_time = unix_time(); 803 uint32_t temp_time = unix_time();
809 for(i = 0; i < num_friends; ++i) 804 for(i = 0; i < num_friends; ++i)
810 /* Equal */ 805 /* Equal */
811 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { 806 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
812 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 807 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
813 /*If ip is not zero and node is good */ 808 /*If ip is not zero and node is good */
814 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 809 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
815 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 810 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time)
816 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) 811 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length)
817 ++sent; 812 ++sent;
@@ -827,15 +822,15 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
827 int num = friend_number(friend_id); 822 int num = friend_number(friend_id);
828 if(num == -1) 823 if(num == -1)
829 return 0; 824 return 0;
830 825
831 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 826 IP_Port ip_list[MAX_FRIEND_CLIENTS];
832 int n = 0; 827 int n = 0;
833 uint32_t i; 828 uint32_t i;
834 uint32_t temp_time = unix_time(); 829 uint32_t temp_time = unix_time();
835 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 830 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
836 /*If ip is not zero and node is good */ 831 /*If ip is not zero and node is good */
837 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && 832 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
838 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { 833 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
839 ip_list[n] = friends_list[num].client_list[i].ip_port; 834 ip_list[n] = friends_list[num].client_list[i].ip_port;
840 ++n; 835 ++n;
841 } 836 }
@@ -846,7 +841,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
846 return 0; 841 return 0;
847} 842}
848 843
849/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 844/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
850 ip_portlist must be at least MAX_FRIEND_CLIENTS big 845 ip_portlist must be at least MAX_FRIEND_CLIENTS big
851 returns the number of ips returned 846 returns the number of ips returned
852 return 0 if we are connected to friend or if no ips were found. 847 return 0 if we are connected to friend or if no ips were found.
@@ -856,7 +851,7 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
856 851
857 uint32_t i; 852 uint32_t i;
858 for(i = 0; i < num_friends; ++i) 853 for(i = 0; i < num_friends; ++i)
859 /* Equal */ 854 /* Equal */
860 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) 855 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0)
861 return friend_iplist(ip_portlist, i); 856 return friend_iplist(ip_portlist, i);
862 return -1; 857 return -1;
@@ -869,7 +864,7 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
869 uint8_t data[sizeof(uint64_t) + 1]; 864 uint8_t data[sizeof(uint64_t) + 1];
870 data[0] = type; 865 data[0] = type;
871 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 866 memcpy(data + 1, &ping_id, sizeof(uint64_t));
872 867
873 uint8_t packet[MAX_DATA_SIZE]; 868 uint8_t packet[MAX_DATA_SIZE];
874 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */ 869 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
875 if(len == -1) 870 if(len == -1)
@@ -890,9 +885,9 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
890int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) 885int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
891{ 886{
892 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 887 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
893 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 888 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
894 return 1; 889 return 1;
895 /* check if request is for us. */ 890 /* check if request is for us. */
896 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 891 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
897 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 892 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
898 uint8_t data[MAX_DATA_SIZE]; 893 uint8_t data[MAX_DATA_SIZE];
@@ -901,11 +896,11 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
901 return 1; 896 return 1;
902 uint64_t ping_id; 897 uint64_t ping_id;
903 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 898 memcpy(&ping_id, data + 1, sizeof(uint64_t));
904 899
905 int friendnumber = friend_number(public_key); 900 int friendnumber = friend_number(public_key);
906 if(friendnumber == -1) 901 if(friendnumber == -1)
907 return 1; 902 return 1;
908 903
909 if(data[0] == 0) { 904 if(data[0] == 0) {
910 send_NATping(public_key, ping_id, 1); /*1 is reply*/ 905 send_NATping(public_key, ping_id, 1); /*1 is reply*/
911 return 0; 906 return 0;
@@ -917,10 +912,9 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
917 } 912 }
918 return 1; 913 return 1;
919 } 914 }
920 /* if request is not for us, try routing it. */ 915 /* if request is not for us, try routing it. */
921 else 916 else if(route_packet(packet + 1, packet, length) == length)
922 if(route_packet(packet + 1, packet, length) == length) 917 return 0;
923 return 0;
924 return 0; 918 return 0;
925} 919}
926 920
@@ -933,7 +927,7 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
933 IP zero = {{0}}; 927 IP zero = {{0}};
934 if(len > MAX_FRIEND_CLIENTS) 928 if(len > MAX_FRIEND_CLIENTS)
935 return zero; 929 return zero;
936 930
937 uint32_t i, j; 931 uint32_t i, j;
938 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; 932 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
939 for(i = 0; i < len; ++i) { 933 for(i = 0; i < len; ++i) {
@@ -998,8 +992,7 @@ static void doNAT()
998 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 992 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
999 friends_list[i].NATping_timestamp = temp_time; 993 friends_list[i].NATping_timestamp = temp_time;
1000 } 994 }
1001 } 995 } else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
1002 else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
1003 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); 996 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1004 if(ip.i == 0) 997 if(ip.i == 0)
1005 continue; 998 continue;
@@ -1020,23 +1013,23 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1020{ 1013{
1021 switch (packet[0]) { 1014 switch (packet[0]) {
1022 case 0: 1015 case 0:
1023 return handle_pingreq(packet, length, source); 1016 return handle_pingreq(packet, length, source);
1024 1017
1025 case 1: 1018 case 1:
1026 return handle_pingres(packet, length, source); 1019 return handle_pingres(packet, length, source);
1027 1020
1028 case 2: 1021 case 2:
1029 return handle_getnodes(packet, length, source); 1022 return handle_getnodes(packet, length, source);
1030 1023
1031 case 3: 1024 case 3:
1032 return handle_sendnodes(packet, length, source); 1025 return handle_sendnodes(packet, length, source);
1033 1026
1034 case 254: 1027 case 254:
1035 return handle_NATping(packet, length, source); 1028 return handle_NATping(packet, length, source);
1036 1029
1037 default: 1030 default:
1038 return 1; 1031 return 1;
1039 1032
1040 } 1033 }
1041 1034
1042 return 0; 1035 return 0;
@@ -1074,17 +1067,17 @@ int DHT_load(uint8_t * data, uint32_t size)
1074 uint32_t i, j; 1067 uint32_t i, j;
1075 /* uint32_t temp_time = unix_time(); */ 1068 /* uint32_t temp_time = unix_time(); */
1076 uint16_t temp; 1069 uint16_t temp;
1077 1070
1078 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1071 temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1079 1072
1080 if(temp != 0) { 1073 if(temp != 0) {
1081 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1074 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1082 1075
1083 for(i = 0; i < temp; ++i) { 1076 for(i = 0; i < temp; ++i) {
1084 DHT_addfriend(tempfriends_list[i].client_id); 1077 DHT_addfriend(tempfriends_list[i].client_id);
1085 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1078 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
1086 if(tempfriends_list[i].client_list[j].timestamp != 0) { 1079 if(tempfriends_list[i].client_list[j].timestamp != 0) {
1087 getnodes(tempfriends_list[i].client_list[j].ip_port, 1080 getnodes(tempfriends_list[i].client_list[j].ip_port,
1088 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); 1081 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id);
1089 } 1082 }
1090 } 1083 }
diff --git a/core/DHT.h b/core/DHT.h
index f306026e..edab264b 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -1,7 +1,7 @@
1/* DHT.h 1/* DHT.h
2 * 2 *
3 * An implementation of the DHT as seen in docs/DHT.txt 3 * An implementation of the DHT as seen in docs/DHT.txt
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,11 +18,11 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
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 "net_crypto.h"
28 28
@@ -30,79 +30,79 @@
30extern "C" { 30extern "C" {
31#endif 31#endif
32 32
33/* Current time, unix format */ 33 /* Current time, unix format */
34#define unix_time() ((uint32_t)time(NULL)) 34#define unix_time() ((uint32_t)time(NULL))
35 35
36/* size of the client_id in bytes */ 36 /* size of the client_id in bytes */
37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES 37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
38 38
39/* Add a new friend to the friends list 39 /* Add a new friend to the friends list
40 client_id must be CLIENT_ID_SIZE bytes long. 40 client_id must be CLIENT_ID_SIZE bytes long.
41 returns 0 if success 41 returns 0 if success
42 returns 1 if failure (friends list is full) */ 42 returns 1 if failure (friends list is full) */
43int DHT_addfriend(uint8_t *client_id); 43 int DHT_addfriend(uint8_t *client_id);
44 44
45/* Delete a friend from the friends list 45 /* Delete a friend from the friends list
46 client_id must be CLIENT_ID_SIZE bytes long. 46 client_id must be CLIENT_ID_SIZE bytes long.
47 returns 0 if success 47 returns 0 if success
48 returns 1 if failure (client_id not in friends list) */ 48 returns 1 if failure (client_id not in friends list) */
49int DHT_delfriend(uint8_t *client_id); 49 int DHT_delfriend(uint8_t *client_id);
50 50
51/* Get ip of friend 51 /* Get ip of friend
52 client_id must be CLIENT_ID_SIZE bytes long. 52 client_id must be CLIENT_ID_SIZE bytes long.
53 ip must be 4 bytes long. 53 ip must be 4 bytes long.
54 port must be 2 bytes long. 54 port must be 2 bytes long.
55 returns ip if success 55 returns ip if success
56 returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) 56 returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.)
57 returns ip of 1 if friend is not in list. */ 57 returns ip of 1 if friend is not in list. */
58IP_Port DHT_getfriendip(uint8_t *client_id); 58 IP_Port DHT_getfriendip(uint8_t *client_id);
59 59
60/* Run this function at least a couple times per second (It's the main loop) */ 60 /* Run this function at least a couple times per second (It's the main loop) */
61void doDHT(); 61 void doDHT();
62 62
63/* if we receive a DHT packet we call this function so it can be handled. 63 /* if we receive a DHT packet we call this function so it can be handled.
64 return 0 if packet is handled correctly. 64 return 0 if packet is handled correctly.
65 return 1 if it didn't handle the packet or if the packet was shit. */ 65 return 1 if it didn't handle the packet or if the packet was shit. */
66int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); 66 int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
67 67
68/* Use this function to bootstrap the client 68 /* Use this function to bootstrap the client
69 Sends a get nodes request to the given node with ip port and public_key */ 69 Sends a get nodes request to the given node with ip port and public_key */
70void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); 70 void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
71 71
72/* ROUTING FUNCTIONS */ 72 /* ROUTING FUNCTIONS */
73 73
74/* send the given packet to node with client_id 74 /* send the given packet to node with client_id
75 returns -1 if failure */ 75 returns -1 if failure */
76int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length); 76 int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length);
77 77
78/* Send the following packet to everyone who tells us they are connected to friend_id 78 /* Send the following packet to everyone who tells us they are connected to friend_id
79 returns the number of nodes it sent the packet to */ 79 returns the number of nodes it sent the packet to */
80int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); 80 int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length);
81 81
82/* NAT PUNCHING FUNCTIONS */ 82 /* NAT PUNCHING FUNCTIONS */
83 83
84/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 84 /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
85 ip_portlist must be at least MAX_FRIEND_CLIENTS big 85 ip_portlist must be at least MAX_FRIEND_CLIENTS big
86 returns the number of ips returned 86 returns the number of ips returned
87 returns -1 if no such friend*/ 87 returns -1 if no such friend*/
88int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id); 88 int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id);
89 89
90/* SAVE/LOAD functions */ 90 /* SAVE/LOAD functions */
91 91
92/* get the size of the DHT (for saving) */ 92 /* get the size of the DHT (for saving) */
93uint32_t DHT_size(); 93 uint32_t DHT_size();
94 94
95/* save the DHT in data where data is an array of size DHT_size() */ 95 /* save the DHT in data where data is an array of size DHT_size() */
96void DHT_save(uint8_t *data); 96 void DHT_save(uint8_t *data);
97 97
98/* load the DHT from data of size size; 98 /* load the DHT from data of size size;
99 return -1 if failure 99 return -1 if failure
100 return 0 if success */ 100 return 0 if success */
101int DHT_load(uint8_t *data, uint32_t size); 101 int DHT_load(uint8_t *data, uint32_t size);
102 102
103/* returns 0 if we are not connected to the DHT 103 /* returns 0 if we are not connected to the DHT
104 returns 1 if we are */ 104 returns 1 if we are */
105int DHT_isconnected(); 105 int DHT_isconnected();
106 106
107#ifdef __cplusplus 107#ifdef __cplusplus
108} 108}
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c
index 1ac13c33..0a23914d 100644
--- a/core/LAN_discovery.c
+++ b/core/LAN_discovery.c
@@ -1,7 +1,7 @@
1/* LAN_discovery.c 1/* LAN_discovery.c
2 * 2 *
3 * LAN discovery implementation. 3 * LAN discovery implementation.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#include "LAN_discovery.h" 24#include "LAN_discovery.h"
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h
index cca5bd30..3c056ba6 100644
--- a/core/LAN_discovery.h
+++ b/core/LAN_discovery.h
@@ -1,7 +1,7 @@
1/* LAN_discovery.h 1/* LAN_discovery.h
2 * 2 *
3 * LAN discovery implementation. 3 * LAN discovery implementation.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,12 +18,12 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24 24
25#ifndef LAN_DISCOVERY_H 25#ifndef LAN_DISCOVERY_H
26#define LAN_DISCOVERY_H 26#define LAN_DISCOVERY_H
27 27
28 28
29#include "DHT.h" 29#include "DHT.h"
@@ -32,14 +32,14 @@
32extern "C" { 32extern "C" {
33#endif 33#endif
34 34
35/*Send a LAN discovery pcaket to the broadcast address with port port*/ 35 /*Send a LAN discovery pcaket to the broadcast address with port port*/
36int send_LANdiscovery(uint16_t port); 36 int send_LANdiscovery(uint16_t port);
37 37
38 38
39/* if we receive a packet we call this function so it can be handled. 39 /* if we receive a packet we call this function so it can be handled.
40 return 0 if packet is handled correctly. 40 return 0 if packet is handled correctly.
41 return 1 if it didn't handle the packet or if the packet was shit. */ 41 return 1 if it didn't handle the packet or if the packet was shit. */
42int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); 42 int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
43 43
44 44
45 45
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index f9d20b2f..0194375a 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -1,7 +1,7 @@
1/* Lossless_UDP.c 1/* Lossless_UDP.c
2 * 2 *
3 * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt 3 * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24/* TODO: clean this file a bit. 24/* TODO: clean this file a bit.
@@ -47,18 +47,18 @@ timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION
47typedef struct { 47typedef struct {
48 uint8_t data[MAX_DATA_SIZE]; 48 uint8_t data[MAX_DATA_SIZE];
49 uint16_t size; 49 uint16_t size;
50}Data; 50} Data;
51 51
52typedef struct { 52typedef struct {
53 IP_Port ip_port; 53 IP_Port ip_port;
54 uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, 54 uint8_t status; /* 0 if connection is dead, 1 if attempting handshake,
55 2 if handshake is done (we start sending SYNC packets) 55 2 if handshake is done (we start sending SYNC packets)
56 3 if we are sending SYNC packets and can send data 56 3 if we are sending SYNC packets and can send data
57 4 if the connection has timed out. */ 57 4 if the connection has timed out. */
58 58
59 uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. 59 uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not.
60 2 if incoming_connection() has not returned it yet, 1 if it has. */ 60 2 if incoming_connection() has not returned it yet, 1 if it has. */
61 61
62 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ 62 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
63 uint16_t data_rate; /* current data packet send rate packets per second. */ 63 uint16_t data_rate; /* current data packet send rate packets per second. */
64 uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ 64 uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */
@@ -82,7 +82,7 @@ typedef struct {
82 uint8_t recv_counter; 82 uint8_t recv_counter;
83 uint8_t send_counter; 83 uint8_t send_counter;
84 uint8_t timeout; /* connection timeout in seconds. */ 84 uint8_t timeout; /* connection timeout in seconds. */
85}Connection; 85} Connection;
86 86
87#define MAX_CONNECTIONS 256 87#define MAX_CONNECTIONS 256
88 88
@@ -95,10 +95,11 @@ static Connection connections[MAX_CONNECTIONS];
95/* get connection id from IP_Port 95/* get connection id from IP_Port
96 return -1 if there are no connections like we are looking for 96 return -1 if there are no connections like we are looking for
97 return id if it found it */ 97 return id if it found it */
98int getconnection_id(IP_Port ip_port) { 98int getconnection_id(IP_Port ip_port)
99{
99 uint32_t i; 100 uint32_t i;
100 for (i = 0; i < MAX_CONNECTIONS; ++i) { 101 for (i = 0; i < MAX_CONNECTIONS; ++i) {
101 if (connections[i].ip_port.ip.i == ip_port.ip.i && 102 if (connections[i].ip_port.ip.i == ip_port.ip.i &&
102 connections[i].ip_port.port == ip_port.port && connections[i].status > 0) 103 connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
103 return i; 104 return i;
104 } 105 }
@@ -384,10 +385,10 @@ int send_data_packet(uint32_t connection_id, uint32_t packet_num)
384 packet[0] = 18; 385 packet[0] = 18;
385 temp = htonl(packet_num); 386 temp = htonl(packet_num);
386 memcpy(packet + 1, &temp, 4); 387 memcpy(packet + 1, &temp, 4);
387 memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, 388 memcpy(packet + 5, connections[connection_id].sendbuffer[index].data,
388 connections[connection_id].sendbuffer[index].size); 389 connections[connection_id].sendbuffer[index].size);
389 return sendpacket(connections[connection_id].ip_port, packet, 390 return sendpacket(connections[connection_id].ip_port, packet,
390 1 + 4 + connections[connection_id].sendbuffer[index].size); 391 1 + 4 + connections[connection_id].sendbuffer[index].size);
391} 392}
392 393
393/* sends 1 data packet */ 394/* sends 1 data packet */
@@ -395,7 +396,7 @@ int send_DATA(uint32_t connection_id)
395{ 396{
396 int ret; 397 int ret;
397 uint32_t buffer[BUFFER_PACKET_NUM]; 398 uint32_t buffer[BUFFER_PACKET_NUM];
398 if (connections[connection_id].num_req_paquets > 0) { 399 if (connections[connection_id].num_req_paquets > 0) {
399 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); 400 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
400 connections[connection_id].num_req_paquets--; 401 connections[connection_id].num_req_paquets--;
401 memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); 402 memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4);
@@ -416,9 +417,9 @@ int send_DATA(uint32_t connection_id)
416 One to handle each type of packets we receive 417 One to handle each type of packets we receive
417 return 0 if handled correctly, 1 if packet is bad. */ 418 return 0 if handled correctly, 1 if packet is bad. */
418int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) 419int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
419{ 420{
420 if (length != (1 + 4 + 4)) 421 if (length != (1 + 4 + 4))
421 return 1; 422 return 1;
422 uint32_t temp; 423 uint32_t temp;
423 uint32_t handshake_id1, handshake_id2; 424 uint32_t handshake_id1, handshake_id2;
424 int connection = getconnection_id(source); 425 int connection = getconnection_id(source);
@@ -426,7 +427,7 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
426 handshake_id1 = ntohl(temp); 427 handshake_id1 = ntohl(temp);
427 memcpy(&temp, packet + 5, 4); 428 memcpy(&temp, packet + 5, 4);
428 handshake_id2 = ntohl(temp); 429 handshake_id2 = ntohl(temp);
429 430
430 if (handshake_id2 == 0) { 431 if (handshake_id2 == 0) {
431 send_handshake(source, handshake_id(source), handshake_id1); 432 send_handshake(source, handshake_id(source), handshake_id1);
432 return 0; 433 return 0;
@@ -452,7 +453,7 @@ int SYNC_valid(uint32_t length)
452{ 453{
453 if (length < 4 + 4 + 2) 454 if (length < 4 + 4 + 2)
454 return 0; 455 return 0;
455 if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || 456 if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) ||
456 ((length - 4 - 4 - 2) % 4) != 0) 457 ((length - 4 - 4 - 2) % 4) != 0)
457 return 0; 458 return 0;
458 return 1; 459 return 1;
@@ -482,7 +483,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu
482int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 483int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
483{ 484{
484 if (recv_packetnum == connections[connection_id].orecv_packetnum) { 485 if (recv_packetnum == connections[connection_id].orecv_packetnum) {
485 /* && sent_packetnum == connections[connection_id].osent_packetnum) */ 486 /* && sent_packetnum == connections[connection_id].osent_packetnum) */
486 connections[connection_id].status = 3; 487 connections[connection_id].status = 3;
487 connections[connection_id].recv_counter = counter; 488 connections[connection_id].recv_counter = counter;
488 ++connections[connection_id].send_counter; 489 ++connections[connection_id].send_counter;
@@ -522,14 +523,14 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
522{ 523{
523 524
524 if (!SYNC_valid(length)) 525 if (!SYNC_valid(length))
525 return 1; 526 return 1;
526 int connection = getconnection_id(source); 527 int connection = getconnection_id(source);
527 uint8_t counter; 528 uint8_t counter;
528 uint32_t temp; 529 uint32_t temp;
529 uint32_t recv_packetnum, sent_packetnum; 530 uint32_t recv_packetnum, sent_packetnum;
530 uint32_t req_packets[BUFFER_PACKET_NUM]; 531 uint32_t req_packets[BUFFER_PACKET_NUM];
531 uint16_t number = (length - 4 - 4 - 2)/ 4; 532 uint16_t number = (length - 4 - 4 - 2)/ 4;
532 533
533 memcpy(&counter, packet + 1, 1); 534 memcpy(&counter, packet + 1, 1);
534 memcpy(&temp, packet + 2, 4); 535 memcpy(&temp, packet + 2, 4);
535 recv_packetnum = ntohl(temp); 536 recv_packetnum = ntohl(temp);
@@ -556,7 +557,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
556 uint32_t i; 557 uint32_t i;
557 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; 558 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM;
558 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; 559 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum;
559 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 560 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
560 if (i == data_num) { 561 if (i == data_num) {
561 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); 562 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
562 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; 563 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
@@ -568,7 +569,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
568 } 569 }
569 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 570 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
570 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) 571 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
571 connections[connection_id].recv_packetnum = i; 572 connections[connection_id].recv_packetnum = i;
572 else 573 else
573 break; 574 break;
574 } 575 }
@@ -603,15 +604,15 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
603{ 604{
604 switch (packet[0]) { //TODO: check if no break statement is correct??? 605 switch (packet[0]) { //TODO: check if no break statement is correct???
605 case 16: 606 case 16:
606 return handle_handshake(packet, length, source); 607 return handle_handshake(packet, length, source);
607 608
608 case 17: 609 case 17:
609 return handle_SYNC(packet, length, source); 610 return handle_SYNC(packet, length, source);
610 611
611 case 18: 612 case 18:
612 return handle_data(packet, length, source); 613 return handle_data(packet, length, source);
613 614
614 default: 615 default:
615 return 1; 616 return 1;
616 } 617 }
617 618
@@ -627,13 +628,13 @@ void doNew()
627 for (i = 0; i < MAX_CONNECTIONS; ++i) { 628 for (i = 0; i < MAX_CONNECTIONS; ++i) {
628 if (connections[i].status == 1) 629 if (connections[i].status == 1)
629 if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { 630 if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
630 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); 631 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
631 connections[i].last_sent = temp_time; 632 connections[i].last_sent = temp_time;
632 } 633 }
633 634
634 /* kill all timed out connections */ 635 /* kill all timed out connections */
635 if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 636 if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
636 connections[i].status != 4) 637 connections[i].status != 4)
637 /* kill_connection(i); */ 638 /* kill_connection(i); */
638 connections[i].status = 4; 639 connections[i].status = 4;
639 if (connections[i].status > 0 && connections[i].killat < temp_time) 640 if (connections[i].status > 0 && connections[i].killat < temp_time)
@@ -648,8 +649,8 @@ void doSYNC()
648 for (i = 0; i < MAX_CONNECTIONS; ++i) { 649 for (i = 0; i < MAX_CONNECTIONS; ++i) {
649 if (connections[i].status == 2 || connections[i].status == 3) 650 if (connections[i].status == 2 || connections[i].status == 3)
650 if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { 651 if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) {
651 send_SYNC(i); 652 send_SYNC(i);
652 connections[i].last_SYNC = temp_time; 653 connections[i].last_SYNC = temp_time;
653 } 654 }
654 } 655 }
655} 656}
@@ -682,10 +683,9 @@ void adjustRates()
682 connections[i].SYNC_rate = MAX_SYNC_RATE; 683 connections[i].SYNC_rate = MAX_SYNC_RATE;
683 if (connections[i].status == 3) { 684 if (connections[i].status == 3) {
684 if (sendqueue(i) != 0) { 685 if (sendqueue(i) != 0) {
685 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; 686 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;
686 connections[i].SYNC_rate = MAX_SYNC_RATE; 687 connections[i].SYNC_rate = MAX_SYNC_RATE;
687 } 688 } else if (connections[i].last_recvdata + 1000000UL > temp_time)
688 else if (connections[i].last_recvdata + 1000000UL > temp_time)
689 connections[i].SYNC_rate = MAX_SYNC_RATE; 689 connections[i].SYNC_rate = MAX_SYNC_RATE;
690 else 690 else
691 connections[i].SYNC_rate = SYNC_RATE; 691 connections[i].SYNC_rate = SYNC_RATE;
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index d27fea79..72214370 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -1,7 +1,7 @@
1/* Lossless_UDP.h 1/* Lossless_UDP.h
2 * 2 *
3 * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt 3 * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,11 +18,11 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#ifndef LOSSLESS_UDP_H 24#ifndef LOSSLESS_UDP_H
25#define LOSSLESS_UDP_H 25#define LOSSLESS_UDP_H
26 26
27#include "network.h" 27#include "network.h"
28 28
@@ -30,74 +30,74 @@
30extern "C" { 30extern "C" {
31#endif 31#endif
32 32
33/* maximum length of the data in the data packets */ 33 /* maximum length of the data in the data packets */
34#define MAX_DATA_SIZE 1024 34#define MAX_DATA_SIZE 1024
35 35
36/* Functions */ 36 /* Functions */
37 37
38/* initialize a new connection to ip_port 38 /* initialize a new connection to ip_port
39 returns an integer corresponding to the connection id. 39 returns an integer corresponding to the connection id.
40 return -1 if it could not initialize the connection. 40 return -1 if it could not initialize the connection.
41 if there already was an existing connection to that ip_port return its number. */ 41 if there already was an existing connection to that ip_port return its number. */
42int new_connection(IP_Port ip_port); 42 int new_connection(IP_Port ip_port);
43 43
44/* get connection id from IP_Port 44 /* get connection id from IP_Port
45 return -1 if there are no connections like we are looking for 45 return -1 if there are no connections like we are looking for
46 return id if it found it */ 46 return id if it found it */
47int getconnection_id(IP_Port ip_port); 47 int getconnection_id(IP_Port ip_port);
48 48
49/* returns an integer corresponding to the next connection in our imcoming connection list 49 /* returns an integer corresponding to the next connection in our imcoming connection list
50 return -1 if there are no new incoming connections in the list. */ 50 return -1 if there are no new incoming connections in the list. */
51int incoming_connection(); 51 int incoming_connection();
52 52
53/* return -1 if it could not kill the connection. 53 /* return -1 if it could not kill the connection.
54 return 0 if killed successfully */ 54 return 0 if killed successfully */
55int kill_connection(int connection_id); 55 int kill_connection(int connection_id);
56 56
57/* kill connection in seconds seconds. 57 /* kill connection in seconds seconds.
58 return -1 if it can not kill the connection. 58 return -1 if it can not kill the connection.
59 return 0 if it will kill it */ 59 return 0 if it will kill it */
60int kill_connection_in(int connection_id, uint32_t seconds); 60 int kill_connection_in(int connection_id, uint32_t seconds);
61 61
62/* returns the ip_port of the corresponding connection. 62 /* returns the ip_port of the corresponding connection.
63 return 0 if there is no such connection. */ 63 return 0 if there is no such connection. */
64IP_Port connection_ip(int connection_id); 64 IP_Port connection_ip(int connection_id);
65 65
66/* returns the id of the next packet in the queue 66 /* returns the id of the next packet in the queue
67 return -1 if no packet in queue */ 67 return -1 if no packet in queue */
68char id_packet(int connection_id); 68 char id_packet(int connection_id);
69 69
70/* return 0 if there is no received data in the buffer. 70 /* return 0 if there is no received data in the buffer.
71 return length of received packet if successful */ 71 return length of received packet if successful */
72int read_packet(int connection_id, uint8_t *data); 72 int read_packet(int connection_id, uint8_t *data);
73 73
74/* return 0 if data could not be put in packet queue 74 /* return 0 if data could not be put in packet queue
75 return 1 if data was put into the queue */ 75 return 1 if data was put into the queue */
76int write_packet(int connection_id, uint8_t *data, uint32_t length); 76 int write_packet(int connection_id, uint8_t *data, uint32_t length);
77 77
78/* returns the number of packets in the queue waiting to be successfully sent. */ 78 /* returns the number of packets in the queue waiting to be successfully sent. */
79uint32_t sendqueue(int connection_id); 79 uint32_t sendqueue(int connection_id);
80 80
81/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ 81 /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
82uint32_t recvqueue(int connection_id); 82 uint32_t recvqueue(int connection_id);
83 83
84/* check if connection is connected 84 /* check if connection is connected
85 return 0 no. 85 return 0 no.
86 return 1 if attempting handshake 86 return 1 if attempting handshake
87 return 2 if handshake is done 87 return 2 if handshake is done
88 return 3 if fully connected 88 return 3 if fully connected
89 return 4 if timed out and wating to be killed */ 89 return 4 if timed out and wating to be killed */
90int is_connected(int connection_id); 90 int is_connected(int connection_id);
91 91
92/* Call this function a couple times per second 92 /* Call this function a couple times per second
93 It's the main loop. */ 93 It's the main loop. */
94void doLossless_UDP(); 94 void doLossless_UDP();
95 95
96 96
97/* if we receive a Lossless_UDP packet we call this function so it can be handled. 97 /* if we receive a Lossless_UDP packet we call this function so it can be handled.
98 return 0 if packet is handled correctly. 98 return 0 if packet is handled correctly.
99 return 1 if it didn't handle the packet or if the packet was shit. */ 99 return 1 if it didn't handle the packet or if the packet was shit. */
100int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); 100 int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
101 101
102#ifdef __cplusplus 102#ifdef __cplusplus
103} 103}
diff --git a/core/Messenger.c b/core/Messenger.c
index fd95869f..86056df8 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -18,12 +18,12 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#include "Messenger.h" 24#include "Messenger.h"
25#define MIN(a,b) (((a)<(b))?(a):(b)) 25#define MIN(a,b) (((a)<(b))?(a):(b))
26 26
27typedef struct { 27typedef struct {
28 uint8_t client_id[CLIENT_ID_SIZE]; 28 uint8_t client_id[CLIENT_ID_SIZE];
29 int crypt_connection_id; 29 int crypt_connection_id;
@@ -49,7 +49,7 @@ static uint16_t self_userstatus_len;
49static Friend friendlist[MAX_NUM_FRIENDS]; 49static Friend friendlist[MAX_NUM_FRIENDS];
50 50
51static uint32_t numfriends; 51static uint32_t numfriends;
52 52
53/* 1 if we are online 53/* 1 if we are online
54 0 if we are offline 54 0 if we are offline
55 static uint8_t online; */ 55 static uint8_t online; */
@@ -95,7 +95,7 @@ int getclient_id(int friend_id, uint8_t *client_id)
95int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) 95int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
96{ 96{
97 if (length == 0 || length >= 97 if (length == 0 || length >=
98 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) 98 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
99 return -1; 99 return -1;
100 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 100 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
101 return -1; 101 return -1;
@@ -113,7 +113,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
113 friendlist[i].userstatus_length = 1; 113 friendlist[i].userstatus_length = 1;
114 memcpy(friendlist[i].info, data, length); 114 memcpy(friendlist[i].info, data, length);
115 friendlist[i].info_size = length; 115 friendlist[i].info_size = length;
116 116
117 ++numfriends; 117 ++numfriends;
118 return i; 118 return i;
119 } 119 }
@@ -183,7 +183,7 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
183 if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) 183 if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS)
184 return 0; 184 return 0;
185 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) 185 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
186 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ 186 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
187 return 0; 187 return 0;
188 uint8_t temp[MAX_DATA_SIZE]; 188 uint8_t temp[MAX_DATA_SIZE];
189 temp[0] = PACKET_ID_MESSAGE; 189 temp[0] = PACKET_ID_MESSAGE;
@@ -349,7 +349,8 @@ int initMessenger()
349 349
350//TODO: make this function not suck. 350//TODO: make this function not suck.
351static void doFriends() 351static void doFriends()
352{/* TODO: add incoming connections and some other stuff. */ 352{
353 /* TODO: add incoming connections and some other stuff. */
353 uint32_t i; 354 uint32_t i;
354 int len; 355 int len;
355 uint8_t temp[MAX_DATA_SIZE]; 356 uint8_t temp[MAX_DATA_SIZE];
@@ -370,19 +371,19 @@ static void doFriends()
370 } 371 }
371 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); 372 IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
372 switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) { 373 switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) {
373 case 0: 374 case 0:
374 if (friendip.ip.i > 1) 375 if (friendip.ip.i > 1)
375 friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); 376 friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
376 break; 377 break;
377 case 3: /* Connection is established */ 378 case 3: /* Connection is established */
378 friendlist[i].status = 4; 379 friendlist[i].status = 4;
379 break; 380 break;
380 case 4: 381 case 4:
381 crypto_kill(friendlist[i].crypt_connection_id); 382 crypto_kill(friendlist[i].crypt_connection_id);
382 friendlist[i].crypt_connection_id = -1; 383 friendlist[i].crypt_connection_id = -1;
383 break; 384 break;
384 default: 385 default:
385 break; 386 break;
386 } 387 }
387 } 388 }
388 while (friendlist[i].status == 4) { /* friend is online */ 389 while (friendlist[i].status == 4) { /* friend is online */
@@ -397,38 +398,37 @@ static void doFriends()
397 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); 398 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
398 if (len > 0) { 399 if (len > 0) {
399 switch (temp[0]) { 400 switch (temp[0]) {
400 case PACKET_ID_NICKNAME: { 401 case PACKET_ID_NICKNAME: {
401 if (len != MAX_NAME_LENGTH + 1) 402 if (len != MAX_NAME_LENGTH + 1)
402 break;
403 if(friend_namechange_isset)
404 friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */
405 memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH);
406 friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */
407 break; 403 break;
408 } 404 if(friend_namechange_isset)
409 case PACKET_ID_USERSTATUS: { 405 friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */
410 uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1); 406 memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH);
411 memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH)); 407 friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */
412 if (friend_statuschange_isset) 408 break;
413 friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
414 set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
415 free(status);
416 break;
417 }
418 case PACKET_ID_MESSAGE: {
419 if (friend_message_isset)
420 (*friend_message)(i, temp + 1, len - 1);
421 break;
422 }
423 } 409 }
424 } 410 case PACKET_ID_USERSTATUS: {
425 else { 411 uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1);
426 if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ 412 memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH));
427 crypto_kill(friendlist[i].crypt_connection_id); 413 if (friend_statuschange_isset)
428 friendlist[i].crypt_connection_id = -1; 414 friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
429 friendlist[i].status = 3; 415 set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
430 } 416 free(status);
431 break; 417 break;
418 }
419 case PACKET_ID_MESSAGE: {
420 if (friend_message_isset)
421 (*friend_message)(i, temp + 1, len - 1);
422 break;
423 }
424 }
425 } else {
426 if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
427 crypto_kill(friendlist[i].crypt_connection_id);
428 friendlist[i].crypt_connection_id = -1;
429 friendlist[i].status = 3;
430 }
431 break;
432 } 432 }
433 } 433 }
434 } 434 }
@@ -443,11 +443,11 @@ static void doInbound()
443 if (inconnection != -1) { 443 if (inconnection != -1) {
444 int friend_id = getfriend_id(public_key); 444 int friend_id = getfriend_id(public_key);
445 if (friend_id != -1) { 445 if (friend_id != -1) {
446 crypto_kill(friendlist[friend_id].crypt_connection_id); 446 crypto_kill(friendlist[friend_id].crypt_connection_id);
447 friendlist[friend_id].crypt_connection_id = 447 friendlist[friend_id].crypt_connection_id =
448 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); 448 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
449 449
450 friendlist[friend_id].status = 3; 450 friendlist[friend_id].status = 3;
451 } 451 }
452 } 452 }
453} 453}
@@ -477,8 +477,8 @@ void doMessenger()
477#ifdef DEBUG 477#ifdef DEBUG
478 /* if(rand() % 3 != 1) //simulate packet loss */ 478 /* if(rand() % 3 != 1) //simulate packet loss */
479 /* { */ 479 /* { */
480 if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && 480 if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) &&
481 friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port)) 481 friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port))
482 /* if packet is discarded */ 482 /* if packet is discarded */
483 printf("Received unhandled packet with length: %u\n", length); 483 printf("Received unhandled packet with length: %u\n", length);
484 else 484 else
@@ -505,7 +505,7 @@ void doMessenger()
505uint32_t Messenger_size() 505uint32_t Messenger_size()
506{ 506{
507 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES 507 return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES
508 + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends; 508 + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends;
509} 509}
510 510
511/* save the messenger in data of size Messenger_size() */ 511/* save the messenger in data of size Messenger_size() */
@@ -537,7 +537,7 @@ int Messenger_load(uint8_t * data, uint32_t length)
537 uint32_t size; 537 uint32_t size;
538 memcpy(&size, data, sizeof(size)); 538 memcpy(&size, data, sizeof(size));
539 data += sizeof(size); 539 data += sizeof(size);
540 540
541 if (length < size) 541 if (length < size)
542 return -1; 542 return -1;
543 length -= size; 543 length -= size;
@@ -548,12 +548,12 @@ int Messenger_load(uint8_t * data, uint32_t length)
548 data += sizeof(size); 548 data += sizeof(size);
549 if (length != size || length % sizeof(Friend) != 0) 549 if (length != size || length % sizeof(Friend) != 0)
550 return -1; 550 return -1;
551 551
552 Friend * temp = malloc(size); 552 Friend * temp = malloc(size);
553 memcpy(temp, data, size); 553 memcpy(temp, data, size);
554 554
555 uint16_t num = size / sizeof(Friend); 555 uint16_t num = size / sizeof(Friend);
556 556
557 uint32_t i; 557 uint32_t i;
558 for (i = 0; i < num; ++i) { 558 for (i = 0; i < num; ++i) {
559 if(temp[i].status != 0) { 559 if(temp[i].status != 0) {
diff --git a/core/Messenger.h b/core/Messenger.h
index 0e2606d9..3cdeeb93 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -3,7 +3,7 @@
3 * An implementation of a simple text chat only messenger on the tox network core. 3 * An implementation of a simple text chat only messenger on the tox network core.
4 * 4 *
5 * NOTE: All the text in the messages must be encoded using UTF-8 5 * NOTE: All the text in the messages must be encoded using UTF-8
6 * 6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved. 7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 * 8 *
9 * This file is part of Tox. 9 * This file is part of Tox.
@@ -20,8 +20,8 @@
20 * 20 *
21 * You should have received a copy of the GNU General Public License 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/>. 22 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23 * 23 *
24 */ 24 */
25 25
26#ifndef MESSENGER_H 26#ifndef MESSENGER_H
27#define MESSENGER_H 27#define MESSENGER_H
@@ -42,111 +42,111 @@ extern "C" {
42#define PACKET_ID_USERSTATUS 49 42#define PACKET_ID_USERSTATUS 49
43#define PACKET_ID_MESSAGE 64 43#define PACKET_ID_MESSAGE 64
44 44
45/* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased 45 /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased
46 to an absurdly large number later */ 46 to an absurdly large number later */
47 47
48/* add a friend 48 /* add a friend
49 set the data that will be sent along with friend request 49 set the data that will be sent along with friend request
50 client_id is the client id of the friend 50 client_id is the client id of the friend
51 data is the data and length is the length 51 data is the data and length is the length
52 returns the friend number if success 52 returns the friend number if success
53 return -1 if failure. */ 53 return -1 if failure. */
54int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); 54 int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
55 55
56 56
57/* add a friend without sending a friendrequest. 57 /* add a friend without sending a friendrequest.
58 returns the friend number if success 58 returns the friend number if success
59 return -1 if failure. */ 59 return -1 if failure. */
60int m_addfriend_norequest(uint8_t *client_id); 60 int m_addfriend_norequest(uint8_t *client_id);
61 61
62/* return the friend id associated to that client id. 62 /* return the friend id associated to that client id.
63 return -1 if no such friend */ 63 return -1 if no such friend */
64int getfriend_id(uint8_t *client_id); 64 int getfriend_id(uint8_t *client_id);
65 65
66/* copies the public key associated to that friend id into client_id buffer. 66 /* copies the public key associated to that friend id into client_id buffer.
67 make sure that client_id is of size CLIENT_ID_SIZE. 67 make sure that client_id is of size CLIENT_ID_SIZE.
68 return 0 if success 68 return 0 if success
69 return -1 if failure */ 69 return -1 if failure */
70int getclient_id(int friend_id, uint8_t *client_id); 70 int getclient_id(int friend_id, uint8_t *client_id);
71 71
72/* remove a friend */ 72 /* remove a friend */
73int m_delfriend(int friendnumber); 73 int m_delfriend(int friendnumber);
74 74
75/* return 4 if friend is online 75 /* return 4 if friend is online
76 return 3 if friend is confirmed 76 return 3 if friend is confirmed
77 return 2 if the friend request was sent 77 return 2 if the friend request was sent
78 return 1 if the friend was added 78 return 1 if the friend was added
79 return 0 if there is no friend with that number */ 79 return 0 if there is no friend with that number */
80int m_friendstatus(int friendnumber); 80 int m_friendstatus(int friendnumber);
81 81
82/* send a text chat message to an online friend 82 /* send a text chat message to an online friend
83 returns 1 if packet was successfully put into the send queue 83 returns 1 if packet was successfully put into the send queue
84 return 0 if it was not */ 84 return 0 if it was not */
85int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); 85 int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
86 86
87/* Set our nickname 87 /* Set our nickname
88 name must be a string of maximum MAX_NAME_LENGTH length. 88 name must be a string of maximum MAX_NAME_LENGTH length.
89 return 0 if success 89 return 0 if success
90 return -1 if failure */ 90 return -1 if failure */
91int setname(uint8_t *name, uint16_t length); 91 int setname(uint8_t *name, uint16_t length);
92 92
93/* get name of friendnumber 93 /* get name of friendnumber
94 put it in name 94 put it in name
95 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 95 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
96 return 0 if success 96 return 0 if success
97 return -1 if failure */ 97 return -1 if failure */
98int getname(int friendnumber, uint8_t *name); 98 int getname(int friendnumber, uint8_t *name);
99 99
100/* set our user status 100 /* set our user status
101 you are responsible for freeing status after 101 you are responsible for freeing status after
102 returns 0 on success, -1 on failure */ 102 returns 0 on success, -1 on failure */
103int m_set_userstatus(uint8_t *status, uint16_t length); 103 int m_set_userstatus(uint8_t *status, uint16_t length);
104 104
105/* return the length of friendnumber's user status, 105 /* return the length of friendnumber's user status,
106 including null 106 including null
107 pass it into malloc */ 107 pass it into malloc */
108int m_get_userstatus_size(int friendnumber); 108 int m_get_userstatus_size(int friendnumber);
109 109
110/* copy friendnumber's userstatus into buf, truncating if size is over maxlen 110 /* copy friendnumber's userstatus into buf, truncating if size is over maxlen
111 get the size you need to allocate from m_get_userstatus_size */ 111 get the size you need to allocate from m_get_userstatus_size */
112int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen); 112 int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen);
113 113
114/* set the function that will be executed when a friend request is received. 114 /* set the function that will be executed when a friend request is received.
115 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 115 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
116void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 116 void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
117 117
118/* set the function that will be executed when a message from a friend is received. 118 /* set the function that will be executed when a message from a friend is received.
119 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ 119 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
120void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); 120 void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t));
121 121
122/* set the callback for name changes 122 /* set the callback for name changes
123 function(int friendnumber, uint8_t *newname, uint16_t length) 123 function(int friendnumber, uint8_t *newname, uint16_t length)
124 you are not responsible for freeing newname */ 124 you are not responsible for freeing newname */
125void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); 125 void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t));
126 126
127/* set the callback for user status changes 127 /* set the callback for user status changes
128 function(int friendnumber, uint8_t *newstatus, uint16_t length) 128 function(int friendnumber, uint8_t *newstatus, uint16_t length)
129 you are not responsible for freeing newstatus */ 129 you are not responsible for freeing newstatus */
130void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t)); 130 void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t));
131 131
132/* run this at startup 132 /* run this at startup
133 returns 0 if no connection problems 133 returns 0 if no connection problems
134 returns -1 if there are problems */ 134 returns -1 if there are problems */
135int initMessenger(); 135 int initMessenger();
136 136
137/* the main loop that needs to be run at least 200 times per second */ 137 /* the main loop that needs to be run at least 200 times per second */
138void doMessenger(); 138 void doMessenger();
139 139
140/* SAVING AND LOADING FUNCTIONS: */ 140 /* SAVING AND LOADING FUNCTIONS: */
141 141
142/* returns the size of the messenger data (for saving) */ 142 /* returns the size of the messenger data (for saving) */
143uint32_t Messenger_size(); 143 uint32_t Messenger_size();
144 144
145/* save the messenger in data (must be allocated memory of size Messenger_size()) */ 145 /* save the messenger in data (must be allocated memory of size Messenger_size()) */
146void Messenger_save(uint8_t *data); 146 void Messenger_save(uint8_t *data);
147 147
148/* load the messenger from data of size length */ 148 /* load the messenger from data of size length */
149int Messenger_load(uint8_t *data, uint32_t length); 149 int Messenger_load(uint8_t *data, uint32_t length);
150 150
151#ifdef __cplusplus 151#ifdef __cplusplus
152} 152}
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 7a2cdc24..f1ffb8d0 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -1,7 +1,7 @@
1/* friend_requests.c 1/* friend_requests.c
2 * 2 *
3 * Handle friend requests. 3 * Handle friend requests.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#include "friend_requests.h" 24#include "friend_requests.h"
@@ -26,7 +26,7 @@
26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
27 27
28/* Try to send a friendrequest to peer with public_key 28/* Try to send a friendrequest to peer with public_key
29 data is the data in the request and length is the length. 29 data is the data in the request and length is the length.
30 return -1 if failure. 30 return -1 if failure.
31 return 0 if it sent the friend request directly to the friend. 31 return 0 if it sent the friend request directly to the friend.
32 return the number of peers it was routed through if it did not send it directly.*/ 32 return the number of peers it was routed through if it did not send it directly.*/
@@ -34,7 +34,7 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
34{ 34{
35 uint8_t packet[MAX_DATA_SIZE]; 35 uint8_t packet[MAX_DATA_SIZE];
36 int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */ 36 int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */
37 37
38 if (len == -1) 38 if (len == -1)
39 return -1; 39 return -1;
40 40
@@ -48,7 +48,7 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
48 return 0; 48 return 0;
49 return -1; 49 return -1;
50 } 50 }
51 51
52 int num = route_tofriend(public_key, packet, len); 52 int num = route_tofriend(public_key, packet, len);
53 53
54 if (num == 0) 54 if (num == 0)
@@ -61,7 +61,8 @@ static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t);
61static uint8_t handle_friendrequest_isset = 0; 61static uint8_t handle_friendrequest_isset = 0;
62 62
63/* set the function that will be executed when a friend request is received. */ 63/* set the function that will be executed when a friend request is received. */
64void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) { 64void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t))
65{
65 handle_friendrequest = function; 66 handle_friendrequest = function;
66 handle_friendrequest_isset = 1; 67 handle_friendrequest_isset = 1;
67} 68}
@@ -76,17 +77,19 @@ static uint8_t recieved_requests[MAX_RECIEVED_STORED][crypto_box_PUBLICKEYBYTES]
76static uint16_t recieved_requests_index; 77static uint16_t recieved_requests_index;
77 78
78/*Add to list of recieved friend requests*/ 79/*Add to list of recieved friend requests*/
79static void addto_recievedlist(uint8_t * client_id) { 80static void addto_recievedlist(uint8_t * client_id)
81{
80 if (recieved_requests_index >= MAX_RECIEVED_STORED) 82 if (recieved_requests_index >= MAX_RECIEVED_STORED)
81 recieved_requests_index = 0; 83 recieved_requests_index = 0;
82 84
83 memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES); 85 memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES);
84 ++recieved_requests_index; 86 ++recieved_requests_index;
85} 87}
86 88
87/* Check if a friend request was already recieved 89/* Check if a friend request was already recieved
88 return 0 if not, 1 if we did */ 90 return 0 if not, 1 if we did */
89static int request_recieved(uint8_t * client_id) { 91static int request_recieved(uint8_t * client_id)
92{
90 uint32_t i; 93 uint32_t i;
91 94
92 for (i = 0; i < MAX_RECIEVED_STORED; ++i) { 95 for (i = 0; i < MAX_RECIEVED_STORED; ++i) {
@@ -98,7 +101,8 @@ static int request_recieved(uint8_t * client_id) {
98} 101}
99 102
100 103
101int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) { 104int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
105{
102 if (packet[0] == 32) { 106 if (packet[0] == 32) {
103 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 107 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
104 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 108 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
@@ -118,11 +122,10 @@ int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) {
118 122
119 addto_recievedlist(public_key); 123 addto_recievedlist(public_key);
120 (*handle_friendrequest)(public_key, data, len); 124 (*handle_friendrequest)(public_key, data, len);
121 } 125 } else { /* if request is not for us, try routing it. */
122 else {/* if request is not for us, try routing it. */
123 if(route_packet(packet + 1, packet, length) == length) 126 if(route_packet(packet + 1, packet, length) == length)
124 return 0; 127 return 0;
125 } 128 }
126 } 129 }
127 return 1; 130 return 1;
128} 131}
diff --git a/core/friend_requests.h b/core/friend_requests.h
index 8988403c..e21c2a90 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -1,7 +1,7 @@
1/* friend_requests.h 1/* friend_requests.h
2 * 2 *
3 * Handle friend requests. 3 * Handle friend requests.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,11 +18,11 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#ifndef FRIEND_REQUESTS_H 24#ifndef FRIEND_REQUESTS_H
25#define FRIEND_REQUESTS_H 25#define FRIEND_REQUESTS_H
26 26
27#include "DHT.h" 27#include "DHT.h"
28#include "net_crypto.h" 28#include "net_crypto.h"
@@ -31,18 +31,18 @@
31extern "C" { 31extern "C" {
32#endif 32#endif
33 33
34/* Try to send a friendrequest to peer with public_key 34 /* Try to send a friendrequest to peer with public_key
35 data is the data in the request and length is the length. */ 35 data is the data in the request and length is the length. */
36int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length); 36 int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length);
37 37
38/* set the function that will be executed when a friend request for us is received. 38 /* set the function that will be executed when a friend request for us is received.
39 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 39 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
40void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 40 void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
41 41
42/* if we receive a packet we call this function so it can be handled. 42 /* if we receive a packet we call this function so it can be handled.
43 return 0 if packet is handled correctly. 43 return 0 if packet is handled correctly.
44 return 1 if it didn't handle the packet or if the packet was shit. */ 44 return 1 if it didn't handle the packet or if the packet was shit. */
45int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); 45 int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
46 46
47#ifdef __cplusplus 47#ifdef __cplusplus
48} 48}
diff --git a/core/net_crypto.c b/core/net_crypto.c
index c1571467..a437c5ee 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -1,10 +1,10 @@
1/* net_crypto.c 1/* net_crypto.c
2 * 2 *
3 * Functions for the core network crypto. 3 * Functions for the core network crypto.
4 * See also: docs/Crypto.txt 4 * See also: docs/Crypto.txt
5 * 5 *
6 * NOTE: This code has to be perfect. We don't mess around with encryption. 6 * NOTE: This code has to be perfect. We don't mess around with encryption.
7 * 7 *
8 * Copyright (C) 2013 Tox project All Rights Reserved. 8 * Copyright (C) 2013 Tox project All Rights Reserved.
9 * 9 *
10 * This file is part of Tox. 10 * This file is part of Tox.
@@ -21,7 +21,7 @@
21 * 21 *
22 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
23 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 23 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
24 * 24 *
25 */ 25 */
26 26
27#include "net_crypto.h" 27#include "net_crypto.h"
@@ -37,11 +37,11 @@ typedef struct {
37 uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ 37 uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */
38 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ 38 uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */
39 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ 39 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */
40 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet 40 uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
41 (we have received a handshake but no empty data packet), 3 if the connection is established. 41 (we have received a handshake but no empty data packet), 3 if the connection is established.
42 4 if the connection is timed out. */ 42 4 if the connection is timed out. */
43 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ 43 uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */
44 44
45} Crypto_Connection; 45} Crypto_Connection;
46 46
47#define MAX_CRYPTO_CONNECTIONS 256 47#define MAX_CRYPTO_CONNECTIONS 256
@@ -53,24 +53,24 @@ static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
53/* keeps track of the connection numbers for friends request so we can check later if they were sent */ 53/* keeps track of the connection numbers for friends request so we can check later if they were sent */
54static int incoming_connections[MAX_INCOMING]; 54static int incoming_connections[MAX_INCOMING];
55 55
56/* encrypts plain of length length to encrypted of length + 16 using the 56/* encrypts plain of length length to encrypted of length + 16 using the
57 public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce 57 public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
58 return -1 if there was a problem. 58 return -1 if there was a problem.
59 return length of encrypted data if everything was fine. */ 59 return length of encrypted data if everything was fine. */
60int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 60int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
61 uint8_t *plain, uint32_t length, uint8_t *encrypted) 61 uint8_t *plain, uint32_t length, uint8_t *encrypted)
62{ 62{
63 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) 63 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0)
64 return -1; 64 return -1;
65 65
66 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; 66 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0};
67 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; 67 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES];
68 uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0}; 68 uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0};
69 69
70 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ 70 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */
71 71
72 crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); 72 crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key);
73 73
74 /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ 74 /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */
75 if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) 75 if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0)
76 return -1; 76 return -1;
@@ -84,8 +84,8 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
84 public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce 84 public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
85 return -1 if there was a problem(decryption failed) 85 return -1 if there was a problem(decryption failed)
86 return length of plain data if everything was fine. */ 86 return length of plain data if everything was fine. */
87int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 87int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
88 uint8_t *encrypted, uint32_t length, uint8_t *plain) 88 uint8_t *encrypted, uint32_t length, uint8_t *plain)
89{ 89{
90 if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) 90 if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
91 return -1; 91 return -1;
@@ -93,11 +93,11 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
93 uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; 93 uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES];
94 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; 94 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0};
95 uint8_t zeroes[crypto_box_ZEROBYTES] = {0}; 95 uint8_t zeroes[crypto_box_ZEROBYTES] = {0};
96 96
97 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ 97 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */
98 98
99 if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, 99 if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
100 nonce, public_key, secret_key) == -1) 100 nonce, public_key, secret_key) == -1)
101 return -1; 101 return -1;
102 102
103 /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */ 103 /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */
@@ -130,13 +130,13 @@ void random_nonce(uint8_t *nonce)
130 } 130 }
131} 131}
132 132
133/* return 0 if there is no received data in the buffer 133/* return 0 if there is no received data in the buffer
134 return -1 if the packet was discarded. 134 return -1 if the packet was discarded.
135 return length of received data if successful */ 135 return length of received data if successful */
136int read_cryptpacket(int crypt_connection_id, uint8_t *data) 136int read_cryptpacket(int crypt_connection_id, uint8_t *data)
137{ 137{
138 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 138 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
139 return 0; 139 return 0;
140 if (crypto_connections[crypt_connection_id].status != 3) 140 if (crypto_connections[crypt_connection_id].status != 3)
141 return 0; 141 return 0;
142 uint8_t temp_data[MAX_DATA_SIZE]; 142 uint8_t temp_data[MAX_DATA_SIZE];
@@ -145,7 +145,7 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
145 return 0; 145 return 0;
146 if (temp_data[0] != 3) 146 if (temp_data[0] != 3)
147 return -1; 147 return -1;
148 int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, 148 int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
149 crypto_connections[crypt_connection_id].sessionsecret_key, 149 crypto_connections[crypt_connection_id].sessionsecret_key,
150 crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); 150 crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data);
151 if (len != -1) { 151 if (len != -1) {
@@ -160,13 +160,13 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
160int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) 160int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
161{ 161{
162 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 162 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
163 return 0; 163 return 0;
164 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) 164 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
165 return 0; 165 return 0;
166 if (crypto_connections[crypt_connection_id].status != 3) 166 if (crypto_connections[crypt_connection_id].status != 3)
167 return 0; 167 return 0;
168 uint8_t temp_data[MAX_DATA_SIZE]; 168 uint8_t temp_data[MAX_DATA_SIZE];
169 int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, 169 int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
170 crypto_connections[crypt_connection_id].sessionsecret_key, 170 crypto_connections[crypt_connection_id].sessionsecret_key,
171 crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); 171 crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1);
172 if (len == -1) 172 if (len == -1)
@@ -190,7 +190,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
190 return -1; 190 return -1;
191 uint8_t nonce[crypto_box_NONCEBYTES]; 191 uint8_t nonce[crypto_box_NONCEBYTES];
192 random_nonce(nonce); 192 random_nonce(nonce);
193 int len = encrypt_data(public_key, self_secret_key, nonce, data, length, 193 int len = encrypt_data(public_key, self_secret_key, nonce, data, length,
194 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 194 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
195 if (len == -1) 195 if (len == -1)
196 return -1; 196 return -1;
@@ -198,11 +198,11 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
198 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 198 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
199 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); 199 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES);
200 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); 200 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
201 201
202 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; 202 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
203} 203}
204 204
205/* puts the senders public key in the request in public_key, the data from the request 205/* puts the senders public key in the request in public_key, the data from the request
206 in data if a friend or ping request was sent to us and returns the length of the data. 206 in data if a friend or ping request was sent to us and returns the length of the data.
207 packet is the request packet and length is its length 207 packet is the request packet and length is its length
208 return -1 if not valid request. */ 208 return -1 if not valid request. */
@@ -210,19 +210,17 @@ int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t
210{ 210{
211 211
212 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 212 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
213 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && 213 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
214 memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 214 memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
215 {
216 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); 215 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
217 uint8_t nonce[crypto_box_NONCEBYTES]; 216 uint8_t nonce[crypto_box_NONCEBYTES];
218 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); 217 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
219 int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, 218 int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
220 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); 219 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data);
221 if(len1 == -1) 220 if(len1 == -1)
222 return -1; 221 return -1;
223 return len1; 222 return len1;
224 } 223 } else
225 else
226 return -1; 224 return -1;
227} 225}
228 226
@@ -234,13 +232,13 @@ int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret
234 uint8_t temp_data[MAX_DATA_SIZE]; 232 uint8_t temp_data[MAX_DATA_SIZE];
235 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 233 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
236 uint8_t nonce[crypto_box_NONCEBYTES]; 234 uint8_t nonce[crypto_box_NONCEBYTES];
237 235
238 random_nonce(nonce); 236 random_nonce(nonce);
239 memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); 237 memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
240 memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); 238 memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);
241 239
242 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 240 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
243 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 241 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
244 if (len == -1) 242 if (len == -1)
245 return 0; 243 return 0;
246 temp_data[0] = 2; 244 temp_data[0] = 2;
@@ -252,28 +250,27 @@ int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret
252/* Extract secret nonce, session public key and public_key from a packet(data) with length length 250/* Extract secret nonce, session public key and public_key from a packet(data) with length length
253 return 1 if successful 251 return 1 if successful
254 return 0 if failure */ 252 return 0 if failure */
255int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, 253int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
256 uint8_t *session_key, uint8_t *data, uint16_t length) 254 uint8_t *session_key, uint8_t *data, uint16_t length)
257{ 255{
258 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); 256 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
259 if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES 257 if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
260 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) 258 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) {
261 {
262 return 0; 259 return 0;
263 } 260 }
264 if (data[0] != 2) 261 if (data[0] != 2)
265 return 0; 262 return 0;
266 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 263 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
267 264
268 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); 265 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
269 266
270 int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, 267 int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES,
271 data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, 268 data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
272 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); 269 crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp);
273 270
274 if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) 271 if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES)
275 return 0; 272 return 0;
276 273
277 memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); 274 memcpy(secret_nonce, temp, crypto_box_NONCEBYTES);
278 memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); 275 memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
279 return 1; 276 return 1;
@@ -316,9 +313,8 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
316 memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); 313 memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
317 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); 314 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
318 315
319 if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, 316 if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce,
320 crypto_connections[i].sessionpublic_key) == 1) 317 crypto_connections[i].sessionpublic_key) == 1) {
321 {
322 increment_nonce(crypto_connections[i].recv_nonce); 318 increment_nonce(crypto_connections[i].recv_nonce);
323 return i; 319 return i;
324 } 320 }
@@ -363,9 +359,9 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
363 return 0 if killed successfully 359 return 0 if killed successfully
364 return 1 if there was a problem. */ 360 return 1 if there was a problem. */
365int crypto_kill(int crypt_connection_id) 361int crypto_kill(int crypt_connection_id)
366{ 362{
367 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 363 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
368 return 1; 364 return 1;
369 if (crypto_connections[crypt_connection_id].status != 0) { 365 if (crypto_connections[crypt_connection_id].status != 0) {
370 crypto_connections[crypt_connection_id].status = 0; 366 crypto_connections[crypt_connection_id].status = 0;
371 kill_connection(crypto_connections[crypt_connection_id].number); 367 kill_connection(crypto_connections[crypt_connection_id].number);
@@ -400,9 +396,8 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
400 396
401 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); 397 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
402 398
403 if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, 399 if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce,
404 crypto_connections[i].sessionpublic_key) == 1) 400 crypto_connections[i].sessionpublic_key) == 1) {
405 {
406 increment_nonce(crypto_connections[i].recv_nonce); 401 increment_nonce(crypto_connections[i].recv_nonce);
407 uint32_t zero = 0; 402 uint32_t zero = 0;
408 crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ 403 crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */
@@ -413,10 +408,10 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
413 return -1; /* this should never happen. */ 408 return -1; /* this should never happen. */
414 } 409 }
415 } 410 }
416 return -1; 411 return -1;
417} 412}
418 413
419/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet 414/* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet
420 (we have received a handshake but no empty data packet), 3 if the connection is established. 415 (we have received a handshake but no empty data packet), 3 if the connection is established.
421 4 if the connection is timed out and waiting to be killed */ 416 4 if the connection is timed out and waiting to be killed */
422int is_cryptoconnected(int crypt_connection_id) 417int is_cryptoconnected(int crypt_connection_id)
@@ -471,9 +466,9 @@ static void handle_incomings()
471{ 466{
472 int income; 467 int income;
473 while (1) { 468 while (1) {
474 income = incoming_connection(); 469 income = incoming_connection();
475 if(income == -1 || new_incoming(income) ) 470 if(income == -1 || new_incoming(income) )
476 break; 471 break;
477 } 472 }
478} 473}
479 474
@@ -488,8 +483,8 @@ static void receive_crypto()
488 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 483 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
489 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 484 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
490 uint16_t len; 485 uint16_t len;
491 if (id_packet(crypto_connections[i].number) == 1) 486 if (id_packet(crypto_connections[i].number) == 1)
492 /* if the packet is a friend request drop it (because we are already friends) */ 487 /* if the packet is a friend request drop it (because we are already friends) */
493 len = read_packet(crypto_connections[i].number, temp_data); 488 len = read_packet(crypto_connections[i].number, temp_data);
494 if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ 489 if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
495 len = read_packet(crypto_connections[i].number, temp_data); 490 len = read_packet(crypto_connections[i].number, temp_data);
@@ -504,31 +499,28 @@ static void receive_crypto()
504 crypto_connections[i].status = 2; /* set it to its proper value right after. */ 499 crypto_connections[i].status = 2; /* set it to its proper value right after. */
505 } 500 }
506 } 501 }
507 } 502 } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
508 else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
509 crypto_kill(crypto_connections[i].number); 503 crypto_kill(crypto_connections[i].number);
510 504
511 } 505 }
512 if (crypto_connections[i].status == 2) { 506 if (crypto_connections[i].status == 2) {
513 if (id_packet(crypto_connections[i].number) == 3) { 507 if (id_packet(crypto_connections[i].number) == 3) {
514 uint8_t temp_data[MAX_DATA_SIZE]; 508 uint8_t temp_data[MAX_DATA_SIZE];
515 uint8_t data[MAX_DATA_SIZE]; 509 uint8_t data[MAX_DATA_SIZE];
516 int length = read_packet(crypto_connections[i].number, temp_data); 510 int length = read_packet(crypto_connections[i].number, temp_data);
517 int len = decrypt_data(crypto_connections[i].peersessionpublic_key, 511 int len = decrypt_data(crypto_connections[i].peersessionpublic_key,
518 crypto_connections[i].sessionsecret_key, 512 crypto_connections[i].sessionsecret_key,
519 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); 513 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
520 uint32_t zero = 0; 514 uint32_t zero = 0;
521 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { 515 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
522 increment_nonce(crypto_connections[i].recv_nonce); 516 increment_nonce(crypto_connections[i].recv_nonce);
523 crypto_connections[i].status = 3; 517 crypto_connections[i].status = 3;
524 518
525 /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ 519 /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */
526 kill_connection_in(crypto_connections[i].number, 3000000); 520 kill_connection_in(crypto_connections[i].number, 3000000);
527 } 521 } else
528 else
529 crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does 522 crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does
530 } 523 } else if(id_packet(crypto_connections[i].number) != -1)
531 else if(id_packet(crypto_connections[i].number) != -1)
532 /* This should not happen 524 /* This should not happen
533 kill the connection if it does */ 525 kill the connection if it does */
534 crypto_kill(crypto_connections[i].number); 526 crypto_kill(crypto_connections[i].number);
diff --git a/core/net_crypto.h b/core/net_crypto.h
index d4fe1313..0eb2ad6d 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -1,5 +1,5 @@
1/* net_crypto.h 1/* net_crypto.h
2 * 2 *
3 * Functions for the core network crypto. 3 * Functions for the core network crypto.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -18,11 +18,11 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
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 "Lossless_UDP.h"
28 28
@@ -30,102 +30,102 @@
30extern "C" { 30extern "C" {
31#endif 31#endif
32 32
33/* Our public key. */ 33 /* Our public key. */
34extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 34 extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
35extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 35 extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
36 36
37#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 37#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
38 38
39/* encrypts plain of length length to encrypted of length + 16 using the 39 /* encrypts plain of length length to encrypted of length + 16 using the
40 public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce 40 public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
41 return -1 if there was a problem. 41 return -1 if there was a problem.
42 return length of encrypted data if everything was fine. */ 42 return length of encrypted data if everything was fine. */
43int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 43 int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
44 uint8_t *plain, uint32_t length, uint8_t *encrypted); 44 uint8_t *plain, uint32_t length, uint8_t *encrypted);
45 45
46 46
47/* decrypts encrypted of length length to plain of length length - 16 using the 47 /* decrypts encrypted of length length to plain of length length - 16 using the
48 public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce 48 public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
49 return -1 if there was a problem(decryption failed) 49 return -1 if there was a problem(decryption failed)
50 return length of plain data if everything was fine. */ 50 return length of plain data if everything was fine. */
51int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 51 int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
52 uint8_t *encrypted, uint32_t length, uint8_t *plain); 52 uint8_t *encrypted, uint32_t length, uint8_t *plain);
53 53
54 54
55/* fill the given nonce with random bytes. */ 55 /* fill the given nonce with random bytes. */
56void random_nonce(uint8_t *nonce); 56 void random_nonce(uint8_t *nonce);
57 57
58/* return 0 if there is no received data in the buffer 58 /* return 0 if there is no received data in the buffer
59 return -1 if the packet was discarded. 59 return -1 if the packet was discarded.
60 return length of received data if successful */ 60 return length of received data if successful */
61int read_cryptpacket(int crypt_connection_id, uint8_t *data); 61 int read_cryptpacket(int crypt_connection_id, uint8_t *data);
62 62
63/* return 0 if data could not be put in packet queue 63 /* return 0 if data could not be put in packet queue
64 return 1 if data was put into the queue */ 64 return 1 if data was put into the queue */
65int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); 65 int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length);
66 66
67/* create a request to peer with public_key. 67 /* create a request to peer with public_key.
68 packet must be an array of MAX_DATA_SIZE big. 68 packet must be an array of MAX_DATA_SIZE big.
69 Data represents the data we send with the request with length being the length of the data. 69 Data represents the data we send with the request with length being the length of the data.
70 request_id is the id of the request (32 = friend request, 254 = ping request) 70 request_id is the id of the request (32 = friend request, 254 = ping request)
71 returns -1 on failure 71 returns -1 on failure
72 returns the length of the created packet on success */ 72 returns the length of the created packet on success */
73int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); 73 int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id);
74 74
75/* puts the senders public key in the request in public_key, the data from the request 75 /* puts the senders public key in the request in public_key, the data from the request
76 in data if a friend or ping request was sent to us and returns the length of the data. 76 in data if a friend or ping request was sent to us and returns the length of the data.
77 packet is the request packet and length is its length 77 packet is the request packet and length is its length
78 return -1 if not valid request. */ 78 return -1 if not valid request. */
79int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length); 79 int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length);
80 80
81/* Start a secure connection with other peer who has public_key and ip_port 81 /* Start a secure connection with other peer who has public_key and ip_port
82 returns -1 if failure 82 returns -1 if failure
83 returns crypt_connection_id of the initialized connection if everything went well. */ 83 returns crypt_connection_id of the initialized connection if everything went well. */
84int crypto_connect(uint8_t *public_key, IP_Port ip_port); 84 int crypto_connect(uint8_t *public_key, IP_Port ip_port);
85 85
86/* kill a crypto connection 86 /* kill a crypto connection
87 return 0 if killed successfully 87 return 0 if killed successfully
88 return 1 if there was a problem. */ 88 return 1 if there was a problem. */
89int crypto_kill(int crypt_connection_id); 89 int crypto_kill(int crypt_connection_id);
90 90
91/* handle an incoming connection 91 /* handle an incoming connection
92 return -1 if no crypto inbound connection 92 return -1 if no crypto inbound connection
93 return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection 93 return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection
94 Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce 94 Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce
95 and the session public key for the connection in session_key 95 and the session public key for the connection in session_key
96 to accept it see: accept_crypto_inbound(...) 96 to accept it see: accept_crypto_inbound(...)
97 to refuse it just call kill_connection(...) on the connection id */ 97 to refuse it just call kill_connection(...) on the connection id */
98int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); 98 int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
99 99
100/* accept an incoming connection using the parameters provided by crypto_inbound 100 /* accept an incoming connection using the parameters provided by crypto_inbound
101 return -1 if not successful 101 return -1 if not successful
102 returns the crypt_connection_id if successful */ 102 returns the crypt_connection_id if successful */
103int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); 103 int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key);
104 104
105/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet 105 /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
106 (we have received a handshake but no empty data packet), 3 if the connection is established. 106 (we have received a handshake but no empty data packet), 3 if the connection is established.
107 4 if the connection is timed out and waiting to be killed */ 107 4 if the connection is timed out and waiting to be killed */
108int is_cryptoconnected(int crypt_connection_id); 108 int is_cryptoconnected(int crypt_connection_id);
109 109
110 110
111/* Generate our public and private keys 111 /* Generate our public and private keys
112 Only call this function the first time the program starts. */ 112 Only call this function the first time the program starts. */
113void new_keys(); 113 void new_keys();
114 114
115/* save the public and private keys to the keys array 115 /* save the public and private keys to the keys array
116 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 116 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
117void save_keys(uint8_t * keys); 117 void save_keys(uint8_t * keys);
118 118
119/* load the public and private keys from the keys array 119 /* load the public and private keys from the keys array
120 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 120 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
121void load_keys(uint8_t * keys); 121 void load_keys(uint8_t * keys);
122 122
123/* run this to (re)initialize net_crypto 123 /* run this to (re)initialize net_crypto
124 sets all the global connection variables to their default values. */ 124 sets all the global connection variables to their default values. */
125void initNetCrypto(); 125 void initNetCrypto();
126 126
127/* main loop */ 127 /* main loop */
128void doNetCrypto(); 128 void doNetCrypto();
129 129
130#ifdef __cplusplus 130#ifdef __cplusplus
131} 131}
diff --git a/core/network.c b/core/network.c
index 8804ab4e..aa16bda9 100644
--- a/core/network.c
+++ b/core/network.c
@@ -1,7 +1,7 @@
1/* network.h 1/* network.h
2 * 2 *
3 * Functions for the core networking. 3 * Functions for the core networking.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 * 6 *
7 * This file is part of Tox. 7 * This file is part of Tox.
@@ -18,7 +18,7 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#include "network.h" 24#include "network.h"
@@ -27,7 +27,7 @@
27uint64_t current_time() 27uint64_t current_time()
28{ 28{
29 uint64_t time; 29 uint64_t time;
30 #ifdef WIN32 30#ifdef WIN32
31 /* This probably works fine */ 31 /* This probably works fine */
32 FILETIME ft; 32 FILETIME ft;
33 GetSystemTimeAsFileTime(&ft); 33 GetSystemTimeAsFileTime(&ft);
@@ -36,24 +36,24 @@ uint64_t current_time()
36 time |= ft.dwLowDateTime; 36 time |= ft.dwLowDateTime;
37 time -= 116444736000000000UL; 37 time -= 116444736000000000UL;
38 return time/10; 38 return time/10;
39 #else 39#else
40 struct timeval a; 40 struct timeval a;
41 gettimeofday(&a, NULL); 41 gettimeofday(&a, NULL);
42 time = 1000000UL*a.tv_sec + a.tv_usec; 42 time = 1000000UL*a.tv_sec + a.tv_usec;
43 return time; 43 return time;
44 #endif 44#endif
45} 45}
46 46
47/* return a random number 47/* return a random number
48 NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ 48 NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */
49uint32_t random_int() 49uint32_t random_int()
50{ 50{
51 #ifndef VANILLA_NACL 51#ifndef VANILLA_NACL
52 //NOTE: this function comes from libsodium 52 //NOTE: this function comes from libsodium
53 return randombytes_random(); 53 return randombytes_random();
54 #else 54#else
55 return random(); 55 return random();
56 #endif 56#endif
57} 57}
58 58
59/* our UDP socket, a global variable. */ 59/* our UDP socket, a global variable. */
@@ -63,7 +63,7 @@ static int sock;
63 Function to send packet(data) of length length to ip_port */ 63 Function to send packet(data) of length length to ip_port */
64int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) 64int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length)
65{ 65{
66 ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; 66 ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
67 return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); 67 return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
68} 68}
69 69
@@ -74,15 +74,15 @@ int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length)
74int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) 74int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
75{ 75{
76 ADDR addr; 76 ADDR addr;
77 #ifdef WIN32 77#ifdef WIN32
78 int addrlen = sizeof(addr); 78 int addrlen = sizeof(addr);
79 #else 79#else
80 uint32_t addrlen = sizeof(addr); 80 uint32_t addrlen = sizeof(addr);
81 #endif 81#endif
82 (*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen); 82 (*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen);
83 if (*(int32_t*)length <= 0) 83 if (*(int32_t*)length <= 0)
84 return -1; /* nothing received or empty packet */ 84 return -1; /* nothing received or empty packet */
85 85
86 ip_port->ip = addr.ip; 86 ip_port->ip = addr.ip;
87 ip_port->port = addr.port; 87 ip_port->port = addr.port;
88 return 0; 88 return 0;
@@ -92,30 +92,30 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
92 bind to ip and port 92 bind to ip and port
93 ip must be in network order EX: 127.0.0.1 = (7F000001) 93 ip must be in network order EX: 127.0.0.1 = (7F000001)
94 port is in host byte order (this means don't worry about it) 94 port is in host byte order (this means don't worry about it)
95 returns 0 if no problems 95 returns 0 if no problems
96 returns -1 if there are problems */ 96 returns -1 if there are problems */
97int init_networking(IP ip, uint16_t port) 97int init_networking(IP ip, uint16_t port)
98{ 98{
99 #ifdef WIN32 99#ifdef WIN32
100 WSADATA wsaData; 100 WSADATA wsaData;
101 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) 101 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
102 return -1; 102 return -1;
103 #else 103#else
104 srandom((uint32_t)current_time()); 104 srandom((uint32_t)current_time());
105 #endif 105#endif
106 srand((uint32_t)current_time()); 106 srand((uint32_t)current_time());
107 107
108 /* initialize our socket */ 108 /* initialize our socket */
109 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 109 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
110 110
111 /* Check for socket error */ 111 /* Check for socket error */
112 #ifdef WIN32 112#ifdef WIN32
113 if (sock == INVALID_SOCKET) /* MSDN recommends this */ 113 if (sock == INVALID_SOCKET) /* MSDN recommends this */
114 return -1; 114 return -1;
115 #else 115#else
116 if (sock < 0) 116 if (sock < 0)
117 return -1; 117 return -1;
118 #endif 118#endif
119 119
120 /* Functions to increase the size of the send and receive UDP buffers 120 /* Functions to increase the size of the send and receive UDP buffers
121 NOTE: uncomment if necessary */ 121 NOTE: uncomment if necessary */
@@ -129,23 +129,23 @@ int init_networking(IP ip, uint16_t port)
129 if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1) 129 if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1)
130 return -1; 130 return -1;
131 */ 131 */
132 132
133 /* Enable broadcast on socket */ 133 /* Enable broadcast on socket */
134 int broadcast = 1; 134 int broadcast = 1;
135 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)); 135 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast));
136 136
137 /* Set socket nonblocking */ 137 /* Set socket nonblocking */
138 #ifdef WIN32 138#ifdef WIN32
139 /* I think this works for windows */ 139 /* I think this works for windows */
140 u_long mode = 1; 140 u_long mode = 1;
141 /* ioctl(sock, FIONBIO, &mode); */ 141 /* ioctl(sock, FIONBIO, &mode); */
142 ioctlsocket(sock, FIONBIO, &mode); 142 ioctlsocket(sock, FIONBIO, &mode);
143 #else 143#else
144 fcntl(sock, F_SETFL, O_NONBLOCK, 1); 144 fcntl(sock, F_SETFL, O_NONBLOCK, 1);
145 #endif 145#endif
146 146
147 /* Bind our socket to port PORT and address 0.0.0.0 */ 147 /* Bind our socket to port PORT and address 0.0.0.0 */
148 ADDR addr = {AF_INET, htons(port), ip}; 148 ADDR addr = {AF_INET, htons(port), ip};
149 bind(sock, (struct sockaddr*)&addr, sizeof(addr)); 149 bind(sock, (struct sockaddr*)&addr, sizeof(addr));
150 150
151 return 0; 151 return 0;
@@ -155,12 +155,12 @@ int init_networking(IP ip, uint16_t port)
155/* function to cleanup networking stuff */ 155/* function to cleanup networking stuff */
156void shutdown_networking() 156void shutdown_networking()
157{ 157{
158 #ifdef WIN32 158#ifdef WIN32
159 closesocket(sock); 159 closesocket(sock);
160 WSACleanup(); 160 WSACleanup();
161 #else 161#else
162 close(sock); 162 close(sock);
163 #endif 163#endif
164 return; 164 return;
165} 165}
166 166
diff --git a/core/network.h b/core/network.h
index a59d7c38..c8b8e355 100644
--- a/core/network.h
+++ b/core/network.h
@@ -1,5 +1,5 @@
1/* network.h 1/* network.h
2 * 2 *
3 * Datatypes, functions and includes for the core networking. 3 * Datatypes, functions and includes for the core networking.
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -18,11 +18,11 @@
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23 23
24#ifndef NETWORK_H 24#ifndef NETWORK_H
25#define NETWORK_H 25#define NETWORK_H
26 26
27#include <stdlib.h> 27#include <stdlib.h>
28#include <stdio.h> 28#include <stdio.h>
@@ -46,7 +46,7 @@
46#include <netinet/in.h> 46#include <netinet/in.h>
47#include <errno.h> 47#include <errno.h>
48#include <sys/time.h> 48#include <sys/time.h>
49#include <sys/types.h> 49#include <sys/types.h>
50#include <netdb.h> 50#include <netdb.h>
51#include <unistd.h> 51#include <unistd.h>
52 52
@@ -69,63 +69,63 @@ extern "C" {
69 69
70#define MAX_UDP_PACKET_SIZE 65507 70#define MAX_UDP_PACKET_SIZE 65507
71 71
72typedef union { 72 typedef union {
73 uint8_t c[4]; 73 uint8_t c[4];
74 uint16_t s[2]; 74 uint16_t s[2];
75 uint32_t i; 75 uint32_t i;
76} IP; 76 } IP;
77 77
78typedef struct { 78 typedef struct {
79 IP ip; 79 IP ip;
80 uint16_t port; 80 uint16_t port;
81 /* not used for anything right now */ 81 /* not used for anything right now */
82 uint16_t padding; 82 uint16_t padding;
83} IP_Port; 83 } IP_Port;
84 84
85typedef struct { 85 typedef struct {
86 int16_t family; 86 int16_t family;
87 uint16_t port; 87 uint16_t port;
88 IP ip; 88 IP ip;
89 uint8_t zeroes[8]; 89 uint8_t zeroes[8];
90 #ifdef ENABLE_IPV6 90#ifdef ENABLE_IPV6
91 uint8_t zeroes2[12]; 91 uint8_t zeroes2[12];
92 #endif 92#endif
93} ADDR; 93 } ADDR;
94 94
95/* returns current time in milleseconds since the epoch. */ 95 /* returns current time in milleseconds since the epoch. */
96uint64_t current_time(); 96 uint64_t current_time();
97 97
98/* return a random number 98 /* return a random number
99 NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ 99 NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */
100uint32_t random_int(); 100 uint32_t random_int();
101 101
102/* Basic network functions: */ 102 /* Basic network functions: */
103 103
104/* Function to send packet(data) of length length to ip_port */ 104 /* Function to send packet(data) of length length to ip_port */
105int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); 105 int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length);
106 106
107/* Function to receive data, ip and port of sender is put into ip_port 107 /* Function to receive data, ip and port of sender is put into ip_port
108 the packet data into data 108 the packet data into data
109 the packet length into length. */ 109 the packet length into length. */
110int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length); 110 int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length);
111 111
112/* initialize networking 112 /* initialize networking
113 bind to ip and port 113 bind to ip and port
114 ip must be in network order EX: 127.0.0.1 = (7F000001) 114 ip must be in network order EX: 127.0.0.1 = (7F000001)
115 port is in host byte order (this means don't worry about it) 115 port is in host byte order (this means don't worry about it)
116 returns 0 if no problems 116 returns 0 if no problems
117 returns -1 if there were problems */ 117 returns -1 if there were problems */
118int init_networking(IP ip, uint16_t port); 118 int init_networking(IP ip, uint16_t port);
119 119
120/* function to cleanup networking stuff(doesn't do much right now) */ 120 /* function to cleanup networking stuff(doesn't do much right now) */
121void shutdown_networking(); 121 void shutdown_networking();
122 122
123/* resolves provided address to a binary data in network byte order 123 /* resolves provided address to a binary data in network byte order
124 address is ASCII null terminated string 124 address is ASCII null terminated string
125 address should represent IPv4, IPv6 or a hostname 125 address should represent IPv4, IPv6 or a hostname
126 on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i 126 on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i
127 on failure returns -1 */ 127 on failure returns -1 */
128int resolve_addr(char *address); 128 int resolve_addr(char *address);
129 129
130#ifdef __cplusplus 130#ifdef __cplusplus
131} 131}