diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 498 | ||||
-rw-r--r-- | core/DHT.h | 93 | ||||
-rw-r--r-- | core/LAN_discovery.c | 13 | ||||
-rw-r--r-- | core/LAN_discovery.h | 4 | ||||
-rw-r--r-- | core/Messenger.c | 56 | ||||
-rw-r--r-- | core/Messenger.h | 2 | ||||
-rw-r--r-- | core/friend_requests.c | 77 | ||||
-rw-r--r-- | core/friend_requests.h | 25 | ||||
-rw-r--r-- | core/net_crypto.c | 33 | ||||
-rw-r--r-- | core/net_crypto.h | 36 | ||||
-rw-r--r-- | core/network.c | 1 | ||||
-rw-r--r-- | core/network.h | 1 | ||||
-rw-r--r-- | core/ping.c | 31 |
13 files changed, 452 insertions, 418 deletions
@@ -27,17 +27,6 @@ | |||
27 | #include "packets.h" | 27 | #include "packets.h" |
28 | #include "ping.h" | 28 | #include "ping.h" |
29 | 29 | ||
30 | /* maximum number of clients stored per friend. */ | ||
31 | #define MAX_FRIEND_CLIENTS 8 | ||
32 | |||
33 | /* A list of the clients mathematically closest to ours. */ | ||
34 | #define LCLIENT_LIST 32 | ||
35 | |||
36 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | ||
37 | #define LPING_ARRAY 256 | ||
38 | |||
39 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | ||
40 | |||
41 | /* the number of seconds for a non responsive node to become bad. */ | 30 | /* the number of seconds for a non responsive node to become bad. */ |
42 | #define BAD_NODE_TIMEOUT 70 | 31 | #define BAD_NODE_TIMEOUT 70 |
43 | 32 | ||
@@ -61,59 +50,13 @@ | |||
61 | /*Interval in seconds between punching attempts*/ | 50 | /*Interval in seconds between punching attempts*/ |
62 | #define PUNCH_INTERVAL 10 | 51 | #define PUNCH_INTERVAL 10 |
63 | 52 | ||
64 | /*Maximum newly announced nodes to ping per TIME_TOPING seconds*/ | 53 | /*Ping newly announced nodes to ping per TIME_TOPING seconds*/ |
65 | #define MAX_TOPING 16 | ||
66 | |||
67 | #define TIME_TOPING 5 | 54 | #define TIME_TOPING 5 |
68 | /*----------------------------------------------------------------------------------*/ | ||
69 | |||
70 | typedef struct { | ||
71 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
72 | Client_data client_list[MAX_FRIEND_CLIENTS]; | ||
73 | |||
74 | /* time at which the last get_nodes request was sent. */ | ||
75 | uint64_t lastgetnode; | ||
76 | |||
77 | /* Symetric NAT hole punching stuff */ | ||
78 | |||
79 | /* 1 if currently hole punching, otherwise 0 */ | ||
80 | uint8_t hole_punching; | ||
81 | uint32_t punching_index; | ||
82 | uint64_t punching_timestamp; | ||
83 | uint64_t recvNATping_timestamp; | ||
84 | uint64_t NATping_id; | ||
85 | uint64_t NATping_timestamp; | ||
86 | } Friend; | ||
87 | |||
88 | typedef struct { | ||
89 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
90 | IP_Port ip_port; | ||
91 | } Node_format; | ||
92 | 55 | ||
93 | typedef struct { | ||
94 | IP_Port ip_port; | ||
95 | uint64_t ping_id; | ||
96 | uint64_t timestamp; | ||
97 | } Pinged; | ||
98 | 56 | ||
99 | /*----------------------------------------------------------------------------------*/ | 57 | Client_data *DHT_get_close_list(DHT * dht) |
100 | |||
101 | /* Our client id/public key */ | ||
102 | uint8_t self_public_key[CLIENT_ID_SIZE]; | ||
103 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
104 | static Client_data close_clientlist[LCLIENT_LIST]; | ||
105 | static Friend *friends_list; | ||
106 | static uint16_t num_friends; | ||
107 | static Pinged send_nodes[LSEND_NODES_ARRAY]; | ||
108 | static Node_format toping[MAX_TOPING]; | ||
109 | static uint64_t last_toping; | ||
110 | |||
111 | /*----------------------------------------------------------------------------------*/ | ||
112 | |||
113 | |||
114 | Client_data *DHT_get_close_list(void) | ||
115 | { | 58 | { |
116 | return close_clientlist; | 59 | return dht->close_clientlist; |
117 | } | 60 | } |
118 | 61 | ||
119 | /* Compares client_id1 and client_id2 with client_id | 62 | /* Compares client_id1 and client_id2 with client_id |
@@ -203,12 +146,12 @@ static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *clien | |||
203 | 146 | ||
204 | /* Returns the friend number from the client_id, or -1 if a failure occurs | 147 | /* Returns the friend number from the client_id, or -1 if a failure occurs |
205 | */ | 148 | */ |
206 | static int friend_number(uint8_t *client_id) | 149 | static int friend_number(DHT * dht, uint8_t *client_id) |
207 | { | 150 | { |
208 | uint32_t i; | 151 | uint32_t i; |
209 | 152 | ||
210 | for (i = 0; i < num_friends; ++i) { | 153 | for (i = 0; i < dht->num_friends; ++i) { |
211 | if (id_equal(friends_list[i].client_id, client_id)) | 154 | if (id_equal(dht->friends_list[i].client_id, client_id)) |
212 | return i; | 155 | return i; |
213 | } | 156 | } |
214 | 157 | ||
@@ -220,15 +163,15 @@ static int friend_number(uint8_t *client_id) | |||
220 | * | 163 | * |
221 | * TODO: For the love of based Allah make this function cleaner and much more efficient. | 164 | * TODO: For the love of based Allah make this function cleaner and much more efficient. |
222 | */ | 165 | */ |
223 | static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | 166 | static int get_close_nodes(DHT * dht, uint8_t *client_id, Node_format *nodes_list) |
224 | { | 167 | { |
225 | uint32_t i, j, k; | 168 | uint32_t i, j, k; |
226 | uint64_t temp_time = unix_time(); | 169 | uint64_t temp_time = unix_time(); |
227 | int num_nodes = 0, closest, tout, inlist; | 170 | int num_nodes = 0, closest, tout, inlist; |
228 | 171 | ||
229 | for (i = 0; i < LCLIENT_LIST; ++i) { | 172 | for (i = 0; i < LCLIENT_LIST; ++i) { |
230 | tout = is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); | 173 | tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); |
231 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); | 174 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); |
232 | 175 | ||
233 | /* if node isn't good or is already in list. */ | 176 | /* if node isn't good or is already in list. */ |
234 | if (tout || inlist) | 177 | if (tout || inlist) |
@@ -237,10 +180,10 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
237 | if (num_nodes < MAX_SENT_NODES) { | 180 | if (num_nodes < MAX_SENT_NODES) { |
238 | 181 | ||
239 | memcpy( nodes_list[num_nodes].client_id, | 182 | memcpy( nodes_list[num_nodes].client_id, |
240 | close_clientlist[i].client_id, | 183 | dht->close_clientlist[i].client_id, |
241 | CLIENT_ID_SIZE ); | 184 | CLIENT_ID_SIZE ); |
242 | 185 | ||
243 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; | 186 | nodes_list[num_nodes].ip_port = dht->close_clientlist[i].ip_port; |
244 | num_nodes++; | 187 | num_nodes++; |
245 | 188 | ||
246 | } else { | 189 | } else { |
@@ -248,27 +191,27 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
248 | for (j = 0; j < MAX_SENT_NODES; ++j) { | 191 | for (j = 0; j < MAX_SENT_NODES; ++j) { |
249 | closest = id_closest( client_id, | 192 | closest = id_closest( client_id, |
250 | nodes_list[j].client_id, | 193 | nodes_list[j].client_id, |
251 | close_clientlist[i].client_id ); | 194 | dht->close_clientlist[i].client_id ); |
252 | 195 | ||
253 | if (closest == 2) { | 196 | if (closest == 2) { |
254 | memcpy( nodes_list[j].client_id, | 197 | memcpy( nodes_list[j].client_id, |
255 | close_clientlist[i].client_id, | 198 | dht->close_clientlist[i].client_id, |
256 | CLIENT_ID_SIZE); | 199 | CLIENT_ID_SIZE); |
257 | 200 | ||
258 | nodes_list[j].ip_port = close_clientlist[i].ip_port; | 201 | nodes_list[j].ip_port = dht->close_clientlist[i].ip_port; |
259 | break; | 202 | break; |
260 | } | 203 | } |
261 | } | 204 | } |
262 | } | 205 | } |
263 | } | 206 | } |
264 | 207 | ||
265 | for (i = 0; i < num_friends; ++i) { | 208 | for (i = 0; i < dht->num_friends; ++i) { |
266 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 209 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
267 | 210 | ||
268 | tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); | 211 | tout = is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); |
269 | inlist = client_in_nodelist( nodes_list, | 212 | inlist = client_in_nodelist( nodes_list, |
270 | MAX_SENT_NODES, | 213 | MAX_SENT_NODES, |
271 | friends_list[i].client_list[j].client_id); | 214 | dht->friends_list[i].client_list[j].client_id); |
272 | 215 | ||
273 | /* if node isn't good or is already in list. */ | 216 | /* if node isn't good or is already in list. */ |
274 | if (tout || inlist) | 217 | if (tout || inlist) |
@@ -277,24 +220,24 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
277 | if (num_nodes < MAX_SENT_NODES) { | 220 | if (num_nodes < MAX_SENT_NODES) { |
278 | 221 | ||
279 | memcpy( nodes_list[num_nodes].client_id, | 222 | memcpy( nodes_list[num_nodes].client_id, |
280 | friends_list[i].client_list[j].client_id, | 223 | dht->friends_list[i].client_list[j].client_id, |
281 | CLIENT_ID_SIZE); | 224 | CLIENT_ID_SIZE); |
282 | 225 | ||
283 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; | 226 | nodes_list[num_nodes].ip_port = dht->friends_list[i].client_list[j].ip_port; |
284 | num_nodes++; | 227 | num_nodes++; |
285 | } else { | 228 | } else { |
286 | for (k = 0; k < MAX_SENT_NODES; ++k) { | 229 | for (k = 0; k < MAX_SENT_NODES; ++k) { |
287 | 230 | ||
288 | closest = id_closest( client_id, | 231 | closest = id_closest( client_id, |
289 | nodes_list[k].client_id, | 232 | nodes_list[k].client_id, |
290 | friends_list[i].client_list[j].client_id ); | 233 | dht->friends_list[i].client_list[j].client_id ); |
291 | 234 | ||
292 | if (closest == 2) { | 235 | if (closest == 2) { |
293 | memcpy( nodes_list[k].client_id, | 236 | memcpy( nodes_list[k].client_id, |
294 | friends_list[i].client_list[j].client_id, | 237 | dht->friends_list[i].client_list[j].client_id, |
295 | CLIENT_ID_SIZE ); | 238 | CLIENT_ID_SIZE ); |
296 | 239 | ||
297 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; | 240 | nodes_list[k].ip_port = dht->friends_list[i].client_list[j].ip_port; |
298 | break; | 241 | break; |
299 | } | 242 | } |
300 | } | 243 | } |
@@ -387,40 +330,40 @@ static int replace_good( Client_data *list, | |||
387 | /* Attempt to add client with ip_port and client_id to the friends client list | 330 | /* Attempt to add client with ip_port and client_id to the friends client list |
388 | * and close_clientlist | 331 | * and close_clientlist |
389 | */ | 332 | */ |
390 | void addto_lists(IP_Port ip_port, uint8_t *client_id) | 333 | void addto_lists(DHT * dht, IP_Port ip_port, uint8_t *client_id) |
391 | { | 334 | { |
392 | uint32_t i; | 335 | uint32_t i; |
393 | 336 | ||
394 | /* NOTE: current behavior if there are two clients with the same id is | 337 | /* NOTE: current behavior if there are two clients with the same id is |
395 | * to replace the first ip by the second. | 338 | * to replace the first ip by the second. |
396 | */ | 339 | */ |
397 | if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 340 | if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
398 | if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 341 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
399 | /* if we can't replace bad nodes we try replacing good ones */ | 342 | /* if we can't replace bad nodes we try replacing good ones */ |
400 | replace_good( close_clientlist, | 343 | replace_good( dht->close_clientlist, |
401 | LCLIENT_LIST, | 344 | LCLIENT_LIST, |
402 | client_id, | 345 | client_id, |
403 | ip_port, | 346 | ip_port, |
404 | self_public_key ); | 347 | dht->c->self_public_key ); |
405 | } | 348 | } |
406 | } | 349 | } |
407 | 350 | ||
408 | for (i = 0; i < num_friends; ++i) { | 351 | for (i = 0; i < dht->num_friends; ++i) { |
409 | if (!client_in_list( friends_list[i].client_list, | 352 | if (!client_in_list( dht->friends_list[i].client_list, |
410 | MAX_FRIEND_CLIENTS, | 353 | MAX_FRIEND_CLIENTS, |
411 | client_id, | 354 | client_id, |
412 | ip_port )) { | 355 | ip_port )) { |
413 | 356 | ||
414 | if (replace_bad( friends_list[i].client_list, | 357 | if (replace_bad( dht->friends_list[i].client_list, |
415 | MAX_FRIEND_CLIENTS, | 358 | MAX_FRIEND_CLIENTS, |
416 | client_id, | 359 | client_id, |
417 | ip_port )) { | 360 | ip_port )) { |
418 | /* if we can't replace bad nodes we try replacing good ones. */ | 361 | /* if we can't replace bad nodes we try replacing good ones. */ |
419 | replace_good( friends_list[i].client_list, | 362 | replace_good( dht->friends_list[i].client_list, |
420 | MAX_FRIEND_CLIENTS, | 363 | MAX_FRIEND_CLIENTS, |
421 | client_id, | 364 | client_id, |
422 | ip_port, | 365 | ip_port, |
423 | friends_list[i].client_id ); | 366 | dht->friends_list[i].client_id ); |
424 | } | 367 | } |
425 | } | 368 | } |
426 | } | 369 | } |
@@ -429,30 +372,30 @@ void addto_lists(IP_Port ip_port, uint8_t *client_id) | |||
429 | /* If client_id is a friend or us, update ret_ip_port | 372 | /* If client_id is a friend or us, update ret_ip_port |
430 | * nodeclient_id is the id of the node that sent us this info | 373 | * nodeclient_id is the id of the node that sent us this info |
431 | */ | 374 | */ |
432 | static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) | 375 | static void returnedip_ports(DHT * dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) |
433 | { | 376 | { |
434 | uint32_t i, j; | 377 | uint32_t i, j; |
435 | uint64_t temp_time = unix_time(); | 378 | uint64_t temp_time = unix_time(); |
436 | 379 | ||
437 | if (id_equal(client_id, self_public_key)) { | 380 | if (id_equal(client_id, dht->c->self_public_key)) { |
438 | 381 | ||
439 | for (i = 0; i < LCLIENT_LIST; ++i) { | 382 | for (i = 0; i < LCLIENT_LIST; ++i) { |
440 | if (id_equal(nodeclient_id, close_clientlist[i].client_id)) { | 383 | if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { |
441 | close_clientlist[i].ret_ip_port = ip_port; | 384 | dht->close_clientlist[i].ret_ip_port = ip_port; |
442 | close_clientlist[i].ret_timestamp = temp_time; | 385 | dht->close_clientlist[i].ret_timestamp = temp_time; |
443 | return; | 386 | return; |
444 | } | 387 | } |
445 | } | 388 | } |
446 | 389 | ||
447 | } else { | 390 | } else { |
448 | 391 | ||
449 | for (i = 0; i < num_friends; ++i) { | 392 | for (i = 0; i < dht->num_friends; ++i) { |
450 | if (id_equal(client_id, friends_list[i].client_id)) { | 393 | if (id_equal(client_id, dht->friends_list[i].client_id)) { |
451 | 394 | ||
452 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 395 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
453 | if (id_equal(nodeclient_id, friends_list[i].client_list[j].client_id)) { | 396 | if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) { |
454 | friends_list[i].client_list[j].ret_ip_port = ip_port; | 397 | dht->friends_list[i].client_list[j].ret_ip_port = ip_port; |
455 | friends_list[i].client_list[j].ret_timestamp = temp_time; | 398 | dht->friends_list[i].client_list[j].ret_timestamp = temp_time; |
456 | return; | 399 | return; |
457 | } | 400 | } |
458 | } | 401 | } |
@@ -463,20 +406,20 @@ static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodec | |||
463 | } | 406 | } |
464 | 407 | ||
465 | /* Same as last function but for get_node requests. */ | 408 | /* Same as last function but for get_node requests. */ |
466 | static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | 409 | static int is_gettingnodes(DHT * dht, IP_Port ip_port, uint64_t ping_id) |
467 | { | 410 | { |
468 | uint32_t i; | 411 | uint32_t i; |
469 | uint8_t pinging; | 412 | uint8_t pinging; |
470 | uint64_t temp_time = unix_time(); | 413 | uint64_t temp_time = unix_time(); |
471 | 414 | ||
472 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { | 415 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { |
473 | if (!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) { | 416 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { |
474 | pinging = 0; | 417 | pinging = 0; |
475 | 418 | ||
476 | if (ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port)) | 419 | if (ip_port.ip.i != 0 && ipport_equal(dht->send_nodes[i].ip_port, ip_port)) |
477 | ++pinging; | 420 | ++pinging; |
478 | 421 | ||
479 | if (ping_id != 0 && send_nodes[i].ping_id == ping_id) | 422 | if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) |
480 | ++pinging; | 423 | ++pinging; |
481 | 424 | ||
482 | if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 425 | if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
@@ -488,7 +431,7 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
488 | } | 431 | } |
489 | 432 | ||
490 | /* Same but for get node requests */ | 433 | /* Same but for get node requests */ |
491 | static uint64_t add_gettingnodes(IP_Port ip_port) | 434 | static uint64_t add_gettingnodes(DHT * dht, IP_Port ip_port) |
492 | { | 435 | { |
493 | uint32_t i, j; | 436 | uint32_t i, j; |
494 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 437 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
@@ -496,10 +439,10 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
496 | 439 | ||
497 | for (i = 0; i < PING_TIMEOUT; ++i ) { | 440 | for (i = 0; i < PING_TIMEOUT; ++i ) { |
498 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { | 441 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { |
499 | if (is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) { | 442 | if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { |
500 | send_nodes[j].timestamp = temp_time; | 443 | dht->send_nodes[j].timestamp = temp_time; |
501 | send_nodes[j].ip_port = ip_port; | 444 | dht->send_nodes[j].ip_port = ip_port; |
502 | send_nodes[j].ping_id = ping_id; | 445 | dht->send_nodes[j].ping_id = ping_id; |
503 | return ping_id; | 446 | return ping_id; |
504 | } | 447 | } |
505 | } | 448 | } |
@@ -509,13 +452,13 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
509 | } | 452 | } |
510 | 453 | ||
511 | /* send a getnodes request */ | 454 | /* send a getnodes request */ |
512 | static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | 455 | static int getnodes(DHT * dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) |
513 | { | 456 | { |
514 | /* check if packet is gonna be sent to ourself */ | 457 | /* check if packet is gonna be sent to ourself */ |
515 | if (id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0)) | 458 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) |
516 | return 1; | 459 | return 1; |
517 | 460 | ||
518 | uint64_t ping_id = add_gettingnodes(ip_port); | 461 | uint64_t ping_id = add_gettingnodes(dht, ip_port); |
519 | 462 | ||
520 | if (ping_id == 0) | 463 | if (ping_id == 0) |
521 | return 1; | 464 | return 1; |
@@ -530,7 +473,7 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
530 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); | 473 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
531 | 474 | ||
532 | int len = encrypt_data( public_key, | 475 | int len = encrypt_data( public_key, |
533 | self_secret_key, | 476 | dht->c->self_secret_key, |
534 | nonce, | 477 | nonce, |
535 | plain, | 478 | plain, |
536 | sizeof(ping_id) + CLIENT_ID_SIZE, | 479 | sizeof(ping_id) + CLIENT_ID_SIZE, |
@@ -540,25 +483,25 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
540 | return -1; | 483 | return -1; |
541 | 484 | ||
542 | data[0] = 2; | 485 | data[0] = 2; |
543 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 486 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); |
544 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 487 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
545 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 488 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
546 | 489 | ||
547 | return sendpacket(temp_net->sock, ip_port, data, sizeof(data)); | 490 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); |
548 | } | 491 | } |
549 | 492 | ||
550 | /* send a send nodes response */ | 493 | /* send a send nodes response */ |
551 | static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) | 494 | static int sendnodes(DHT * dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) |
552 | { | 495 | { |
553 | /* check if packet is gonna be sent to ourself */ | 496 | /* check if packet is gonna be sent to ourself */ |
554 | if (id_equal(public_key, self_public_key)) | 497 | if (id_equal(public_key, dht->c->self_public_key)) |
555 | return 1; | 498 | return 1; |
556 | 499 | ||
557 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 500 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
558 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 501 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
559 | 502 | ||
560 | Node_format nodes_list[MAX_SENT_NODES]; | 503 | Node_format nodes_list[MAX_SENT_NODES]; |
561 | int num_nodes = get_close_nodes(client_id, nodes_list); | 504 | int num_nodes = get_close_nodes(dht, client_id, nodes_list); |
562 | 505 | ||
563 | if (num_nodes == 0) | 506 | if (num_nodes == 0) |
564 | return 0; | 507 | return 0; |
@@ -572,7 +515,7 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
572 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); | 515 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); |
573 | 516 | ||
574 | int len = encrypt_data( public_key, | 517 | int len = encrypt_data( public_key, |
575 | self_secret_key, | 518 | dht->c->self_secret_key, |
576 | nonce, | 519 | nonce, |
577 | plain, | 520 | plain, |
578 | sizeof(ping_id) + num_nodes * sizeof(Node_format), | 521 | sizeof(ping_id) + num_nodes * sizeof(Node_format), |
@@ -582,15 +525,16 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
582 | return -1; | 525 | return -1; |
583 | 526 | ||
584 | data[0] = 3; | 527 | data[0] = 3; |
585 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 528 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); |
586 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 529 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
587 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 530 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
588 | 531 | ||
589 | return sendpacket(temp_net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 532 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
590 | } | 533 | } |
591 | 534 | ||
592 | static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 535 | static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
593 | { | 536 | { |
537 | DHT * dht = object; | ||
594 | uint64_t ping_id; | 538 | uint64_t ping_id; |
595 | 539 | ||
596 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | 540 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
@@ -598,13 +542,13 @@ static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint3 | |||
598 | return 1; | 542 | return 1; |
599 | 543 | ||
600 | /* check if packet is from ourself. */ | 544 | /* check if packet is from ourself. */ |
601 | if (id_equal(packet + 1, self_public_key)) | 545 | if (id_equal(packet + 1, dht->c->self_public_key)) |
602 | return 1; | 546 | return 1; |
603 | 547 | ||
604 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 548 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
605 | 549 | ||
606 | int len = decrypt_data( packet + 1, | 550 | int len = decrypt_data( packet + 1, |
607 | self_secret_key, | 551 | dht->c->self_secret_key, |
608 | packet + 1 + CLIENT_ID_SIZE, | 552 | packet + 1 + CLIENT_ID_SIZE, |
609 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 553 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
610 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, | 554 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, |
@@ -614,15 +558,16 @@ static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint3 | |||
614 | return 1; | 558 | return 1; |
615 | 559 | ||
616 | memcpy(&ping_id, plain, sizeof(ping_id)); | 560 | memcpy(&ping_id, plain, sizeof(ping_id)); |
617 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | 561 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); |
618 | 562 | ||
619 | //send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ | 563 | //send_ping_request(dht, source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ |
620 | 564 | ||
621 | return 0; | 565 | return 0; |
622 | } | 566 | } |
623 | 567 | ||
624 | static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 568 | static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
625 | { | 569 | { |
570 | DHT * dht = object; | ||
626 | uint64_t ping_id; | 571 | uint64_t ping_id; |
627 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 572 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
628 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; | 573 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; |
@@ -637,7 +582,7 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint | |||
637 | 582 | ||
638 | int len = decrypt_data( | 583 | int len = decrypt_data( |
639 | packet + 1, | 584 | packet + 1, |
640 | self_secret_key, | 585 | dht->c->self_secret_key, |
641 | packet + 1 + CLIENT_ID_SIZE, | 586 | packet + 1 + CLIENT_ID_SIZE, |
642 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 587 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
643 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); | 588 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); |
@@ -647,19 +592,19 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint | |||
647 | 592 | ||
648 | memcpy(&ping_id, plain, sizeof(ping_id)); | 593 | memcpy(&ping_id, plain, sizeof(ping_id)); |
649 | 594 | ||
650 | if (!is_gettingnodes(source, ping_id)) | 595 | if (!is_gettingnodes(dht, source, ping_id)) |
651 | return 1; | 596 | return 1; |
652 | 597 | ||
653 | Node_format nodes_list[MAX_SENT_NODES]; | 598 | Node_format nodes_list[MAX_SENT_NODES]; |
654 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | 599 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
655 | 600 | ||
656 | addto_lists(source, packet + 1); | 601 | addto_lists(dht, source, packet + 1); |
657 | 602 | ||
658 | uint32_t i; | 603 | uint32_t i; |
659 | 604 | ||
660 | for (i = 0; i < num_nodes; ++i) { | 605 | for (i = 0; i < num_nodes; ++i) { |
661 | send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); | 606 | send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); |
662 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 607 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
663 | } | 608 | } |
664 | 609 | ||
665 | return 0; | 610 | return 0; |
@@ -668,54 +613,54 @@ static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint | |||
668 | /*----------------------------------------------------------------------------------*/ | 613 | /*----------------------------------------------------------------------------------*/ |
669 | /*------------------------END of packet handling functions--------------------------*/ | 614 | /*------------------------END of packet handling functions--------------------------*/ |
670 | 615 | ||
671 | int DHT_addfriend(uint8_t *client_id) | 616 | int DHT_addfriend(DHT * dht, uint8_t *client_id) |
672 | { | 617 | { |
673 | if (friend_number(client_id) != -1) /*Is friend already in DHT?*/ | 618 | if (friend_number(dht, client_id) != -1) /*Is friend already in DHT?*/ |
674 | return 1; | 619 | return 1; |
675 | 620 | ||
676 | Friend *temp; | 621 | DHT_Friend *temp; |
677 | temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); | 622 | temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); |
678 | 623 | ||
679 | if (temp == NULL) | 624 | if (temp == NULL) |
680 | return 1; | 625 | return 1; |
681 | 626 | ||
682 | friends_list = temp; | 627 | dht->friends_list = temp; |
683 | memset(&friends_list[num_friends], 0, sizeof(Friend)); | 628 | memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend)); |
684 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); | 629 | memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE); |
685 | 630 | ||
686 | friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); | 631 | dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); |
687 | ++num_friends; | 632 | ++dht->num_friends; |
688 | return 0; | 633 | return 0; |
689 | } | 634 | } |
690 | 635 | ||
691 | int DHT_delfriend(uint8_t *client_id) | 636 | int DHT_delfriend(DHT * dht, uint8_t *client_id) |
692 | { | 637 | { |
693 | uint32_t i; | 638 | uint32_t i; |
694 | Friend *temp; | 639 | DHT_Friend *temp; |
695 | 640 | ||
696 | for (i = 0; i < num_friends; ++i) { | 641 | for (i = 0; i < dht->num_friends; ++i) { |
697 | /* Equal */ | 642 | /* Equal */ |
698 | if (id_equal(friends_list[i].client_id, client_id)) { | 643 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
699 | --num_friends; | 644 | --dht->num_friends; |
700 | 645 | ||
701 | if (num_friends != i) { | 646 | if (dht->num_friends != i) { |
702 | memcpy( friends_list[i].client_id, | 647 | memcpy( dht->friends_list[i].client_id, |
703 | friends_list[num_friends].client_id, | 648 | dht->friends_list[dht->num_friends].client_id, |
704 | CLIENT_ID_SIZE ); | 649 | CLIENT_ID_SIZE ); |
705 | } | 650 | } |
706 | 651 | ||
707 | if (num_friends == 0) { | 652 | if (dht->num_friends == 0) { |
708 | free(friends_list); | 653 | free(dht->friends_list); |
709 | friends_list = NULL; | 654 | dht->friends_list = NULL; |
710 | return 0; | 655 | return 0; |
711 | } | 656 | } |
712 | 657 | ||
713 | temp = realloc(friends_list, sizeof(Friend) * (num_friends)); | 658 | temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends)); |
714 | 659 | ||
715 | if (temp == NULL) | 660 | if (temp == NULL) |
716 | return 1; | 661 | return 1; |
717 | 662 | ||
718 | friends_list = temp; | 663 | dht->friends_list = temp; |
719 | return 0; | 664 | return 0; |
720 | } | 665 | } |
721 | } | 666 | } |
@@ -724,19 +669,19 @@ int DHT_delfriend(uint8_t *client_id) | |||
724 | } | 669 | } |
725 | 670 | ||
726 | /* TODO: Optimize this. */ | 671 | /* TODO: Optimize this. */ |
727 | IP_Port DHT_getfriendip(uint8_t *client_id) | 672 | IP_Port DHT_getfriendip(DHT * dht, uint8_t *client_id) |
728 | { | 673 | { |
729 | uint32_t i, j; | 674 | uint32_t i, j; |
730 | uint64_t temp_time = unix_time(); | 675 | uint64_t temp_time = unix_time(); |
731 | IP_Port empty = {{{0}}, 0}; | 676 | IP_Port empty = {{{0}}, 0}; |
732 | 677 | ||
733 | for (i = 0; i < num_friends; ++i) { | 678 | for (i = 0; i < dht->num_friends; ++i) { |
734 | /* Equal */ | 679 | /* Equal */ |
735 | if (id_equal(friends_list[i].client_id, client_id)) { | 680 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
736 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 681 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
737 | if (id_equal(friends_list[i].client_list[j].client_id, client_id) | 682 | if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) |
738 | && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) | 683 | && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) |
739 | return friends_list[i].client_list[j].ip_port; | 684 | return dht->friends_list[i].client_list[j].ip_port; |
740 | } | 685 | } |
741 | 686 | ||
742 | return empty; | 687 | return empty; |
@@ -750,49 +695,47 @@ IP_Port DHT_getfriendip(uint8_t *client_id) | |||
750 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request | 695 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request |
751 | * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. | 696 | * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. |
752 | */ | 697 | */ |
753 | static void doDHTFriends(void) | 698 | static void do_DHT_friends(DHT * dht) |
754 | { | 699 | { |
755 | uint32_t i, j; | 700 | uint32_t i, j; |
756 | uint64_t temp_time = unix_time(); | 701 | uint64_t temp_time = unix_time(); |
757 | uint32_t rand_node; | 702 | uint32_t rand_node; |
758 | uint32_t index[MAX_FRIEND_CLIENTS]; | 703 | uint32_t index[MAX_FRIEND_CLIENTS]; |
759 | 704 | ||
760 | for (i = 0; i < num_friends; ++i) { | 705 | for (i = 0; i < dht->num_friends; ++i) { |
761 | uint32_t num_nodes = 0; | 706 | uint32_t num_nodes = 0; |
762 | 707 | ||
763 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 708 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
764 | /* if node is not dead. */ | 709 | /* if node is not dead. */ |
765 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { | 710 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { |
766 | if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 711 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
767 | send_ping_request( friends_list[i].client_list[j].ip_port, | 712 | send_ping_request( dht->friends_list[i].client_list[j].ip_port, |
768 | (clientid_t *) &friends_list[i].client_list[j].client_id ); | 713 | (clientid_t *) &dht->friends_list[i].client_list[j].client_id ); |
769 | friends_list[i].client_list[j].last_pinged = temp_time; | 714 | dht->friends_list[i].client_list[j].last_pinged = temp_time; |
770 | } | 715 | } |
771 | 716 | ||
772 | /* if node is good. */ | 717 | /* if node is good. */ |
773 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { | 718 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { |
774 | index[num_nodes] = j; | 719 | index[num_nodes] = j; |
775 | ++num_nodes; | 720 | ++num_nodes; |
776 | } | 721 | } |
777 | } | 722 | } |
778 | } | 723 | } |
779 | 724 | ||
780 | if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 725 | if (dht->friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
781 | rand_node = rand() % num_nodes; | 726 | rand_node = rand() % num_nodes; |
782 | getnodes( friends_list[i].client_list[index[rand_node]].ip_port, | 727 | getnodes(dht, dht->friends_list[i].client_list[index[rand_node]].ip_port, |
783 | friends_list[i].client_list[index[rand_node]].client_id, | 728 | dht->friends_list[i].client_list[index[rand_node]].client_id, |
784 | friends_list[i].client_id ); | 729 | dht->friends_list[i].client_id ); |
785 | friends_list[i].lastgetnode = temp_time; | 730 | dht->friends_list[i].lastgetnode = temp_time; |
786 | } | 731 | } |
787 | } | 732 | } |
788 | } | 733 | } |
789 | 734 | ||
790 | static uint64_t close_lastgetnodes; | ||
791 | |||
792 | /* Ping each client in the close nodes list every PING_INTERVAL seconds. | 735 | /* Ping each client in the close nodes list every PING_INTERVAL seconds. |
793 | * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. | 736 | * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. |
794 | */ | 737 | */ |
795 | static void doClose(void) | 738 | static void do_Close(DHT * dht) |
796 | { | 739 | { |
797 | uint32_t i; | 740 | uint32_t i; |
798 | uint64_t temp_time = unix_time(); | 741 | uint64_t temp_time = unix_time(); |
@@ -802,46 +745,47 @@ static void doClose(void) | |||
802 | 745 | ||
803 | for (i = 0; i < LCLIENT_LIST; ++i) { | 746 | for (i = 0; i < LCLIENT_LIST; ++i) { |
804 | /* if node is not dead. */ | 747 | /* if node is not dead. */ |
805 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { | 748 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { |
806 | if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 749 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
807 | send_ping_request( close_clientlist[i].ip_port, | 750 | send_ping_request( dht->close_clientlist[i].ip_port, |
808 | (clientid_t *) &close_clientlist[i].client_id ); | 751 | (clientid_t *) &dht->close_clientlist[i].client_id ); |
809 | close_clientlist[i].last_pinged = temp_time; | 752 | dht->close_clientlist[i].last_pinged = temp_time; |
810 | } | 753 | } |
811 | 754 | ||
812 | /* if node is good. */ | 755 | /* if node is good. */ |
813 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { | 756 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { |
814 | index[num_nodes] = i; | 757 | index[num_nodes] = i; |
815 | ++num_nodes; | 758 | ++num_nodes; |
816 | } | 759 | } |
817 | } | 760 | } |
818 | } | 761 | } |
819 | 762 | ||
820 | if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 763 | if (dht->close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
821 | rand_node = rand() % num_nodes; | 764 | rand_node = rand() % num_nodes; |
822 | getnodes( close_clientlist[index[rand_node]].ip_port, | 765 | getnodes(dht, dht->close_clientlist[index[rand_node]].ip_port, |
823 | close_clientlist[index[rand_node]].client_id, | 766 | dht->close_clientlist[index[rand_node]].client_id, |
824 | self_public_key ); | 767 | dht->c->self_public_key ); |
825 | close_lastgetnodes = temp_time; | 768 | dht->close_lastgetnodes = temp_time; |
826 | } | 769 | } |
827 | } | 770 | } |
828 | 771 | ||
829 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key) | 772 | void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key) |
830 | { | 773 | { |
831 | getnodes(ip_port, public_key, self_public_key); | 774 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); |
775 | //send_ping_request(dht, ip_port, (clientid_t *) public_key); | ||
832 | send_ping_request(ip_port, (clientid_t *) public_key); | 776 | send_ping_request(ip_port, (clientid_t *) public_key); |
833 | } | 777 | } |
834 | 778 | ||
835 | /* send the given packet to node with client_id | 779 | /* send the given packet to node with client_id |
836 | * returns -1 if failure | 780 | * returns -1 if failure |
837 | */ | 781 | */ |
838 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | 782 | int route_packet(DHT * dht, uint8_t *client_id, uint8_t *packet, uint32_t length) |
839 | { | 783 | { |
840 | uint32_t i; | 784 | uint32_t i; |
841 | 785 | ||
842 | for (i = 0; i < LCLIENT_LIST; ++i) { | 786 | for (i = 0; i < LCLIENT_LIST; ++i) { |
843 | if (id_equal(client_id, close_clientlist[i].client_id)) | 787 | if (id_equal(client_id, dht->close_clientlist[i].client_id)) |
844 | return sendpacket(temp_net->sock, close_clientlist[i].ip_port, packet, length); | 788 | return sendpacket(dht->c->lossless_udp->net->sock, dht->close_clientlist[i].ip_port, packet, length); |
845 | } | 789 | } |
846 | 790 | ||
847 | return -1; | 791 | return -1; |
@@ -853,16 +797,16 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | |||
853 | * return 0 if we are connected to friend or if no ips were found. | 797 | * return 0 if we are connected to friend or if no ips were found. |
854 | * returns -1 if no such friend | 798 | * returns -1 if no such friend |
855 | */ | 799 | */ |
856 | static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | 800 | static int friend_iplist(DHT * dht, IP_Port *ip_portlist, uint16_t friend_num) |
857 | { | 801 | { |
858 | int num_ips = 0; | 802 | int num_ips = 0; |
859 | uint32_t i; | 803 | uint32_t i; |
860 | uint64_t temp_time = unix_time(); | 804 | uint64_t temp_time = unix_time(); |
861 | 805 | ||
862 | if (friend_num >= num_friends) | 806 | if (friend_num >= dht->num_friends) |
863 | return -1; | 807 | return -1; |
864 | 808 | ||
865 | Friend *friend = &friends_list[friend_num]; | 809 | DHT_Friend *friend = &dht->friends_list[friend_num]; |
866 | Client_data *client; | 810 | Client_data *client; |
867 | 811 | ||
868 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 812 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
@@ -888,9 +832,9 @@ static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | |||
888 | * | 832 | * |
889 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. | 833 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. |
890 | */ | 834 | */ |
891 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | 835 | int route_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
892 | { | 836 | { |
893 | int num = friend_number(friend_id); | 837 | int num = friend_number(dht, friend_id); |
894 | 838 | ||
895 | if (num == -1) | 839 | if (num == -1) |
896 | return 0; | 840 | return 0; |
@@ -898,13 +842,13 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
898 | uint32_t i, sent = 0; | 842 | uint32_t i, sent = 0; |
899 | 843 | ||
900 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 844 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
901 | int ip_num = friend_iplist(ip_list, num); | 845 | int ip_num = friend_iplist(dht, ip_list, num); |
902 | 846 | ||
903 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) | 847 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) |
904 | return 0; | 848 | return 0; |
905 | 849 | ||
906 | uint64_t temp_time = unix_time(); | 850 | uint64_t temp_time = unix_time(); |
907 | Friend *friend = &friends_list[num]; | 851 | DHT_Friend *friend = &dht->friends_list[num]; |
908 | Client_data *client; | 852 | Client_data *client; |
909 | 853 | ||
910 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 854 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
@@ -912,7 +856,7 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
912 | 856 | ||
913 | /*If ip is not zero and node is good */ | 857 | /*If ip is not zero and node is good */ |
914 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 858 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
915 | if (sendpacket(temp_net->sock, client->ip_port, packet, length) == length) | 859 | if (sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length) == length) |
916 | ++sent; | 860 | ++sent; |
917 | } | 861 | } |
918 | } | 862 | } |
@@ -923,14 +867,14 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
923 | /* Send the following packet to one random person who tells us they are connected to friend_id | 867 | /* Send the following packet to one random person who tells us they are connected to friend_id |
924 | * returns the number of nodes it sent the packet to | 868 | * returns the number of nodes it sent the packet to |
925 | */ | 869 | */ |
926 | static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | 870 | static int routeone_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
927 | { | 871 | { |
928 | int num = friend_number(friend_id); | 872 | int num = friend_number(dht, friend_id); |
929 | 873 | ||
930 | if (num == -1) | 874 | if (num == -1) |
931 | return 0; | 875 | return 0; |
932 | 876 | ||
933 | Friend *friend = &friends_list[num]; | 877 | DHT_Friend *friend = &dht->friends_list[num]; |
934 | Client_data *client; | 878 | Client_data *client; |
935 | 879 | ||
936 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 880 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
@@ -951,7 +895,7 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
951 | if (n < 1) | 895 | if (n < 1) |
952 | return 0; | 896 | return 0; |
953 | 897 | ||
954 | if (sendpacket(temp_net->sock, ip_list[rand() % n], packet, length) == length) | 898 | if (sendpacket(dht->c->lossless_udp->net->sock, ip_list[rand() % n], packet, length) == length) |
955 | return 1; | 899 | return 1; |
956 | 900 | ||
957 | return 0; | 901 | return 0; |
@@ -963,14 +907,14 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
963 | * return 0 if we are connected to friend or if no ips were found. | 907 | * return 0 if we are connected to friend or if no ips were found. |
964 | * returns -1 if no such friend | 908 | * returns -1 if no such friend |
965 | */ | 909 | */ |
966 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) | 910 | int friend_ips(DHT * dht, IP_Port *ip_portlist, uint8_t *friend_id) |
967 | { | 911 | { |
968 | uint32_t i; | 912 | uint32_t i; |
969 | 913 | ||
970 | for (i = 0; i < num_friends; ++i) { | 914 | for (i = 0; i < dht->num_friends; ++i) { |
971 | /* Equal */ | 915 | /* Equal */ |
972 | if (id_equal(friends_list[i].client_id, friend_id)) | 916 | if (id_equal(dht->friends_list[i].client_id, friend_id)) |
973 | return friend_iplist(ip_portlist, i); | 917 | return friend_iplist(dht, ip_portlist, i); |
974 | } | 918 | } |
975 | 919 | ||
976 | return -1; | 920 | return -1; |
@@ -979,7 +923,7 @@ int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) | |||
979 | /*----------------------------------------------------------------------------------*/ | 923 | /*----------------------------------------------------------------------------------*/ |
980 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ | 924 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ |
981 | 925 | ||
982 | static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | 926 | static int send_NATping(DHT * dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) |
983 | { | 927 | { |
984 | uint8_t data[sizeof(uint64_t) + 1]; | 928 | uint8_t data[sizeof(uint64_t) + 1]; |
985 | uint8_t packet[MAX_DATA_SIZE]; | 929 | uint8_t packet[MAX_DATA_SIZE]; |
@@ -989,15 +933,15 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
989 | data[0] = type; | 933 | data[0] = type; |
990 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); | 934 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); |
991 | /* 254 is NAT ping request packet id */ | 935 | /* 254 is NAT ping request packet id */ |
992 | int len = create_request(self_public_key, self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254); | 936 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254); |
993 | 937 | ||
994 | if (len == -1) | 938 | if (len == -1) |
995 | return -1; | 939 | return -1; |
996 | 940 | ||
997 | if (type == 0) /*If packet is request use many people to route it*/ | 941 | if (type == 0) /*If packet is request use many people to route it*/ |
998 | num = route_tofriend(public_key, packet, len); | 942 | num = route_tofriend(dht, public_key, packet, len); |
999 | else if (type == 1) /*If packet is response use only one person to route it*/ | 943 | else if (type == 1) /*If packet is response use only one person to route it*/ |
1000 | num = routeone_tofriend(public_key, packet, len); | 944 | num = routeone_tofriend(dht, public_key, packet, len); |
1001 | 945 | ||
1002 | if (num == 0) | 946 | if (num == 0) |
1003 | return -1; | 947 | return -1; |
@@ -1006,21 +950,22 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
1006 | } | 950 | } |
1007 | 951 | ||
1008 | /* Handle a received ping request for */ | 952 | /* Handle a received ping request for */ |
1009 | static int handle_NATping(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 953 | static int handle_NATping(void * object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) |
1010 | { | 954 | { |
955 | DHT * dht = object; | ||
1011 | uint64_t ping_id; | 956 | uint64_t ping_id; |
1012 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); | 957 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); |
1013 | 958 | ||
1014 | int friendnumber = friend_number(source_pubkey); | 959 | int friendnumber = friend_number(dht, source_pubkey); |
1015 | 960 | ||
1016 | if (friendnumber == -1) | 961 | if (friendnumber == -1) |
1017 | return 1; | 962 | return 1; |
1018 | 963 | ||
1019 | Friend *friend = &friends_list[friendnumber]; | 964 | DHT_Friend *friend = &dht->friends_list[friendnumber]; |
1020 | 965 | ||
1021 | if (packet[0] == 0) { | 966 | if (packet[0] == 0) { |
1022 | /* 1 is reply */ | 967 | /* 1 is reply */ |
1023 | send_NATping(source_pubkey, ping_id, 1); | 968 | send_NATping(dht, source_pubkey, ping_id, 1); |
1024 | friend->recvNATping_timestamp = unix_time(); | 969 | friend->recvNATping_timestamp = unix_time(); |
1025 | return 0; | 970 | return 0; |
1026 | } else if (packet[0] == 1) { | 971 | } else if (packet[0] == 1) { |
@@ -1082,45 +1027,46 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t | |||
1082 | return num; | 1027 | return num; |
1083 | } | 1028 | } |
1084 | 1029 | ||
1085 | static void punch_holes(IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) | 1030 | static void punch_holes(DHT * dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) |
1086 | { | 1031 | { |
1087 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) | 1032 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) |
1088 | return; | 1033 | return; |
1089 | 1034 | ||
1090 | uint32_t i; | 1035 | uint32_t i; |
1091 | uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; | 1036 | uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; |
1092 | 1037 | ||
1093 | for (i = friends_list[friend_num].punching_index; i != top; i++) { | 1038 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { |
1094 | /*TODO: improve port guessing algorithm*/ | 1039 | /*TODO: improve port guessing algorithm*/ |
1095 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); | 1040 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); |
1096 | IP_Port pinging = {ip, htons(port)}; | 1041 | IP_Port pinging = {ip, htons(port)}; |
1097 | send_ping_request(pinging, (clientid_t *) &friends_list[friend_num].client_id); | 1042 | //send_ping_request(dht, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); |
1043 | send_ping_request(pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); | ||
1098 | } | 1044 | } |
1099 | 1045 | ||
1100 | friends_list[friend_num].punching_index = i; | 1046 | dht->friends_list[friend_num].punching_index = i; |
1101 | } | 1047 | } |
1102 | 1048 | ||
1103 | static void doNAT(void) | 1049 | static void do_NAT(DHT * dht) |
1104 | { | 1050 | { |
1105 | uint32_t i; | 1051 | uint32_t i; |
1106 | uint64_t temp_time = unix_time(); | 1052 | uint64_t temp_time = unix_time(); |
1107 | 1053 | ||
1108 | for (i = 0; i < num_friends; ++i) { | 1054 | for (i = 0; i < dht->num_friends; ++i) { |
1109 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 1055 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
1110 | int num = friend_iplist(ip_list, i); | 1056 | int num = friend_iplist(dht, ip_list, i); |
1111 | 1057 | ||
1112 | /*If already connected or friend is not online don't try to hole punch*/ | 1058 | /*If already connected or friend is not online don't try to hole punch*/ |
1113 | if (num < MAX_FRIEND_CLIENTS / 2) | 1059 | if (num < MAX_FRIEND_CLIENTS / 2) |
1114 | continue; | 1060 | continue; |
1115 | 1061 | ||
1116 | if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { | 1062 | if (dht->friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { |
1117 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ | 1063 | send_NATping(dht, dht->friends_list[i].client_id, dht->friends_list[i].NATping_id, 0); /*0 is request*/ |
1118 | friends_list[i].NATping_timestamp = temp_time; | 1064 | dht->friends_list[i].NATping_timestamp = temp_time; |
1119 | } | 1065 | } |
1120 | 1066 | ||
1121 | if (friends_list[i].hole_punching == 1 && | 1067 | if (dht->friends_list[i].hole_punching == 1 && |
1122 | friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && | 1068 | dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && |
1123 | friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { | 1069 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { |
1124 | 1070 | ||
1125 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); | 1071 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); |
1126 | 1072 | ||
@@ -1129,10 +1075,10 @@ static void doNAT(void) | |||
1129 | 1075 | ||
1130 | uint16_t port_list[MAX_FRIEND_CLIENTS]; | 1076 | uint16_t port_list[MAX_FRIEND_CLIENTS]; |
1131 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); | 1077 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); |
1132 | punch_holes(ip, port_list, numports, i); | 1078 | punch_holes(dht, ip, port_list, numports, i); |
1133 | 1079 | ||
1134 | friends_list[i].punching_timestamp = temp_time; | 1080 | dht->friends_list[i].punching_timestamp = temp_time; |
1135 | friends_list[i].hole_punching = 0; | 1081 | dht->friends_list[i].hole_punching = 0; |
1136 | } | 1082 | } |
1137 | } | 1083 | } |
1138 | } | 1084 | } |
@@ -1149,7 +1095,7 @@ static void doNAT(void) | |||
1149 | network while preventing amplification attacks. | 1095 | network while preventing amplification attacks. |
1150 | return 0 if node was added | 1096 | return 0 if node was added |
1151 | return -1 if node was not added */ | 1097 | return -1 if node was not added */ |
1152 | int add_toping(uint8_t *client_id, IP_Port ip_port) | 1098 | int add_toping(DHT * dht, uint8_t *client_id, IP_Port ip_port) |
1153 | { | 1099 | { |
1154 | if (ip_port.ip.i == 0) | 1100 | if (ip_port.ip.i == 0) |
1155 | return -1; | 1101 | return -1; |
@@ -1157,19 +1103,19 @@ int add_toping(uint8_t *client_id, IP_Port ip_port) | |||
1157 | uint32_t i; | 1103 | uint32_t i; |
1158 | 1104 | ||
1159 | for (i = 0; i < MAX_TOPING; ++i) { | 1105 | for (i = 0; i < MAX_TOPING; ++i) { |
1160 | if (toping[i].ip_port.ip.i == 0) { | 1106 | if (dht->toping[i].ip_port.ip.i == 0) { |
1161 | memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1107 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1162 | toping[i].ip_port.ip.i = ip_port.ip.i; | 1108 | dht->toping[i].ip_port.ip.i = ip_port.ip.i; |
1163 | toping[i].ip_port.port = ip_port.port; | 1109 | dht->toping[i].ip_port.port = ip_port.port; |
1164 | return 0; | 1110 | return 0; |
1165 | } | 1111 | } |
1166 | } | 1112 | } |
1167 | 1113 | ||
1168 | for (i = 0; i < MAX_TOPING; ++i) { | 1114 | for (i = 0; i < MAX_TOPING; ++i) { |
1169 | if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) { | 1115 | if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { |
1170 | memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1116 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1171 | toping[i].ip_port.ip.i = ip_port.ip.i; | 1117 | dht->toping[i].ip_port.ip.i = ip_port.ip.i; |
1172 | toping[i].ip_port.port = ip_port.port; | 1118 | dht->toping[i].ip_port.port = ip_port.port; |
1173 | return 0; | 1119 | return 0; |
1174 | } | 1120 | } |
1175 | } | 1121 | } |
@@ -1179,68 +1125,80 @@ int add_toping(uint8_t *client_id, IP_Port ip_port) | |||
1179 | 1125 | ||
1180 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds | 1126 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds |
1181 | this function must be run at least once every TIME_TOPING seconds*/ | 1127 | this function must be run at least once every TIME_TOPING seconds*/ |
1182 | static void do_toping() | 1128 | static void do_toping(DHT * dht) |
1183 | { | 1129 | { |
1184 | uint64_t temp_time = unix_time(); | 1130 | uint64_t temp_time = unix_time(); |
1185 | 1131 | ||
1186 | if (!is_timeout(temp_time, last_toping, TIME_TOPING)) | 1132 | if (!is_timeout(temp_time, dht->last_toping, TIME_TOPING)) |
1187 | return; | 1133 | return; |
1188 | 1134 | ||
1189 | last_toping = temp_time; | 1135 | dht->last_toping = temp_time; |
1190 | uint32_t i; | 1136 | uint32_t i; |
1191 | 1137 | ||
1192 | for (i = 0; i < MAX_TOPING; ++i) { | 1138 | for (i = 0; i < MAX_TOPING; ++i) { |
1193 | if (toping[i].ip_port.ip.i == 0) | 1139 | if (dht->toping[i].ip_port.ip.i == 0) |
1194 | return; | 1140 | return; |
1195 | 1141 | ||
1196 | send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id); | 1142 | //send_ping_request(dht, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); |
1197 | toping[i].ip_port.ip.i = 0; | 1143 | send_ping_request(dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); |
1144 | dht->toping[i].ip_port.ip.i = 0; | ||
1198 | } | 1145 | } |
1199 | } | 1146 | } |
1200 | 1147 | ||
1201 | 1148 | ||
1202 | void DHT_init(void) | 1149 | DHT * new_DHT(Net_Crypto *c) |
1203 | { | 1150 | { |
1204 | networking_registerhandler(temp_net, 0, &handle_ping_request, NULL); | 1151 | DHT * temp = calloc(1, sizeof(DHT)); |
1205 | networking_registerhandler(temp_net, 1, &handle_ping_response, NULL); | 1152 | if (temp == NULL) |
1206 | networking_registerhandler(temp_net, 2, &handle_getnodes, NULL); | 1153 | return NULL; |
1207 | networking_registerhandler(temp_net, 3, &handle_sendnodes, NULL); | 1154 | temp->c = c; |
1208 | cryptopacket_registerhandler(temp_net_crypto, 254, &handle_NATping); | 1155 | networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp); |
1156 | networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp); | ||
1157 | networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp); | ||
1158 | networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp); | ||
1159 | cryptopacket_registerhandler(c, 254, &handle_NATping, temp); | ||
1160 | temp_DHT = temp; | ||
1161 | return temp; | ||
1209 | } | 1162 | } |
1210 | 1163 | ||
1211 | void doDHT(void) | 1164 | void do_DHT(DHT * dht) |
1165 | { | ||
1166 | do_Close(dht); | ||
1167 | do_DHT_friends(dht); | ||
1168 | do_NAT(dht); | ||
1169 | do_toping(dht); | ||
1170 | } | ||
1171 | void kill_DHT(DHT * dht) | ||
1212 | { | 1172 | { |
1213 | doClose(); | 1173 | free(dht->friends_list); |
1214 | doDHTFriends(); | 1174 | free(dht); |
1215 | doNAT(); | ||
1216 | do_toping(); | ||
1217 | } | 1175 | } |
1218 | 1176 | ||
1219 | /* get the size of the DHT (for saving) */ | 1177 | /* get the size of the DHT (for saving) */ |
1220 | uint32_t DHT_size(void) | 1178 | uint32_t DHT_size(DHT * dht) |
1221 | { | 1179 | { |
1222 | return sizeof(close_clientlist) + sizeof(Friend) * num_friends; | 1180 | return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends; |
1223 | } | 1181 | } |
1224 | 1182 | ||
1225 | /* save the DHT in data where data is an array of size DHT_size() */ | 1183 | /* save the DHT in data where data is an array of size DHT_size() */ |
1226 | void DHT_save(uint8_t *data) | 1184 | void DHT_save(DHT * dht, uint8_t *data) |
1227 | { | 1185 | { |
1228 | memcpy(data, close_clientlist, sizeof(close_clientlist)); | 1186 | memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist)); |
1229 | memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends); | 1187 | memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); |
1230 | } | 1188 | } |
1231 | 1189 | ||
1232 | /* load the DHT from data of size size; | 1190 | /* load the DHT from data of size size; |
1233 | * return -1 if failure | 1191 | * return -1 if failure |
1234 | * return 0 if success | 1192 | * return 0 if success |
1235 | */ | 1193 | */ |
1236 | int DHT_load(uint8_t *data, uint32_t size) | 1194 | int DHT_load(DHT * dht, uint8_t *data, uint32_t size) |
1237 | { | 1195 | { |
1238 | init_ping(); | 1196 | init_ping(); |
1239 | 1197 | ||
1240 | if (size < sizeof(close_clientlist)) | 1198 | if (size < sizeof(dht->close_clientlist)) |
1241 | return -1; | 1199 | return -1; |
1242 | 1200 | ||
1243 | if ((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) | 1201 | if ((size - sizeof(dht->close_clientlist)) % sizeof(DHT_Friend) != 0) |
1244 | return -1; | 1202 | return -1; |
1245 | 1203 | ||
1246 | uint32_t i, j; | 1204 | uint32_t i, j; |
@@ -1249,19 +1207,19 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1249 | 1207 | ||
1250 | Client_data *client; | 1208 | Client_data *client; |
1251 | 1209 | ||
1252 | temp = (size - sizeof(close_clientlist)) / sizeof(Friend); | 1210 | temp = (size - sizeof(dht->close_clientlist)) / sizeof(DHT_Friend); |
1253 | 1211 | ||
1254 | if (temp != 0) { | 1212 | if (temp != 0) { |
1255 | Friend *tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); | 1213 | DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); |
1256 | 1214 | ||
1257 | for (i = 0; i < temp; ++i) { | 1215 | for (i = 0; i < temp; ++i) { |
1258 | DHT_addfriend(tempfriends_list[i].client_id); | 1216 | DHT_addfriend(dht, tempfriends_list[i].client_id); |
1259 | 1217 | ||
1260 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 1218 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
1261 | client = &tempfriends_list[i].client_list[j]; | 1219 | client = &tempfriends_list[i].client_list[j]; |
1262 | 1220 | ||
1263 | if (client->timestamp != 0) | 1221 | if (client->timestamp != 0) |
1264 | getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id); | 1222 | getnodes(dht, client->ip_port, client->client_id, tempfriends_list[i].client_id); |
1265 | } | 1223 | } |
1266 | } | 1224 | } |
1267 | } | 1225 | } |
@@ -1270,7 +1228,7 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1270 | 1228 | ||
1271 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1229 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1272 | if (tempclose_clientlist[i].timestamp != 0) | 1230 | if (tempclose_clientlist[i].timestamp != 0) |
1273 | DHT_bootstrap( tempclose_clientlist[i].ip_port, | 1231 | DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, |
1274 | tempclose_clientlist[i].client_id ); | 1232 | tempclose_clientlist[i].client_id ); |
1275 | } | 1233 | } |
1276 | 1234 | ||
@@ -1280,13 +1238,13 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1280 | /* returns 0 if we are not connected to the DHT | 1238 | /* returns 0 if we are not connected to the DHT |
1281 | * returns 1 if we are | 1239 | * returns 1 if we are |
1282 | */ | 1240 | */ |
1283 | int DHT_isconnected(void) | 1241 | int DHT_isconnected(DHT * dht) |
1284 | { | 1242 | { |
1285 | uint32_t i; | 1243 | uint32_t i; |
1286 | uint64_t temp_time = unix_time(); | 1244 | uint64_t temp_time = unix_time(); |
1287 | 1245 | ||
1288 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1246 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1289 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) | 1247 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) |
1290 | return 1; | 1248 | return 1; |
1291 | } | 1249 | } |
1292 | 1250 | ||
@@ -34,6 +34,20 @@ extern "C" { | |||
34 | /* size of the client_id in bytes */ | 34 | /* size of the client_id in bytes */ |
35 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES | 35 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES |
36 | 36 | ||
37 | /* maximum number of clients stored per friend. */ | ||
38 | #define MAX_FRIEND_CLIENTS 8 | ||
39 | |||
40 | /* A list of the clients mathematically closest to ours. */ | ||
41 | #define LCLIENT_LIST 32 | ||
42 | |||
43 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | ||
44 | #define LPING_ARRAY 256 //NOTE Deprecated (doesn't do anything) | ||
45 | |||
46 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | ||
47 | |||
48 | /*Maximum newly announced nodes to ping per TIME_TOPING seconds*/ | ||
49 | #define MAX_TOPING 16 | ||
50 | |||
37 | typedef struct { | 51 | typedef struct { |
38 | uint8_t client_id[CLIENT_ID_SIZE]; | 52 | uint8_t client_id[CLIENT_ID_SIZE]; |
39 | IP_Port ip_port; | 53 | IP_Port ip_port; |
@@ -45,19 +59,64 @@ typedef struct { | |||
45 | uint64_t ret_timestamp; | 59 | uint64_t ret_timestamp; |
46 | } Client_data; | 60 | } Client_data; |
47 | 61 | ||
48 | Client_data *DHT_get_close_list(void); | 62 | /*----------------------------------------------------------------------------------*/ |
63 | |||
64 | typedef struct { | ||
65 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
66 | Client_data client_list[MAX_FRIEND_CLIENTS]; | ||
67 | |||
68 | /* time at which the last get_nodes request was sent. */ | ||
69 | uint64_t lastgetnode; | ||
70 | |||
71 | /* Symetric NAT hole punching stuff */ | ||
72 | |||
73 | /* 1 if currently hole punching, otherwise 0 */ | ||
74 | uint8_t hole_punching; | ||
75 | uint32_t punching_index; | ||
76 | uint64_t punching_timestamp; | ||
77 | uint64_t recvNATping_timestamp; | ||
78 | uint64_t NATping_id; | ||
79 | uint64_t NATping_timestamp; | ||
80 | } DHT_Friend; | ||
81 | |||
82 | typedef struct { | ||
83 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
84 | IP_Port ip_port; | ||
85 | } Node_format; | ||
86 | |||
87 | typedef struct { | ||
88 | IP_Port ip_port; | ||
89 | uint64_t ping_id; | ||
90 | uint64_t timestamp; | ||
91 | } Pinged; | ||
92 | |||
93 | /*----------------------------------------------------------------------------------*/ | ||
94 | typedef struct { | ||
95 | Net_Crypto *c; | ||
96 | Client_data close_clientlist[LCLIENT_LIST]; | ||
97 | DHT_Friend *friends_list; | ||
98 | uint16_t num_friends; | ||
99 | Pinged send_nodes[LSEND_NODES_ARRAY]; | ||
100 | Node_format toping[MAX_TOPING]; | ||
101 | uint64_t last_toping; | ||
102 | uint64_t close_lastgetnodes; | ||
103 | } DHT; | ||
104 | /*----------------------------------------------------------------------------------*/ | ||
105 | DHT * temp_DHT; //TODO: remove | ||
106 | |||
107 | Client_data *DHT_get_close_list(DHT * dht); | ||
49 | 108 | ||
50 | /* Add a new friend to the friends list | 109 | /* Add a new friend to the friends list |
51 | client_id must be CLIENT_ID_SIZE bytes long. | 110 | client_id must be CLIENT_ID_SIZE bytes long. |
52 | returns 0 if success | 111 | returns 0 if success |
53 | returns 1 if failure (friends list is full) */ | 112 | returns 1 if failure (friends list is full) */ |
54 | int DHT_addfriend(uint8_t *client_id); | 113 | int DHT_addfriend(DHT * dht, uint8_t *client_id); |
55 | 114 | ||
56 | /* Delete a friend from the friends list | 115 | /* Delete a friend from the friends list |
57 | client_id must be CLIENT_ID_SIZE bytes long. | 116 | client_id must be CLIENT_ID_SIZE bytes long. |
58 | returns 0 if success | 117 | returns 0 if success |
59 | returns 1 if failure (client_id not in friends list) */ | 118 | returns 1 if failure (client_id not in friends list) */ |
60 | int DHT_delfriend(uint8_t *client_id); | 119 | int DHT_delfriend(DHT * dht, uint8_t *client_id); |
61 | 120 | ||
62 | /* Get ip of friend | 121 | /* Get ip of friend |
63 | client_id must be CLIENT_ID_SIZE bytes long. | 122 | client_id must be CLIENT_ID_SIZE bytes long. |
@@ -66,14 +125,14 @@ int DHT_delfriend(uint8_t *client_id); | |||
66 | returns ip if success | 125 | returns ip if success |
67 | returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) | 126 | returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) |
68 | returns ip of 1 if friend is not in list. */ | 127 | returns ip of 1 if friend is not in list. */ |
69 | IP_Port DHT_getfriendip(uint8_t *client_id); | 128 | IP_Port DHT_getfriendip(DHT * dht, uint8_t *client_id); |
70 | 129 | ||
71 | /* Run this function at least a couple times per second (It's the main loop) */ | 130 | /* Run this function at least a couple times per second (It's the main loop) */ |
72 | void doDHT(void); | 131 | void do_DHT(DHT * dht); |
73 | 132 | ||
74 | /* Use this function to bootstrap the client | 133 | /* Use this function to bootstrap the client |
75 | Sends a get nodes request to the given node with ip port and public_key */ | 134 | Sends a get nodes request to the given node with ip port and public_key */ |
76 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); | 135 | void DHT_bootstrap(DHT * dht, IP_Port ip_port, uint8_t *public_key); |
77 | 136 | ||
78 | /* Add nodes to the toping list | 137 | /* Add nodes to the toping list |
79 | all nodes in this list are pinged every TIME_TOPING seconds | 138 | all nodes in this list are pinged every TIME_TOPING seconds |
@@ -83,17 +142,17 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); | |||
83 | network while preventing amplification attacks. | 142 | network while preventing amplification attacks. |
84 | return 0 if node was added | 143 | return 0 if node was added |
85 | return -1 if node was not added */ | 144 | return -1 if node was not added */ |
86 | int add_toping(uint8_t *client_id, IP_Port ip_port); | 145 | int add_toping(DHT * dht, uint8_t *client_id, IP_Port ip_port); |
87 | 146 | ||
88 | /* ROUTING FUNCTIONS */ | 147 | /* ROUTING FUNCTIONS */ |
89 | 148 | ||
90 | /* send the given packet to node with client_id | 149 | /* send the given packet to node with client_id |
91 | returns -1 if failure */ | 150 | returns -1 if failure */ |
92 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length); | 151 | int route_packet(DHT * dht, uint8_t *client_id, uint8_t *packet, uint32_t length); |
93 | 152 | ||
94 | /* Send the following packet to everyone who tells us they are connected to friend_id | 153 | /* Send the following packet to everyone who tells us they are connected to friend_id |
95 | returns the number of nodes it sent the packet to */ | 154 | returns the number of nodes it sent the packet to */ |
96 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); | 155 | int route_tofriend(DHT * dht, uint8_t *friend_id, uint8_t *packet, uint32_t length); |
97 | 156 | ||
98 | /* NAT PUNCHING FUNCTIONS */ | 157 | /* NAT PUNCHING FUNCTIONS */ |
99 | 158 | ||
@@ -101,29 +160,31 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); | |||
101 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | 160 | ip_portlist must be at least MAX_FRIEND_CLIENTS big |
102 | returns the number of ips returned | 161 | returns the number of ips returned |
103 | returns -1 if no such friend*/ | 162 | returns -1 if no such friend*/ |
104 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id); | 163 | int friend_ips(DHT * dht, IP_Port *ip_portlist, uint8_t *friend_id); |
105 | 164 | ||
106 | /* SAVE/LOAD functions */ | 165 | /* SAVE/LOAD functions */ |
107 | 166 | ||
108 | /* get the size of the DHT (for saving) */ | 167 | /* get the size of the DHT (for saving) */ |
109 | uint32_t DHT_size(void); | 168 | uint32_t DHT_size(DHT * dht); |
110 | 169 | ||
111 | /* save the DHT in data where data is an array of size DHT_size() */ | 170 | /* save the DHT in data where data is an array of size DHT_size() */ |
112 | void DHT_save(uint8_t *data); | 171 | void DHT_save(DHT * dht, uint8_t *data); |
113 | 172 | ||
114 | /* init DHT */ | 173 | /* init DHT */ |
115 | void DHT_init(void); | 174 | DHT * new_DHT(Net_Crypto *c); |
175 | |||
176 | void kill_DHT(DHT * dht); | ||
116 | 177 | ||
117 | /* load the DHT from data of size size; | 178 | /* load the DHT from data of size size; |
118 | return -1 if failure | 179 | return -1 if failure |
119 | return 0 if success */ | 180 | return 0 if success */ |
120 | int DHT_load(uint8_t *data, uint32_t size); | 181 | int DHT_load(DHT * dht, uint8_t *data, uint32_t size); |
121 | 182 | ||
122 | /* returns 0 if we are not connected to the DHT | 183 | /* returns 0 if we are not connected to the DHT |
123 | returns 1 if we are */ | 184 | returns 1 if we are */ |
124 | int DHT_isconnected(); | 185 | int DHT_isconnected(DHT * dht); |
125 | 186 | ||
126 | void addto_lists(IP_Port ip_port, uint8_t *client_id); | 187 | void addto_lists(DHT * dht, IP_Port ip_port, uint8_t *client_id); |
127 | 188 | ||
128 | #ifdef __cplusplus | 189 | #ifdef __cplusplus |
129 | } | 190 | } |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index 3045e215..07980d26 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -123,28 +123,29 @@ static int LAN_ip(IP ip) | |||
123 | 123 | ||
124 | static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 124 | static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
125 | { | 125 | { |
126 | DHT *dht = object; | ||
126 | if (LAN_ip(source.ip) == -1) | 127 | if (LAN_ip(source.ip) == -1) |
127 | return 1; | 128 | return 1; |
128 | 129 | ||
129 | if (length != crypto_box_PUBLICKEYBYTES + 1) | 130 | if (length != crypto_box_PUBLICKEYBYTES + 1) |
130 | return 1; | 131 | return 1; |
131 | 132 | ||
132 | DHT_bootstrap(source, packet + 1); | 133 | DHT_bootstrap(dht, source, packet + 1); |
133 | return 0; | 134 | return 0; |
134 | } | 135 | } |
135 | 136 | ||
136 | 137 | ||
137 | int send_LANdiscovery(uint16_t port) | 138 | int send_LANdiscovery(uint16_t port, Net_Crypto *c) |
138 | { | 139 | { |
139 | uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; | 140 | uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; |
140 | data[0] = 33; | 141 | data[0] = 33; |
141 | memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 142 | memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); |
142 | IP_Port ip_port = {broadcast_ip(), port}; | 143 | IP_Port ip_port = {broadcast_ip(), port}; |
143 | return sendpacket(temp_net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); | 144 | return sendpacket(c->lossless_udp->net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); |
144 | } | 145 | } |
145 | 146 | ||
146 | 147 | ||
147 | void LANdiscovery_init(void) | 148 | void LANdiscovery_init(DHT *dht) |
148 | { | 149 | { |
149 | networking_registerhandler(temp_net, 33, &handle_LANdiscovery, NULL); | 150 | networking_registerhandler(dht->c->lossless_udp->net, 33, &handle_LANdiscovery, dht); |
150 | } | 151 | } |
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h index 6b5b8c75..5a790331 100644 --- a/core/LAN_discovery.h +++ b/core/LAN_discovery.h | |||
@@ -40,11 +40,11 @@ extern "C" { | |||
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /*Send a LAN discovery pcaket to the broadcast address with port port*/ | 42 | /*Send a LAN discovery pcaket to the broadcast address with port port*/ |
43 | int send_LANdiscovery(uint16_t port); | 43 | int send_LANdiscovery(uint16_t port, Net_Crypto *c); |
44 | 44 | ||
45 | 45 | ||
46 | /* sets up packet handlers */ | 46 | /* sets up packet handlers */ |
47 | void LANdiscovery_init(void); | 47 | void LANdiscovery_init(DHT *dht); |
48 | 48 | ||
49 | 49 | ||
50 | 50 | ||
diff --git a/core/Messenger.c b/core/Messenger.c index cb3d2551..25a4ff98 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -108,9 +108,8 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len) | |||
108 | */ | 108 | */ |
109 | void getaddress(Messenger *m, uint8_t *address) | 109 | void getaddress(Messenger *m, uint8_t *address) |
110 | { | 110 | { |
111 | //memcpy(address, m->public_key, crypto_box_PUBLICKEYBYTES); //TODO | 111 | memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES); |
112 | memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES); | 112 | uint32_t nospam = get_nospam(&(m->fr)); |
113 | uint32_t nospam = get_nospam(); | ||
114 | memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); | 113 | memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); |
115 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | 114 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); |
116 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); | 115 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); |
@@ -150,7 +149,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) | |||
150 | if (length < 1) | 149 | if (length < 1) |
151 | return FAERR_NOMESSAGE; | 150 | return FAERR_NOMESSAGE; |
152 | 151 | ||
153 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | 152 | if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) |
154 | return FAERR_OWNKEY; | 153 | return FAERR_OWNKEY; |
155 | 154 | ||
156 | int friend_id = getfriend_id(m, client_id); | 155 | int friend_id = getfriend_id(m, client_id); |
@@ -176,7 +175,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) | |||
176 | 175 | ||
177 | for (i = 0; i <= m->numfriends; ++i) { | 176 | for (i = 0; i <= m->numfriends; ++i) { |
178 | if (m->friendlist[i].status == NOFRIEND) { | 177 | if (m->friendlist[i].status == NOFRIEND) { |
179 | DHT_addfriend(client_id); | 178 | DHT_addfriend(m->dht, client_id); |
180 | m->friendlist[i].status = FRIEND_ADDED; | 179 | m->friendlist[i].status = FRIEND_ADDED; |
181 | m->friendlist[i].crypt_connection_id = -1; | 180 | m->friendlist[i].crypt_connection_id = -1; |
182 | m->friendlist[i].friendrequest_lastsent = 0; | 181 | m->friendlist[i].friendrequest_lastsent = 0; |
@@ -216,7 +215,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id) | |||
216 | 215 | ||
217 | for (i = 0; i <= m->numfriends; ++i) { | 216 | for (i = 0; i <= m->numfriends; ++i) { |
218 | if (m->friendlist[i].status == NOFRIEND) { | 217 | if (m->friendlist[i].status == NOFRIEND) { |
219 | DHT_addfriend(client_id); | 218 | DHT_addfriend(m->dht, client_id); |
220 | m->friendlist[i].status = FRIEND_CONFIRMED; | 219 | m->friendlist[i].status = FRIEND_CONFIRMED; |
221 | m->friendlist[i].crypt_connection_id = -1; | 220 | m->friendlist[i].crypt_connection_id = -1; |
222 | m->friendlist[i].friendrequest_lastsent = 0; | 221 | m->friendlist[i].friendrequest_lastsent = 0; |
@@ -245,7 +244,7 @@ int m_delfriend(Messenger *m, int friendnumber) | |||
245 | if (friendnumber >= m->numfriends || friendnumber < 0) | 244 | if (friendnumber >= m->numfriends || friendnumber < 0) |
246 | return -1; | 245 | return -1; |
247 | 246 | ||
248 | DHT_delfriend(m->friendlist[friendnumber].client_id); | 247 | DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id); |
249 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); | 248 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); |
250 | free(m->friendlist[friendnumber].statusmessage); | 249 | free(m->friendlist[friendnumber].statusmessage); |
251 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); | 250 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); |
@@ -522,7 +521,7 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno) | |||
522 | /* set the function that will be executed when a friend request is received. */ | 521 | /* set the function that will be executed when a friend request is received. */ |
523 | void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) | 522 | void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) |
524 | { | 523 | { |
525 | callback_friendrequest(function, userdata); | 524 | callback_friendrequest(&(m->fr), function, userdata); |
526 | } | 525 | } |
527 | 526 | ||
528 | /* set the function that will be executed when a message from a friend is received. */ | 527 | /* set the function that will be executed when a message from a friend is received. */ |
@@ -617,7 +616,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint | |||
617 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ | 616 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ |
618 | int LANdiscovery(timer *t, void *arg) | 617 | int LANdiscovery(timer *t, void *arg) |
619 | { | 618 | { |
620 | send_LANdiscovery(htons(PORT)); | 619 | send_LANdiscovery(htons(PORT), temp_net_crypto); |
621 | timer_start(t, LAN_DISCOVERY_INTERVAL); | 620 | timer_start(t, LAN_DISCOVERY_INTERVAL); |
622 | return 0; | 621 | return 0; |
623 | } | 622 | } |
@@ -637,19 +636,26 @@ Messenger *initMessenger(void) | |||
637 | } | 636 | } |
638 | m->net_crypto = new_net_crypto(m->net); | 637 | m->net_crypto = new_net_crypto(m->net); |
639 | if (m->net_crypto == NULL) { | 638 | if (m->net_crypto == NULL) { |
639 | kill_networking(m->net); | ||
640 | free(m); | ||
641 | return NULL; | ||
642 | } | ||
643 | m->dht = new_DHT(m->net_crypto); | ||
644 | if (m->dht == NULL) { | ||
645 | kill_net_crypto(m->net_crypto); | ||
646 | kill_networking(m->net); | ||
640 | free(m); | 647 | free(m); |
641 | free(m->net); | ||
642 | return NULL; | 648 | return NULL; |
643 | } | 649 | } |
644 | new_keys(m->net_crypto); | 650 | new_keys(m->net_crypto); |
645 | m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); | 651 | m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); |
646 | 652 | ||
647 | DHT_init(); | 653 | friendreq_init(&(m->fr), m->net_crypto); |
648 | friendreq_init(); | 654 | LANdiscovery_init(m->dht); |
649 | LANdiscovery_init(); | 655 | set_nospam(&(m->fr), random_int()); |
650 | set_nospam(random_int()); | 656 | init_cryptopackets(m->dht); |
651 | 657 | ||
652 | send_LANdiscovery(htons(PORT)); | 658 | send_LANdiscovery(htons(PORT), m->net_crypto); |
653 | timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL); | 659 | timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL); |
654 | 660 | ||
655 | return m; | 661 | return m; |
@@ -661,7 +667,9 @@ void cleanupMessenger(Messenger *m) | |||
661 | /* FIXME TODO ideally cleanupMessenger will mirror initMessenger | 667 | /* FIXME TODO ideally cleanupMessenger will mirror initMessenger |
662 | * this requires the other modules to expose cleanup functions | 668 | * this requires the other modules to expose cleanup functions |
663 | */ | 669 | */ |
670 | kill_DHT(m->dht); | ||
664 | kill_net_crypto(m->net_crypto); | 671 | kill_net_crypto(m->net_crypto); |
672 | kill_networking(m->net); | ||
665 | free(m->friendlist); | 673 | free(m->friendlist); |
666 | free(m); | 674 | free(m); |
667 | } | 675 | } |
@@ -677,7 +685,7 @@ void doFriends(Messenger *m) | |||
677 | 685 | ||
678 | for (i = 0; i < m->numfriends; ++i) { | 686 | for (i = 0; i < m->numfriends; ++i) { |
679 | if (m->friendlist[i].status == FRIEND_ADDED) { | 687 | if (m->friendlist[i].status == FRIEND_ADDED) { |
680 | int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, | 688 | int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, |
681 | m->friendlist[i].info_size); | 689 | m->friendlist[i].info_size); |
682 | 690 | ||
683 | if (fr >= 0) { | 691 | if (fr >= 0) { |
@@ -699,7 +707,7 @@ void doFriends(Messenger *m) | |||
699 | } | 707 | } |
700 | } | 708 | } |
701 | 709 | ||
702 | IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); | 710 | IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id); |
703 | 711 | ||
704 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { | 712 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { |
705 | case 0: | 713 | case 0: |
@@ -883,7 +891,7 @@ void doMessenger(Messenger *m) | |||
883 | { | 891 | { |
884 | networking_poll(m->net); | 892 | networking_poll(m->net); |
885 | 893 | ||
886 | doDHT(); | 894 | do_DHT(m->dht); |
887 | do_net_crypto(m->net_crypto); | 895 | do_net_crypto(m->net_crypto); |
888 | doInbound(m); | 896 | doInbound(m); |
889 | doFriends(m); | 897 | doFriends(m); |
@@ -897,7 +905,7 @@ uint32_t Messenger_size(Messenger *m) | |||
897 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES | 905 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES |
898 | + sizeof(uint32_t) // nospam | 906 | + sizeof(uint32_t) // nospam |
899 | + sizeof(uint32_t) // DHT size | 907 | + sizeof(uint32_t) // DHT size |
900 | + DHT_size() // DHT itself | 908 | + DHT_size(m->dht) // DHT itself |
901 | + sizeof(uint32_t) // Friendlist size | 909 | + sizeof(uint32_t) // Friendlist size |
902 | + sizeof(Friend) * m->numfriends // Friendlist itself | 910 | + sizeof(Friend) * m->numfriends // Friendlist itself |
903 | + sizeof(uint16_t) // Own nickname length | 911 | + sizeof(uint16_t) // Own nickname length |
@@ -910,13 +918,13 @@ void Messenger_save(Messenger *m, uint8_t *data) | |||
910 | { | 918 | { |
911 | save_keys(m->net_crypto, data); | 919 | save_keys(m->net_crypto, data); |
912 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 920 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
913 | uint32_t nospam = get_nospam(); | 921 | uint32_t nospam = get_nospam(&(m->fr)); |
914 | memcpy(data, &nospam, sizeof(nospam)); | 922 | memcpy(data, &nospam, sizeof(nospam)); |
915 | data += sizeof(nospam); | 923 | data += sizeof(nospam); |
916 | uint32_t size = DHT_size(); | 924 | uint32_t size = DHT_size(m->dht); |
917 | memcpy(data, &size, sizeof(size)); | 925 | memcpy(data, &size, sizeof(size)); |
918 | data += sizeof(size); | 926 | data += sizeof(size); |
919 | DHT_save(data); | 927 | DHT_save(m->dht, data); |
920 | data += size; | 928 | data += size; |
921 | size = sizeof(Friend) * m->numfriends; | 929 | size = sizeof(Friend) * m->numfriends; |
922 | memcpy(data, &size, sizeof(size)); | 930 | memcpy(data, &size, sizeof(size)); |
@@ -943,7 +951,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
943 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 951 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
944 | uint32_t nospam; | 952 | uint32_t nospam; |
945 | memcpy(&nospam, data, sizeof(nospam)); | 953 | memcpy(&nospam, data, sizeof(nospam)); |
946 | set_nospam(nospam); | 954 | set_nospam(&(m->fr), nospam); |
947 | data += sizeof(nospam); | 955 | data += sizeof(nospam); |
948 | uint32_t size; | 956 | uint32_t size; |
949 | memcpy(&size, data, sizeof(size)); | 957 | memcpy(&size, data, sizeof(size)); |
@@ -954,7 +962,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
954 | 962 | ||
955 | length -= size; | 963 | length -= size; |
956 | 964 | ||
957 | if (DHT_load(data, size) == -1) | 965 | if (DHT_load(m->dht, data, size) == -1) |
958 | return -1; | 966 | return -1; |
959 | 967 | ||
960 | data += size; | 968 | data += size; |
diff --git a/core/Messenger.h b/core/Messenger.h index a2e8f16e..c4e7cc1e 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -115,6 +115,8 @@ typedef struct Messenger { | |||
115 | 115 | ||
116 | Networking_Core *net; | 116 | Networking_Core *net; |
117 | Net_Crypto * net_crypto; | 117 | Net_Crypto * net_crypto; |
118 | DHT * dht; | ||
119 | Friend_Requests fr; | ||
118 | uint8_t name[MAX_NAME_LENGTH]; | 120 | uint8_t name[MAX_NAME_LENGTH]; |
119 | uint16_t name_length; | 121 | uint16_t name_length; |
120 | 122 | ||
diff --git a/core/friend_requests.c b/core/friend_requests.c index 7be7a4bd..b723de36 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -23,15 +23,12 @@ | |||
23 | 23 | ||
24 | #include "friend_requests.h" | 24 | #include "friend_requests.h" |
25 | 25 | ||
26 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
27 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
28 | |||
29 | /* Try to send a friendrequest to peer with public_key | 26 | /* Try to send a friendrequest to peer with public_key |
30 | data is the data in the request and length is the length. | 27 | data is the data in the request and length is the length. |
31 | return -1 if failure. | 28 | return -1 if failure. |
32 | return 0 if it sent the friend request directly to the friend. | 29 | return 0 if it sent the friend request directly to the friend. |
33 | return the number of peers it was routed through if it did not send it directly.*/ | 30 | return the number of peers it was routed through if it did not send it directly.*/ |
34 | int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) | 31 | int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) |
35 | { | 32 | { |
36 | if (length + sizeof(nospam_num) > MAX_DATA_SIZE) | 33 | if (length + sizeof(nospam_num) > MAX_DATA_SIZE) |
37 | return -1; | 34 | return -1; |
@@ -40,25 +37,25 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, | |||
40 | memcpy(temp, &nospam_num, sizeof(nospam_num)); | 37 | memcpy(temp, &nospam_num, sizeof(nospam_num)); |
41 | memcpy(temp + sizeof(nospam_num), data, length); | 38 | memcpy(temp + sizeof(nospam_num), data, length); |
42 | uint8_t packet[MAX_DATA_SIZE]; | 39 | uint8_t packet[MAX_DATA_SIZE]; |
43 | int len = create_request(self_public_key, self_secret_key, packet, public_key, temp, length + sizeof(nospam_num), | 40 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp, length + sizeof(nospam_num), |
44 | 32); /* 32 is friend request packet id */ | 41 | 32); /* 32 is friend request packet id */ |
45 | 42 | ||
46 | if (len == -1) | 43 | if (len == -1) |
47 | return -1; | 44 | return -1; |
48 | 45 | ||
49 | IP_Port ip_port = DHT_getfriendip(public_key); | 46 | IP_Port ip_port = DHT_getfriendip(dht, public_key); |
50 | 47 | ||
51 | if (ip_port.ip.i == 1) | 48 | if (ip_port.ip.i == 1) |
52 | return -1; | 49 | return -1; |
53 | 50 | ||
54 | if (ip_port.ip.i != 0) { | 51 | if (ip_port.ip.i != 0) { |
55 | if (sendpacket(temp_net->sock, ip_port, packet, len) != -1) | 52 | if (sendpacket(dht->c->lossless_udp->net->sock, ip_port, packet, len) != -1) |
56 | return 0; | 53 | return 0; |
57 | 54 | ||
58 | return -1; | 55 | return -1; |
59 | } | 56 | } |
60 | 57 | ||
61 | int num = route_tofriend(public_key, packet, len); | 58 | int num = route_tofriend(dht, public_key, packet, len); |
62 | 59 | ||
63 | if (num == 0) | 60 | if (num == 0) |
64 | return -1; | 61 | return -1; |
@@ -66,58 +63,47 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, | |||
66 | return num; | 63 | return num; |
67 | } | 64 | } |
68 | 65 | ||
69 | static uint32_t nospam; | 66 | |
70 | /* | 67 | /* |
71 | * Set and get the nospam variable used to prevent one type of friend request spam | 68 | * Set and get the nospam variable used to prevent one type of friend request spam |
72 | */ | 69 | */ |
73 | void set_nospam(uint32_t num) | 70 | void set_nospam(Friend_Requests *fr, uint32_t num) |
74 | { | 71 | { |
75 | nospam = num; | 72 | fr->nospam = num; |
76 | } | 73 | } |
77 | 74 | ||
78 | uint32_t get_nospam() | 75 | uint32_t get_nospam(Friend_Requests *fr) |
79 | { | 76 | { |
80 | return nospam; | 77 | return fr->nospam; |
81 | } | 78 | } |
82 | 79 | ||
83 | static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *); | 80 | |
84 | static uint8_t handle_friendrequest_isset = 0; | ||
85 | static void *handle_friendrequest_userdata; | ||
86 | /* set the function that will be executed when a friend request is received. */ | 81 | /* set the function that will be executed when a friend request is received. */ |
87 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) | 82 | void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) |
88 | { | 83 | { |
89 | handle_friendrequest = function; | 84 | fr->handle_friendrequest = function; |
90 | handle_friendrequest_isset = 1; | 85 | fr->handle_friendrequest_isset = 1; |
91 | handle_friendrequest_userdata = userdata; | 86 | fr->handle_friendrequest_userdata = userdata; |
92 | } | 87 | } |
93 | 88 | ||
94 | |||
95 | /*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem | ||
96 | TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/ | ||
97 | |||
98 | #define MAX_RECEIVED_STORED 32 | ||
99 | |||
100 | static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]; | ||
101 | static uint16_t received_requests_index; | ||
102 | |||
103 | /*Add to list of received friend requests*/ | 89 | /*Add to list of received friend requests*/ |
104 | static void addto_receivedlist(uint8_t *client_id) | 90 | static void addto_receivedlist(Friend_Requests *fr, uint8_t *client_id) |
105 | { | 91 | { |
106 | if (received_requests_index >= MAX_RECEIVED_STORED) | 92 | if (fr->received_requests_index >= MAX_RECEIVED_STORED) |
107 | received_requests_index = 0; | 93 | fr->received_requests_index = 0; |
108 | 94 | ||
109 | memcpy(received_requests[received_requests_index], client_id, crypto_box_PUBLICKEYBYTES); | 95 | memcpy(fr->received_requests[fr->received_requests_index], client_id, crypto_box_PUBLICKEYBYTES); |
110 | ++received_requests_index; | 96 | ++fr->received_requests_index; |
111 | } | 97 | } |
112 | 98 | ||
113 | /* Check if a friend request was already received | 99 | /* Check if a friend request was already received |
114 | return 0 if not, 1 if we did */ | 100 | return 0 if not, 1 if we did */ |
115 | static int request_received(uint8_t *client_id) | 101 | static int request_received(Friend_Requests *fr, uint8_t *client_id) |
116 | { | 102 | { |
117 | uint32_t i; | 103 | uint32_t i; |
118 | 104 | ||
119 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) { | 105 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) { |
120 | if (memcmp(received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) | 106 | if (memcmp(fr->received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) |
121 | return 1; | 107 | return 1; |
122 | } | 108 | } |
123 | 109 | ||
@@ -125,26 +111,27 @@ static int request_received(uint8_t *client_id) | |||
125 | } | 111 | } |
126 | 112 | ||
127 | 113 | ||
128 | static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 114 | static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) |
129 | { | 115 | { |
130 | if (handle_friendrequest_isset == 0) | 116 | Friend_Requests *fr = object; |
117 | if (fr->handle_friendrequest_isset == 0) | ||
131 | return 1; | 118 | return 1; |
132 | 119 | ||
133 | if (length <= sizeof(nospam)) | 120 | if (length <= sizeof(fr->nospam)) |
134 | return 1; | 121 | return 1; |
135 | 122 | ||
136 | if (request_received(source_pubkey)) | 123 | if (request_received(fr, source_pubkey)) |
137 | return 1; | 124 | return 1; |
138 | 125 | ||
139 | if (memcmp(packet, &nospam, sizeof(nospam)) != 0) | 126 | if (memcmp(packet, &fr->nospam, sizeof(fr->nospam)) != 0) |
140 | return 1; | 127 | return 1; |
141 | 128 | ||
142 | addto_receivedlist(source_pubkey); | 129 | addto_receivedlist(fr, source_pubkey); |
143 | (*handle_friendrequest)(source_pubkey, packet + 4, length - 4, handle_friendrequest_userdata); | 130 | (*fr->handle_friendrequest)(source_pubkey, packet + 4, length - 4, fr->handle_friendrequest_userdata); |
144 | return 0; | 131 | return 0; |
145 | } | 132 | } |
146 | 133 | ||
147 | void friendreq_init(void) | 134 | void friendreq_init(Friend_Requests *fr, Net_Crypto *c) |
148 | { | 135 | { |
149 | cryptopacket_registerhandler(temp_net_crypto, 32, &friendreq_handlepacket); | 136 | cryptopacket_registerhandler(c, 32, &friendreq_handlepacket, fr); |
150 | } | 137 | } |
diff --git a/core/friend_requests.h b/core/friend_requests.h index 3ce0df8c..cc31155e 100644 --- a/core/friend_requests.h +++ b/core/friend_requests.h | |||
@@ -31,21 +31,36 @@ | |||
31 | extern "C" { | 31 | extern "C" { |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | typedef struct { | ||
35 | uint32_t nospam; | ||
36 | void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *); | ||
37 | uint8_t handle_friendrequest_isset; | ||
38 | void *handle_friendrequest_userdata; | ||
39 | |||
40 | /*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem | ||
41 | TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/ | ||
42 | |||
43 | #define MAX_RECEIVED_STORED 32 | ||
44 | |||
45 | uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]; | ||
46 | uint16_t received_requests_index; | ||
47 | } Friend_Requests; | ||
48 | |||
34 | /* Try to send a friendrequest to peer with public_key | 49 | /* Try to send a friendrequest to peer with public_key |
35 | data is the data in the request and length is the length. */ | 50 | data is the data in the request and length is the length. */ |
36 | int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); | 51 | int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); |
37 | /* | 52 | /* |
38 | * Set and get the nospam variable used to prevent one type of friend request spam | 53 | * Set and get the nospam variable used to prevent one type of friend request spam |
39 | */ | 54 | */ |
40 | void set_nospam(uint32_t num); | 55 | void set_nospam(Friend_Requests *fr, uint32_t num); |
41 | uint32_t get_nospam(); | 56 | uint32_t get_nospam(Friend_Requests *fr); |
42 | 57 | ||
43 | /* set the function that will be executed when a friend request for us is received. | 58 | /* set the function that will be executed when a friend request for us is received. |
44 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ | 59 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ |
45 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata); | 60 | void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata); |
46 | 61 | ||
47 | /* sets up friendreq packet handlers */ | 62 | /* sets up friendreq packet handlers */ |
48 | void friendreq_init(void); | 63 | void friendreq_init(Friend_Requests *fr, Net_Crypto *c); |
49 | 64 | ||
50 | #ifdef __cplusplus | 65 | #ifdef __cplusplus |
51 | } | 66 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index dcf36a12..2e63d2f1 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -265,34 +265,35 @@ static int handle_request(Net_Crypto *c, uint8_t *public_key, uint8_t *data, uin | |||
265 | return -1; | 265 | return -1; |
266 | } | 266 | } |
267 | 267 | ||
268 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb) | 268 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object) |
269 | { | 269 | { |
270 | c->cryptopackethandlers[byte] = cb; | 270 | c->cryptopackethandlers[byte].function = cb; |
271 | c->cryptopackethandlers[byte].object = object; | ||
271 | } | 272 | } |
272 | 273 | ||
273 | static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 274 | static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
274 | { | 275 | { |
275 | Net_Crypto *c = object; | 276 | DHT *dht = object; |
276 | if (packet[0] == 32) { | 277 | if (packet[0] == 32) { |
277 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | 278 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || |
278 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 279 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
279 | return 1; | 280 | return 1; |
280 | 281 | ||
281 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | 282 | if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. |
282 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 283 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
283 | uint8_t data[MAX_DATA_SIZE]; | 284 | uint8_t data[MAX_DATA_SIZE]; |
284 | uint8_t number; | 285 | uint8_t number; |
285 | int len = handle_request(c, public_key, data, &number, packet, length); | 286 | int len = handle_request(dht->c, public_key, data, &number, packet, length); |
286 | 287 | ||
287 | if (len == -1 || len == 0) | 288 | if (len == -1 || len == 0) |
288 | return 1; | 289 | return 1; |
289 | 290 | ||
290 | if (!c->cryptopackethandlers[number]) return 1; | 291 | if (!dht->c->cryptopackethandlers[number].function) return 1; |
291 | 292 | ||
292 | c->cryptopackethandlers[number](source, public_key, data, len); | 293 | dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, data, len); |
293 | 294 | ||
294 | } else { /* if request is not for us, try routing it. */ | 295 | } else { /* if request is not for us, try routing it. */ |
295 | if (route_packet(packet + 1, packet, length) == length) //NOTE | 296 | if (route_packet(dht, packet + 1, packet, length) == length) //NOTE |
296 | return 0; | 297 | return 0; |
297 | } | 298 | } |
298 | } | 299 | } |
@@ -572,17 +573,9 @@ int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id) | |||
572 | return CONN_NO_CONNECTION; | 573 | return CONN_NO_CONNECTION; |
573 | } | 574 | } |
574 | 575 | ||
575 | /* Generate our public and private keys | ||
576 | Only call this function the first time the program starts. */ | ||
577 | |||
578 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this | ||
579 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
580 | |||
581 | void new_keys(Net_Crypto *c) | 576 | void new_keys(Net_Crypto *c) |
582 | { | 577 | { |
583 | crypto_box_keypair(c->self_public_key, c->self_secret_key); | 578 | crypto_box_keypair(c->self_public_key, c->self_secret_key); |
584 | memcpy(self_public_key, c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
585 | memcpy(self_secret_key, c->self_secret_key, crypto_box_PUBLICKEYBYTES); | ||
586 | } | 579 | } |
587 | 580 | ||
588 | /* save the public and private keys to the keys array | 581 | /* save the public and private keys to the keys array |
@@ -713,12 +706,16 @@ Net_Crypto * new_net_crypto(Networking_Core * net) | |||
713 | if (temp->lossless_udp == NULL) | 706 | if (temp->lossless_udp == NULL) |
714 | return NULL; | 707 | return NULL; |
715 | memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); | 708 | memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); |
716 | //networking_registerhandler(temp, 32, &cryptopacket_handle); | ||
717 | networking_registerhandler(net, 32, &cryptopacket_handle, temp); | ||
718 | temp_net_crypto = temp; //TODO remove | 709 | temp_net_crypto = temp; //TODO remove |
719 | return temp; | 710 | return temp; |
720 | } | 711 | } |
721 | 712 | ||
713 | void init_cryptopackets(void *dht) | ||
714 | { | ||
715 | DHT *s_dht = dht; | ||
716 | networking_registerhandler(s_dht->c->lossless_udp->net, 32, &cryptopacket_handle, s_dht); | ||
717 | } | ||
718 | |||
722 | static void kill_timedout(Net_Crypto *c) | 719 | static void kill_timedout(Net_Crypto *c) |
723 | { | 720 | { |
724 | uint32_t i; | 721 | uint32_t i; |
diff --git a/core/net_crypto.h b/core/net_crypto.h index 745f1f14..887b432b 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -25,7 +25,6 @@ | |||
25 | #define NET_CRYPTO_H | 25 | #define NET_CRYPTO_H |
26 | 26 | ||
27 | #include "Lossless_UDP.h" | 27 | #include "Lossless_UDP.h" |
28 | #include "DHT.h" | ||
29 | 28 | ||
30 | #ifdef __cplusplus | 29 | #ifdef __cplusplus |
31 | extern "C" { | 30 | extern "C" { |
@@ -33,9 +32,6 @@ extern "C" { | |||
33 | 32 | ||
34 | #define MAX_INCOMING 64 | 33 | #define MAX_INCOMING 64 |
35 | 34 | ||
36 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this | ||
37 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
38 | |||
39 | typedef struct { | 35 | typedef struct { |
40 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ | 36 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ |
41 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ | 37 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ |
@@ -51,25 +47,32 @@ typedef struct { | |||
51 | 47 | ||
52 | } Crypto_Connection; | 48 | } Crypto_Connection; |
53 | 49 | ||
54 | typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len); | 50 | typedef int (*cryptopacket_handler_callback)(void * object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len); |
51 | |||
52 | typedef struct { | ||
53 | cryptopacket_handler_callback function; | ||
54 | void * object; | ||
55 | }Cryptopacket_Handles; | ||
55 | 56 | ||
56 | typedef struct { | 57 | typedef struct { |
57 | Lossless_UDP * lossless_udp; | 58 | Lossless_UDP * lossless_udp; |
58 | 59 | ||
59 | Crypto_Connection *crypto_connections; | 60 | Crypto_Connection *crypto_connections; |
60 | 61 | ||
61 | uint32_t crypto_connections_length; /* Length of connections array */ | 62 | uint32_t crypto_connections_length; /* Length of connections array */ |
62 | 63 | ||
63 | /* Our public and secret keys. */ | 64 | /* Our public and secret keys. */ |
64 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 65 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; |
65 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | 66 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; |
66 | 67 | ||
67 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | 68 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ |
68 | int incoming_connections[MAX_INCOMING]; | 69 | int incoming_connections[MAX_INCOMING]; |
69 | 70 | ||
70 | cryptopacket_handler_callback cryptopackethandlers[256]; | 71 | Cryptopacket_Handles cryptopackethandlers[256]; |
71 | } Net_Crypto; | 72 | } Net_Crypto; |
72 | 73 | ||
74 | #include "DHT.h" | ||
75 | |||
73 | Net_Crypto * temp_net_crypto; //TODO: remove this | 76 | Net_Crypto * temp_net_crypto; //TODO: remove this |
74 | 77 | ||
75 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) | 78 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) |
@@ -130,7 +133,7 @@ int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t * | |||
130 | 133 | ||
131 | 134 | ||
132 | /* Function to call when request beginning with byte is received */ | 135 | /* Function to call when request beginning with byte is received */ |
133 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb); | 136 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void * object); |
134 | 137 | ||
135 | /* Start a secure connection with other peer who has public_key and ip_port | 138 | /* Start a secure connection with other peer who has public_key and ip_port |
136 | returns -1 if failure | 139 | returns -1 if failure |
@@ -183,6 +186,9 @@ void do_net_crypto(Net_Crypto *c); | |||
183 | 186 | ||
184 | void kill_net_crypto(Net_Crypto *c); | 187 | void kill_net_crypto(Net_Crypto *c); |
185 | 188 | ||
189 | /* Init the cryptopacket handling */ | ||
190 | void init_cryptopackets(void *dht); | ||
191 | |||
186 | #ifdef __cplusplus | 192 | #ifdef __cplusplus |
187 | } | 193 | } |
188 | #endif | 194 | #endif |
diff --git a/core/network.c b/core/network.c index 684a4227..9ec390fb 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -196,7 +196,6 @@ Networking_Core * new_networking(IP ip, uint16_t port) | |||
196 | /* Bind our socket to port PORT and address 0.0.0.0 */ | 196 | /* Bind our socket to port PORT and address 0.0.0.0 */ |
197 | ADDR addr = {AF_INET, htons(port), ip}; | 197 | ADDR addr = {AF_INET, htons(port), ip}; |
198 | bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); | 198 | bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); |
199 | temp_net = temp; | ||
200 | return temp; | 199 | return temp; |
201 | } | 200 | } |
202 | 201 | ||
diff --git a/core/network.h b/core/network.h index 5ed25620..47d9fff2 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -112,7 +112,6 @@ typedef struct { | |||
112 | int sock; | 112 | int sock; |
113 | }Networking_Core; | 113 | }Networking_Core; |
114 | 114 | ||
115 | Networking_Core * temp_net; | ||
116 | /* returns current time in milleseconds since the epoch. */ | 115 | /* returns current time in milleseconds since the epoch. */ |
117 | uint64_t current_time(void); | 116 | uint64_t current_time(void); |
118 | 117 | ||
diff --git a/core/ping.c b/core/ping.c index d2b290a0..10b9b19f 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -26,7 +26,6 @@ typedef struct { | |||
26 | static pinged_t pings[PING_NUM_MAX]; | 26 | static pinged_t pings[PING_NUM_MAX]; |
27 | static size_t num_pings; | 27 | static size_t num_pings; |
28 | static size_t pos_pings; | 28 | static size_t pos_pings; |
29 | static clientid_t *self_id = (clientid_t *) &self_public_key; | ||
30 | 29 | ||
31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 30 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c |
32 | 31 | ||
@@ -115,19 +114,19 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id) | |||
115 | int rc; | 114 | int rc; |
116 | uint64_t ping_id; | 115 | uint64_t ping_id; |
117 | 116 | ||
118 | if (is_pinging(ipp, 0) || id_eq(client_id, self_id)) | 117 | if (is_pinging(ipp, 0) || id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) |
119 | return 1; | 118 | return 1; |
120 | 119 | ||
121 | // Generate random ping_id | 120 | // Generate random ping_id |
122 | ping_id = add_ping(ipp); | 121 | ping_id = add_ping(ipp); |
123 | 122 | ||
124 | pk.magic = PACKET_PING_REQ; | 123 | pk.magic = PACKET_PING_REQ; |
125 | id_cpy(&pk.client_id, self_id); // Our pubkey | 124 | id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey |
126 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce | 125 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce |
127 | 126 | ||
128 | // Encrypt ping_id using recipient privkey | 127 | // Encrypt ping_id using recipient privkey |
129 | rc = encrypt_data((uint8_t *) client_id, | 128 | rc = encrypt_data((uint8_t *) client_id, |
130 | self_secret_key, | 129 | temp_net_crypto->self_secret_key, |
131 | (uint8_t *) &pk.nonce, | 130 | (uint8_t *) &pk.nonce, |
132 | (uint8_t *) &ping_id, sizeof(ping_id), | 131 | (uint8_t *) &ping_id, sizeof(ping_id), |
133 | (uint8_t *) &pk.ping_id); | 132 | (uint8_t *) &pk.ping_id); |
@@ -135,7 +134,7 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id) | |||
135 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 134 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
136 | return 1; | 135 | return 1; |
137 | 136 | ||
138 | return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); | 137 | return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
139 | } | 138 | } |
140 | 139 | ||
141 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | 140 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) |
@@ -143,16 +142,16 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | |||
143 | pingres_t pk; | 142 | pingres_t pk; |
144 | int rc; | 143 | int rc; |
145 | 144 | ||
146 | if (id_eq(client_id, self_id)) | 145 | if (id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) |
147 | return 1; | 146 | return 1; |
148 | 147 | ||
149 | pk.magic = PACKET_PING_RES; | 148 | pk.magic = PACKET_PING_RES; |
150 | id_cpy(&pk.client_id, self_id); // Our pubkey | 149 | id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey |
151 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce | 150 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce |
152 | 151 | ||
153 | // Encrypt ping_id using recipient privkey | 152 | // Encrypt ping_id using recipient privkey |
154 | rc = encrypt_data((uint8_t *) client_id, | 153 | rc = encrypt_data((uint8_t *) client_id, |
155 | self_secret_key, | 154 | temp_net_crypto->self_secret_key, |
156 | (uint8_t *) &pk.nonce, | 155 | (uint8_t *) &pk.nonce, |
157 | (uint8_t *) &ping_id, sizeof(ping_id), | 156 | (uint8_t *) &ping_id, sizeof(ping_id), |
158 | (uint8_t *) &pk.ping_id); | 157 | (uint8_t *) &pk.ping_id); |
@@ -160,21 +159,22 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | |||
160 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 159 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
161 | return 1; | 160 | return 1; |
162 | 161 | ||
163 | return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); | 162 | return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
164 | } | 163 | } |
165 | 164 | ||
166 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 165 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
167 | { | 166 | { |
167 | DHT * dht = object; | ||
168 | pingreq_t *p = (pingreq_t *) packet; | 168 | pingreq_t *p = (pingreq_t *) packet; |
169 | int rc; | 169 | int rc; |
170 | uint64_t ping_id; | 170 | uint64_t ping_id; |
171 | 171 | ||
172 | if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id)) | 172 | if (length != sizeof(pingreq_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key)) |
173 | return 1; | 173 | return 1; |
174 | 174 | ||
175 | // Decrypt ping_id | 175 | // Decrypt ping_id |
176 | rc = decrypt_data((uint8_t *) &p->client_id, | 176 | rc = decrypt_data((uint8_t *) &p->client_id, |
177 | self_secret_key, | 177 | dht->c->self_secret_key, |
178 | (uint8_t *) &p->nonce, | 178 | (uint8_t *) &p->nonce, |
179 | (uint8_t *) &p->ping_id, | 179 | (uint8_t *) &p->ping_id, |
180 | sizeof(ping_id) + ENCRYPTION_PADDING, | 180 | sizeof(ping_id) + ENCRYPTION_PADDING, |
@@ -185,23 +185,24 @@ int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t | |||
185 | 185 | ||
186 | // Send response | 186 | // Send response |
187 | send_ping_response(source, &p->client_id, ping_id); | 187 | send_ping_response(source, &p->client_id, ping_id); |
188 | add_toping((uint8_t *) &p->client_id, source); | 188 | add_toping(dht, (uint8_t *) &p->client_id, source); |
189 | 189 | ||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 193 | int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
194 | { | 194 | { |
195 | DHT * dht = object; | ||
195 | pingres_t *p = (pingres_t *) packet; | 196 | pingres_t *p = (pingres_t *) packet; |
196 | int rc; | 197 | int rc; |
197 | uint64_t ping_id; | 198 | uint64_t ping_id; |
198 | 199 | ||
199 | if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id)) | 200 | if (length != sizeof(pingres_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key)) |
200 | return 1; | 201 | return 1; |
201 | 202 | ||
202 | // Decrypt ping_id | 203 | // Decrypt ping_id |
203 | rc = decrypt_data((uint8_t *) &p->client_id, | 204 | rc = decrypt_data((uint8_t *) &p->client_id, |
204 | self_secret_key, | 205 | dht->c->self_secret_key, |
205 | (uint8_t *) &p->nonce, | 206 | (uint8_t *) &p->nonce, |
206 | (uint8_t *) &p->ping_id, | 207 | (uint8_t *) &p->ping_id, |
207 | sizeof(ping_id) + ENCRYPTION_PADDING, | 208 | sizeof(ping_id) + ENCRYPTION_PADDING, |
@@ -215,6 +216,6 @@ int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_ | |||
215 | return 1; | 216 | return 1; |
216 | 217 | ||
217 | // Associate source ip with client_id | 218 | // Associate source ip with client_id |
218 | addto_lists(source, (uint8_t *) &p->client_id); | 219 | addto_lists(dht, source, (uint8_t *) &p->client_id); |
219 | return 0; | 220 | return 0; |
220 | } | 221 | } |