diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 148 |
1 files changed, 117 insertions, 31 deletions
@@ -60,11 +60,20 @@ int id_closest(char * client_id, char * client_id1, char * client_id2)//tested | |||
60 | //check if client with client_id is already in list of length length. | 60 | //check if client with client_id is already in list of length length. |
61 | //if it is set it's corresponding timestamp to current time. | 61 | //if it is set it's corresponding timestamp to current time. |
62 | //return True(1) or False(0) | 62 | //return True(1) or False(0) |
63 | int client_in_list(Client_data * list, uint32_t length, char * client_id) | 63 | //TODO: maybe optimize this. |
64 | int client_in_list(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port) | ||
64 | { | 65 | { |
65 | uint32_t i, j; | 66 | uint32_t i, j; |
67 | uint32_t temp_time = unix_time(); | ||
68 | |||
66 | for(i = 0; i < length; i++) | 69 | for(i = 0; i < length; i++) |
67 | { | 70 | { |
71 | //If the id for an ip/port changes, replace it. | ||
72 | if(list[i].ip_port.ip.i == ip_port.ip.i && | ||
73 | list[i].ip_port.port == ip_port.port) | ||
74 | { | ||
75 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | ||
76 | } | ||
68 | for(j = 0; j < CLIENT_ID_SIZE; j++) | 77 | for(j = 0; j < CLIENT_ID_SIZE; j++) |
69 | { | 78 | { |
70 | 79 | ||
@@ -76,7 +85,7 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id) | |||
76 | if(j == CLIENT_ID_SIZE) | 85 | if(j == CLIENT_ID_SIZE) |
77 | { | 86 | { |
78 | //Refresh the client timestamp. | 87 | //Refresh the client timestamp. |
79 | list[i].timestamp = unix_time(); | 88 | list[i].timestamp = temp_time; |
80 | return 1; | 89 | return 1; |
81 | } | 90 | } |
82 | } | 91 | } |
@@ -207,13 +216,15 @@ int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port i | |||
207 | int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port, char * comp_client_id) | 216 | int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port, char * comp_client_id) |
208 | { | 217 | { |
209 | uint32_t i; | 218 | uint32_t i; |
219 | uint32_t temp_time = unix_time(); | ||
220 | |||
210 | for(i = 0; i < length; i++) | 221 | for(i = 0; i < length; i++) |
211 | { | 222 | { |
212 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) | 223 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) |
213 | { | 224 | { |
214 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 225 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
215 | list[i].ip_port = ip_port; | 226 | list[i].ip_port = ip_port; |
216 | list[i].timestamp = unix_time(); | 227 | list[i].timestamp = temp_time; |
217 | return 0; | 228 | return 0; |
218 | } | 229 | } |
219 | } | 230 | } |
@@ -227,7 +238,7 @@ void addto_lists(IP_Port ip_port, char * client_id) | |||
227 | uint32_t i; | 238 | uint32_t i; |
228 | 239 | ||
229 | //NOTE: current behaviour if there are two clients with the same id is to only keep one (the first one) | 240 | //NOTE: current behaviour if there are two clients with the same id is to only keep one (the first one) |
230 | if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id)) | 241 | if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
231 | { | 242 | { |
232 | 243 | ||
233 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) | 244 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
@@ -239,7 +250,7 @@ void addto_lists(IP_Port ip_port, char * client_id) | |||
239 | } | 250 | } |
240 | for(i = 0; i < num_friends; i++) | 251 | for(i = 0; i < num_friends; i++) |
241 | { | 252 | { |
242 | if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id)) | 253 | if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) |
243 | { | 254 | { |
244 | 255 | ||
245 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) | 256 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) |
@@ -254,21 +265,43 @@ void addto_lists(IP_Port ip_port, char * client_id) | |||
254 | 265 | ||
255 | //ping timeout in seconds | 266 | //ping timeout in seconds |
256 | #define PING_TIMEOUT 10 | 267 | #define PING_TIMEOUT 10 |
257 | //check if we are currently pinging an ip_port | 268 | //check if we are currently pinging an ip_port and/or a ping_id |
269 | //Variables with values of zero will not be checked. | ||
258 | //if we are already, return 1 | 270 | //if we are already, return 1 |
259 | //else return 0 | 271 | //else return 0 |
260 | //TODO: Maybe optimize this | 272 | //TODO: Maybe optimize this |
261 | int is_pinging(IP_Port ip_port) | 273 | int is_pinging(IP_Port ip_port, uint32_t ping_id) |
262 | { | 274 | { |
263 | uint32_t i; | 275 | uint32_t i; |
264 | 276 | uint8_t pinging; | |
277 | uint32_t temp_time = unix_time(); | ||
278 | |||
265 | for(i = 0; i < LPING_ARRAY; i++ ) | 279 | for(i = 0; i < LPING_ARRAY; i++ ) |
266 | { | 280 | { |
267 | if((pings[i].timestamp + PING_TIMEOUT) > unix_time() && | 281 | if((pings[i].timestamp + PING_TIMEOUT) > temp_time) |
268 | pings[i].ip_port.ip.i == ip_port.ip.i && | ||
269 | pings[i].ip_port.port == ip_port.port) | ||
270 | { | 282 | { |
271 | return 1; | 283 | if(ip_port.ip.i != 0) |
284 | { | ||
285 | pinging = 0; | ||
286 | if(pings[i].ip_port.ip.i == ip_port.ip.i && | ||
287 | pings[i].ip_port.port == ip_port.port) | ||
288 | { | ||
289 | pinging = 1; | ||
290 | } | ||
291 | } | ||
292 | if(ping_id != 0) | ||
293 | { | ||
294 | pinging = 0; | ||
295 | if(pings[i].ping_id == ping_id) | ||
296 | { | ||
297 | pinging = 1; | ||
298 | } | ||
299 | } | ||
300 | if(pinging == 1) | ||
301 | { | ||
302 | return 1; | ||
303 | } | ||
304 | |||
272 | } | 305 | } |
273 | } | 306 | } |
274 | 307 | ||
@@ -278,17 +311,38 @@ int is_pinging(IP_Port ip_port) | |||
278 | 311 | ||
279 | 312 | ||
280 | //Same as last function but for get_node requests. | 313 | //Same as last function but for get_node requests. |
281 | int is_gettingnodes(IP_Port ip_port) | 314 | int is_gettingnodes(IP_Port ip_port, uint32_t ping_id) |
282 | { | 315 | { |
283 | uint32_t i; | 316 | uint32_t i; |
284 | 317 | uint8_t pinging; | |
285 | for(i = 0; i < LSEND_NODES_ARRAY; i++ ) | 318 | uint32_t temp_time = unix_time(); |
319 | |||
320 | for(i = 0; i < LPING_ARRAY; i++ ) | ||
286 | { | 321 | { |
287 | if((send_nodes[i].timestamp + PING_TIMEOUT) > unix_time() && | 322 | if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) |
288 | send_nodes[i].ip_port.ip.i == ip_port.ip.i && | ||
289 | send_nodes[i].ip_port.port == ip_port.port) | ||
290 | { | 323 | { |
291 | return 1; | 324 | if(ip_port.ip.i != 0) |
325 | { | ||
326 | pinging = 0; | ||
327 | if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && | ||
328 | send_nodes[i].ip_port.port == ip_port.port) | ||
329 | { | ||
330 | pinging = 1; | ||
331 | } | ||
332 | } | ||
333 | if(ping_id != 0) | ||
334 | { | ||
335 | pinging = 0; | ||
336 | if(send_nodes[i].ping_id == ping_id) | ||
337 | { | ||
338 | pinging = 1; | ||
339 | } | ||
340 | } | ||
341 | if(pinging == 1) | ||
342 | { | ||
343 | return 1; | ||
344 | } | ||
345 | |||
292 | } | 346 | } |
293 | } | 347 | } |
294 | 348 | ||
@@ -296,6 +350,7 @@ int is_gettingnodes(IP_Port ip_port) | |||
296 | 350 | ||
297 | } | 351 | } |
298 | 352 | ||
353 | |||
299 | //Add a new ping request to the list of ping requests | 354 | //Add a new ping request to the list of ping requests |
300 | //returns the ping_id to put in the ping request | 355 | //returns the ping_id to put in the ping request |
301 | //returns 0 if problem. | 356 | //returns 0 if problem. |
@@ -304,13 +359,15 @@ int add_pinging(IP_Port ip_port) | |||
304 | { | 359 | { |
305 | uint32_t i, j; | 360 | uint32_t i, j; |
306 | int ping_id = rand(); | 361 | int ping_id = rand(); |
362 | uint32_t temp_time = unix_time(); | ||
363 | |||
307 | for(i = 0; i < PING_TIMEOUT; i++ ) | 364 | for(i = 0; i < PING_TIMEOUT; i++ ) |
308 | { | 365 | { |
309 | for(j = 0; j < LPING_ARRAY; j++ ) | 366 | for(j = 0; j < LPING_ARRAY; j++ ) |
310 | { | 367 | { |
311 | if((pings[j].timestamp + PING_TIMEOUT - i) < unix_time()) | 368 | if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) |
312 | { | 369 | { |
313 | pings[j].timestamp = unix_time(); | 370 | pings[j].timestamp = temp_time; |
314 | pings[j].ip_port = ip_port; | 371 | pings[j].ip_port = ip_port; |
315 | pings[j].ping_id = ping_id; | 372 | pings[j].ping_id = ping_id; |
316 | return ping_id; | 373 | return ping_id; |
@@ -326,13 +383,15 @@ int add_gettingnodes(IP_Port ip_port) | |||
326 | { | 383 | { |
327 | uint32_t i, j; | 384 | uint32_t i, j; |
328 | int ping_id = rand(); | 385 | int ping_id = rand(); |
386 | uint32_t temp_time = unix_time(); | ||
387 | |||
329 | for(i = 0; i < PING_TIMEOUT; i++ ) | 388 | for(i = 0; i < PING_TIMEOUT; i++ ) |
330 | { | 389 | { |
331 | for(j = 0; j < LSEND_NODES_ARRAY; j++ ) | 390 | for(j = 0; j < LSEND_NODES_ARRAY; j++ ) |
332 | { | 391 | { |
333 | if((send_nodes[j].timestamp + PING_TIMEOUT - i) < unix_time()) | 392 | if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) |
334 | { | 393 | { |
335 | send_nodes[j].timestamp = unix_time(); | 394 | send_nodes[j].timestamp = temp_time; |
336 | send_nodes[j].ip_port = ip_port; | 395 | send_nodes[j].ip_port = ip_port; |
337 | send_nodes[j].ping_id = ping_id; | 396 | send_nodes[j].ping_id = ping_id; |
338 | return ping_id; | 397 | return ping_id; |
@@ -344,11 +403,12 @@ int add_gettingnodes(IP_Port ip_port) | |||
344 | } | 403 | } |
345 | 404 | ||
346 | 405 | ||
406 | |||
347 | //send a ping request | 407 | //send a ping request |
348 | //Ping request only works if there is none hos been sent to that ip/port in the last 5 seconds. | 408 | //Ping request only works if there is none hos been sent to that ip/port in the last 5 seconds. |
349 | int pingreq(IP_Port ip_port) | 409 | int pingreq(IP_Port ip_port) |
350 | { | 410 | { |
351 | if(is_pinging(ip_port)) | 411 | if(is_pinging(ip_port, 0)) |
352 | { | 412 | { |
353 | return 1; | 413 | return 1; |
354 | } | 414 | } |
@@ -385,7 +445,7 @@ int pingres(IP_Port ip_port, uint32_t ping_id) | |||
385 | //send a getnodes request | 445 | //send a getnodes request |
386 | int getnodes(IP_Port ip_port, char * client_id) | 446 | int getnodes(IP_Port ip_port, char * client_id) |
387 | { | 447 | { |
388 | if(is_gettingnodes(ip_port)) | 448 | if(is_gettingnodes(ip_port, 0)) |
389 | { | 449 | { |
390 | return 1; | 450 | return 1; |
391 | } | 451 | } |
@@ -448,6 +508,13 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested | |||
448 | uint32_t ping_id; | 508 | uint32_t ping_id; |
449 | 509 | ||
450 | memcpy(&ping_id, packet + 1, 4); | 510 | memcpy(&ping_id, packet + 1, 4); |
511 | IP_Port bad_ip = {{{0}}, 0}; | ||
512 | |||
513 | if(is_pinging(bad_ip, ping_id))//check if packet is from ourself. | ||
514 | { | ||
515 | return 1; | ||
516 | } | ||
517 | |||
451 | pingres(source, ping_id); | 518 | pingres(source, ping_id); |
452 | 519 | ||
453 | pingreq(source); | 520 | pingreq(source); |
@@ -456,15 +523,21 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested | |||
456 | 523 | ||
457 | } | 524 | } |
458 | 525 | ||
459 | int handle_pingres(char * packet, uint32_t length, IP_Port source)//tested | 526 | int handle_pingres(char * packet, uint32_t length, IP_Port source) |
460 | { | 527 | { |
461 | if(length != (5 + CLIENT_ID_SIZE)) | 528 | if(length != (5 + CLIENT_ID_SIZE)) |
462 | { | 529 | { |
463 | return 1; | 530 | return 1; |
464 | } | 531 | } |
532 | uint32_t ping_id; | ||
465 | 533 | ||
466 | addto_lists(source, packet + 5); | 534 | memcpy(&ping_id, packet + 1, 4); |
467 | return 0; | 535 | if(is_pinging(source, ping_id)) |
536 | { | ||
537 | addto_lists(source, packet + 5); | ||
538 | return 0; | ||
539 | } | ||
540 | return 1; | ||
468 | 541 | ||
469 | } | 542 | } |
470 | 543 | ||
@@ -478,6 +551,13 @@ int handle_getnodes(char * packet, uint32_t length, IP_Port source) | |||
478 | memcpy(&ping_id, packet + 1, 4); | 551 | memcpy(&ping_id, packet + 1, 4); |
479 | sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id); | 552 | sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id); |
480 | 553 | ||
554 | IP_Port bad_ip = {{{0}}, 0}; | ||
555 | |||
556 | if(is_gettingnodes(bad_ip, ping_id))//check if packet is from ourself. | ||
557 | { | ||
558 | return 1; | ||
559 | } | ||
560 | |||
481 | pingreq(source); | 561 | pingreq(source); |
482 | 562 | ||
483 | return 0; | 563 | return 0; |
@@ -493,6 +573,13 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested | |||
493 | } | 573 | } |
494 | int num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port)); | 574 | int num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port)); |
495 | uint32_t i; | 575 | uint32_t i; |
576 | uint32_t ping_id; | ||
577 | |||
578 | memcpy(&ping_id, packet + 1, 4); | ||
579 | if(!is_gettingnodes(source, ping_id)) | ||
580 | { | ||
581 | return 1; | ||
582 | } | ||
496 | 583 | ||
497 | Node_format nodes_list[MAX_SENT_NODES]; | 584 | Node_format nodes_list[MAX_SENT_NODES]; |
498 | memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | 585 | memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); |
@@ -513,7 +600,7 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested | |||
513 | 600 | ||
514 | int addfriend(char * client_id) | 601 | int addfriend(char * client_id) |
515 | { | 602 | { |
516 | //TODO:Maybe make the array of friends dynamic instead of a static array with 256 | 603 | //TODO:Maybe make the array of friends dynamic instead of a static array with MAX_FRIENDS |
517 | if(MAX_FRIENDS > num_friends) | 604 | if(MAX_FRIENDS > num_friends) |
518 | { | 605 | { |
519 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); | 606 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); |
@@ -609,7 +696,7 @@ int DHT_recvpacket(char * packet, uint32_t length, IP_Port source) | |||
609 | #define PING_INTERVAL 60 | 696 | #define PING_INTERVAL 60 |
610 | 697 | ||
611 | //ping interval in seconds for each random sending of a get nodes request. | 698 | //ping interval in seconds for each random sending of a get nodes request. |
612 | #define GET_NODE_INTERVAL 20 | 699 | #define GET_NODE_INTERVAL 10 |
613 | 700 | ||
614 | //Ping each client in the "friends" list every 60 seconds. | 701 | //Ping each client in the "friends" list every 60 seconds. |
615 | //Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. | 702 | //Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. |
@@ -679,7 +766,6 @@ void doClose()//tested | |||
679 | index[num_nodes] = i; | 766 | index[num_nodes] = i; |
680 | num_nodes++; | 767 | num_nodes++; |
681 | } | 768 | } |
682 | //TODO: Send getnodes requests | ||
683 | } | 769 | } |
684 | } | 770 | } |
685 | 771 | ||