diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .travis.yml | 9 | ||||
-rw-r--r-- | CMakeLists.txt | 13 | ||||
-rw-r--r-- | core/DHT.c | 277 | ||||
-rw-r--r-- | core/DHT.h | 12 | ||||
-rw-r--r-- | core/Messenger.c | 15 | ||||
-rw-r--r-- | core/net_crypto.c | 12 | ||||
-rw-r--r-- | core/net_crypto.h | 7 | ||||
-rw-r--r-- | core/network.h | 17 | ||||
-rw-r--r-- | docs/DHT.txt | 9 | ||||
-rw-r--r-- | testing/DHT_test.c | 46 | ||||
-rw-r--r-- | testing/Messenger_test.c | 13 |
12 files changed, 299 insertions, 132 deletions
@@ -1,5 +1,4 @@ | |||
1 | .DS_Store | 1 | .DS_Store |
2 | .travis.yml | ||
3 | 2 | ||
4 | //nacl build | 3 | //nacl build |
5 | nacl/build/ | 4 | nacl/build/ |
diff --git a/.travis.yml b/.travis.yml index 8918f02d..78ed6349 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -2,6 +2,15 @@ language: c | |||
2 | compiler: | 2 | compiler: |
3 | - gcc | 3 | - gcc |
4 | 4 | ||
5 | before_script: | ||
6 | - git clone git://github.com/jedisct1/libsodium.git | ||
7 | - cd libsodium | ||
8 | - ./autogen.sh | ||
9 | - ./configure && make check | ||
10 | - sudo make install | ||
11 | - sudo ldconfig | ||
12 | - cd .. | ||
13 | |||
5 | script: | 14 | script: |
6 | - cmake CMakeLists.txt | 15 | - cmake CMakeLists.txt |
7 | - make -j3 | 16 | - make -j3 |
diff --git a/CMakeLists.txt b/CMakeLists.txt index 47fca42b..099232d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -2,14 +2,19 @@ cmake_minimum_required(VERSION 2.6.0) | |||
2 | project(TOX C) | 2 | project(TOX C) |
3 | 3 | ||
4 | set(core_sources | 4 | set(core_sources |
5 | #core/DHT.c | 5 | core/DHT.c |
6 | core/network.c) | 6 | core/network.c |
7 | core/Lossless_UDP.c | ||
8 | core/net_crypto.c | ||
9 | core/Messenger.c) | ||
7 | 10 | ||
8 | set(test_sources | 11 | set(test_sources |
9 | testing/DHT_test.c) | 12 | testing/Messenger_test.c) |
10 | 13 | ||
11 | set(exe_name TOX-app) | 14 | set(exe_name TOX-app) |
12 | 15 | ||
16 | target_link_libraries(sodium) | ||
17 | |||
13 | add_executable(${exe_name} | 18 | add_executable(${exe_name} |
14 | ${core_sources} | 19 | ${core_sources} |
15 | ${test_sources}) | 20 | ${test_sources}) |
@@ -54,36 +54,36 @@ typedef struct | |||
54 | typedef struct | 54 | typedef struct |
55 | { | 55 | { |
56 | IP_Port ip_port; | 56 | IP_Port ip_port; |
57 | uint32_t ping_id; | 57 | uint64_t ping_id; |
58 | uint32_t timestamp; | 58 | uint32_t timestamp; |
59 | 59 | ||
60 | }Pinged; | 60 | }Pinged; |
61 | 61 | ||
62 | 62 | //Our client id/public key | |
63 | uint8_t self_client_id[CLIENT_ID_SIZE]; | 63 | uint8_t self_public_key[CLIENT_ID_SIZE]; |
64 | 64 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | |
65 | 65 | ||
66 | //TODO: Move these out of here and put them into the .c file. | 66 | //TODO: Move these out of here and put them into the .c file. |
67 | //A list of the clients mathematically closest to ours. | 67 | //A list of the clients mathematically closest to ours. |
68 | #define LCLIENT_LIST 32 | 68 | #define LCLIENT_LIST 32 |
69 | Client_data close_clientlist[LCLIENT_LIST]; | 69 | static Client_data close_clientlist[LCLIENT_LIST]; |
70 | 70 | ||
71 | 71 | ||
72 | //Hard maximum number of friends | 72 | //Hard maximum number of friends |
73 | #define MAX_FRIENDS 256 | 73 | #define MAX_FRIENDS 256 |
74 | 74 | ||
75 | //Let's start with a static array for testing. | 75 | //Let's start with a static array for testing. |
76 | Friend friends_list[MAX_FRIENDS]; | 76 | static Friend friends_list[MAX_FRIENDS]; |
77 | uint16_t num_friends; | 77 | static uint16_t num_friends; |
78 | 78 | ||
79 | //The list of ip ports along with the ping_id of what we sent them and a timestamp | 79 | //The list of ip ports along with the ping_id of what we sent them and a timestamp |
80 | #define LPING_ARRAY 128 | 80 | #define LPING_ARRAY 128 |
81 | 81 | ||
82 | Pinged pings[LPING_ARRAY]; | 82 | static Pinged pings[LPING_ARRAY]; |
83 | 83 | ||
84 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | 84 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 |
85 | 85 | ||
86 | Pinged send_nodes[LSEND_NODES_ARRAY]; | 86 | static Pinged send_nodes[LSEND_NODES_ARRAY]; |
87 | 87 | ||
88 | 88 | ||
89 | //Compares client_id1 and client_id2 with client_id | 89 | //Compares client_id1 and client_id2 with client_id |
@@ -298,7 +298,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
298 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) | 298 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
299 | { | 299 | { |
300 | //if we can't replace bad nodes we try replacing good ones | 300 | //if we can't replace bad nodes we try replacing good ones |
301 | replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_client_id); | 301 | replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); |
302 | } | 302 | } |
303 | 303 | ||
304 | } | 304 | } |
@@ -310,7 +310,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
310 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) | 310 | if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) |
311 | { | 311 | { |
312 | //if we can't replace bad nodes we try replacing good ones | 312 | //if we can't replace bad nodes we try replacing good ones |
313 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_client_id); | 313 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, self_public_key); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | } | 316 | } |
@@ -324,7 +324,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
324 | //if we are already, return 1 | 324 | //if we are already, return 1 |
325 | //else return 0 | 325 | //else return 0 |
326 | //TODO: Maybe optimize this | 326 | //TODO: Maybe optimize this |
327 | int is_pinging(IP_Port ip_port, uint32_t ping_id) | 327 | int is_pinging(IP_Port ip_port, uint64_t ping_id) |
328 | { | 328 | { |
329 | uint32_t i; | 329 | uint32_t i; |
330 | uint8_t pinging; | 330 | uint8_t pinging; |
@@ -364,7 +364,7 @@ int is_pinging(IP_Port ip_port, uint32_t ping_id) | |||
364 | 364 | ||
365 | 365 | ||
366 | //Same as last function but for get_node requests. | 366 | //Same as last function but for get_node requests. |
367 | int is_gettingnodes(IP_Port ip_port, uint32_t ping_id) | 367 | int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) |
368 | { | 368 | { |
369 | uint32_t i; | 369 | uint32_t i; |
370 | uint8_t pinging; | 370 | uint8_t pinging; |
@@ -407,10 +407,10 @@ int is_gettingnodes(IP_Port ip_port, uint32_t ping_id) | |||
407 | //returns the ping_id to put in the ping request | 407 | //returns the ping_id to put in the ping request |
408 | //returns 0 if problem. | 408 | //returns 0 if problem. |
409 | //TODO: Maybe optimize this | 409 | //TODO: Maybe optimize this |
410 | int add_pinging(IP_Port ip_port) | 410 | uint64_t add_pinging(IP_Port ip_port) |
411 | { | 411 | { |
412 | uint32_t i, j; | 412 | uint32_t i, j; |
413 | int ping_id = rand(); | 413 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
414 | uint32_t temp_time = unix_time(); | 414 | uint32_t temp_time = unix_time(); |
415 | 415 | ||
416 | for(i = 0; i < PING_TIMEOUT; i++ ) | 416 | for(i = 0; i < PING_TIMEOUT; i++ ) |
@@ -431,10 +431,10 @@ int add_pinging(IP_Port ip_port) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | //Same but for get node requests | 433 | //Same but for get node requests |
434 | int add_gettingnodes(IP_Port ip_port) | 434 | uint64_t add_gettingnodes(IP_Port ip_port) |
435 | { | 435 | { |
436 | uint32_t i, j; | 436 | uint32_t i, j; |
437 | int ping_id = rand(); | 437 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
438 | uint32_t temp_time = unix_time(); | 438 | uint32_t temp_time = unix_time(); |
439 | 439 | ||
440 | for(i = 0; i < PING_TIMEOUT; i++ ) | 440 | for(i = 0; i < PING_TIMEOUT; i++ ) |
@@ -458,23 +458,38 @@ int add_gettingnodes(IP_Port ip_port) | |||
458 | 458 | ||
459 | //send a ping request | 459 | //send a ping request |
460 | //Ping request only works if none has been sent to that ip/port in the last 5 seconds. | 460 | //Ping request only works if none has been sent to that ip/port in the last 5 seconds. |
461 | int pingreq(IP_Port ip_port) | 461 | static int pingreq(IP_Port ip_port, uint8_t * public_key) |
462 | { | 462 | { |
463 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself | ||
464 | { | ||
465 | return 1; | ||
466 | } | ||
467 | |||
463 | if(is_pinging(ip_port, 0)) | 468 | if(is_pinging(ip_port, 0)) |
464 | { | 469 | { |
465 | return 1; | 470 | return 1; |
466 | } | 471 | } |
467 | 472 | ||
468 | int ping_id = add_pinging(ip_port); | 473 | uint64_t ping_id = add_pinging(ip_port); |
469 | if(ping_id == 0) | 474 | if(ping_id == 0) |
470 | { | 475 | { |
471 | return 1; | 476 | return 1; |
472 | } | 477 | } |
473 | 478 | ||
474 | uint8_t data[5 + CLIENT_ID_SIZE]; | 479 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; |
480 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; | ||
481 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
482 | random_nonce(nonce); | ||
483 | |||
484 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); | ||
485 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
486 | { | ||
487 | return -1; | ||
488 | } | ||
475 | data[0] = 0; | 489 | data[0] = 0; |
476 | memcpy(data + 1, &ping_id, 4); | 490 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
477 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 491 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
492 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
478 | 493 | ||
479 | return sendpacket(ip_port, data, sizeof(data)); | 494 | return sendpacket(ip_port, data, sizeof(data)); |
480 | 495 | ||
@@ -482,65 +497,117 @@ int pingreq(IP_Port ip_port) | |||
482 | 497 | ||
483 | 498 | ||
484 | //send a ping response | 499 | //send a ping response |
485 | int pingres(IP_Port ip_port, uint32_t ping_id) | 500 | static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) |
486 | { | 501 | { |
487 | uint8_t data[5 + CLIENT_ID_SIZE]; | 502 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself |
488 | data[0] = 1; | 503 | { |
504 | return 1; | ||
505 | } | ||
489 | 506 | ||
490 | memcpy(data + 1, &ping_id, 4); | 507 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; |
491 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 508 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; |
509 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
510 | random_nonce(nonce); | ||
511 | |||
512 | int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); | ||
513 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
514 | { | ||
515 | return -1; | ||
516 | } | ||
517 | data[0] = 1; | ||
518 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | ||
519 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
520 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
492 | 521 | ||
493 | return sendpacket(ip_port, data, sizeof(data)); | 522 | return sendpacket(ip_port, data, sizeof(data)); |
494 | 523 | ||
495 | } | 524 | } |
496 | 525 | ||
497 | //send a getnodes request | 526 | //send a getnodes request |
498 | int getnodes(IP_Port ip_port, uint8_t * client_id) | 527 | static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) |
499 | { | 528 | { |
529 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself | ||
530 | { | ||
531 | return 1; | ||
532 | } | ||
533 | |||
500 | if(is_gettingnodes(ip_port, 0)) | 534 | if(is_gettingnodes(ip_port, 0)) |
501 | { | 535 | { |
502 | return 1; | 536 | return 1; |
503 | } | 537 | } |
504 | 538 | ||
505 | int ping_id = add_gettingnodes(ip_port); | 539 | uint64_t ping_id = add_gettingnodes(ip_port); |
506 | 540 | ||
507 | if(ping_id == 0) | 541 | if(ping_id == 0) |
508 | { | 542 | { |
509 | return 1; | 543 | return 1; |
510 | } | 544 | } |
511 | 545 | ||
512 | uint8_t data[5 + CLIENT_ID_SIZE*2]; | 546 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; |
513 | data[0] = 2; | 547 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
548 | uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; | ||
549 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
550 | random_nonce(nonce); | ||
514 | 551 | ||
515 | memcpy(data + 1, &ping_id, 4); | 552 | memcpy(plain, &ping_id, sizeof(ping_id)); |
516 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 553 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
517 | memcpy(data + 5 + CLIENT_ID_SIZE, client_id, CLIENT_ID_SIZE); | 554 | |
518 | 555 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); | |
556 | |||
557 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | ||
558 | { | ||
559 | return -1; | ||
560 | } | ||
561 | data[0] = 2; | ||
562 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | ||
563 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
564 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
519 | return sendpacket(ip_port, data, sizeof(data)); | 565 | return sendpacket(ip_port, data, sizeof(data)); |
520 | 566 | ||
521 | } | 567 | } |
522 | 568 | ||
523 | 569 | ||
524 | //send a send nodes response | 570 | //send a send nodes response |
525 | int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id) | 571 | static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) |
526 | { | 572 | { |
527 | uint8_t data[5 + CLIENT_ID_SIZE + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES]; | 573 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is gonna be sent to ourself |
574 | { | ||
575 | return 1; | ||
576 | } | ||
577 | |||
578 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
579 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | ||
580 | |||
528 | Node_format nodes_list[MAX_SENT_NODES]; | 581 | Node_format nodes_list[MAX_SENT_NODES]; |
529 | |||
530 | int num_nodes = get_close_nodes(client_id, nodes_list); | 582 | int num_nodes = get_close_nodes(client_id, nodes_list); |
531 | 583 | ||
532 | if(num_nodes == 0) | 584 | if(num_nodes == 0) |
533 | { | 585 | { |
534 | return 0; | 586 | return 0; |
535 | } | 587 | } |
536 | 588 | ||
589 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | ||
590 | uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | ||
591 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
592 | random_nonce(nonce); | ||
593 | |||
594 | memcpy(plain, &ping_id, sizeof(ping_id)); | ||
595 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); | ||
596 | |||
597 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, | ||
598 | sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); | ||
599 | |||
600 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) | ||
601 | { | ||
602 | return -1; | ||
603 | } | ||
604 | |||
537 | data[0] = 3; | 605 | data[0] = 3; |
538 | 606 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | |
539 | memcpy(data + 1, &ping_id, 4); | 607 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
540 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 608 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
541 | memcpy(data + 5 + CLIENT_ID_SIZE, nodes_list, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | 609 | |
542 | 610 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | |
543 | return sendpacket(ip_port, data, 5 + CLIENT_ID_SIZE + num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | ||
544 | 611 | ||
545 | } | 612 | } |
546 | 613 | ||
@@ -550,26 +617,32 @@ int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id) | |||
550 | //Packet handling functions | 617 | //Packet handling functions |
551 | //One to handle each types of packets we receive | 618 | //One to handle each types of packets we receive |
552 | //return 0 if handled correctly, 1 if packet is bad. | 619 | //return 0 if handled correctly, 1 if packet is bad. |
553 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested | 620 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) |
554 | { | 621 | { |
555 | if(length != 5 + CLIENT_ID_SIZE) | 622 | uint64_t ping_id; |
623 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | ||
624 | { | ||
625 | return 1; | ||
626 | } | ||
627 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. | ||
556 | { | 628 | { |
557 | return 1; | 629 | return 1; |
558 | } | 630 | } |
559 | 631 | ||
560 | uint32_t ping_id; | ||
561 | 632 | ||
562 | memcpy(&ping_id, packet + 1, 4); | ||
563 | IP_Port bad_ip = {{{0}}, 0}; | ||
564 | 633 | ||
565 | if(is_pinging(bad_ip, ping_id))//check if packet is from ourself. | 634 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
635 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
636 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | ||
637 | if(len != sizeof(ping_id)) | ||
566 | { | 638 | { |
567 | return 1; | 639 | return 1; |
568 | } | 640 | } |
641 | |||
569 | 642 | ||
570 | pingres(source, ping_id); | 643 | pingres(source, packet + 1, ping_id); |
571 | 644 | ||
572 | pingreq(source); | 645 | pingreq(source, packet + 1);//TODO: make this smarter? |
573 | 646 | ||
574 | return 0; | 647 | return 0; |
575 | 648 | ||
@@ -577,16 +650,29 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested | |||
577 | 650 | ||
578 | int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) | 651 | int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) |
579 | { | 652 | { |
580 | if(length != (5 + CLIENT_ID_SIZE)) | 653 | uint64_t ping_id; |
654 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | ||
655 | { | ||
656 | return 1; | ||
657 | } | ||
658 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. | ||
659 | { | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | |||
664 | |||
665 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | ||
666 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
667 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | ||
668 | if(len != sizeof(ping_id)) | ||
581 | { | 669 | { |
582 | return 1; | 670 | return 1; |
583 | } | 671 | } |
584 | uint32_t ping_id; | ||
585 | 672 | ||
586 | memcpy(&ping_id, packet + 1, 4); | ||
587 | if(is_pinging(source, ping_id)) | 673 | if(is_pinging(source, ping_id)) |
588 | { | 674 | { |
589 | addto_lists(source, packet + 5); | 675 | addto_lists(source, packet + 1); |
590 | return 0; | 676 | return 0; |
591 | } | 677 | } |
592 | return 1; | 678 | return 1; |
@@ -595,53 +681,80 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) | |||
595 | 681 | ||
596 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | 682 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) |
597 | { | 683 | { |
598 | if(length != (5 + CLIENT_ID_SIZE*2)) | 684 | uint64_t ping_id; |
685 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | ||
599 | { | 686 | { |
600 | return 1; | 687 | return 1; |
601 | } | 688 | } |
602 | uint32_t ping_id; | 689 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)//check if packet is from ourself. |
603 | memcpy(&ping_id, packet + 1, 4); | 690 | { |
604 | sendnodes(source, packet + 5 + CLIENT_ID_SIZE, ping_id); | 691 | return 1; |
692 | } | ||
693 | |||
694 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | ||
605 | 695 | ||
606 | IP_Port bad_ip = {{{0}}, 0}; | 696 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
697 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
698 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); | ||
607 | 699 | ||
608 | if(is_gettingnodes(bad_ip, ping_id))//check if packet is from ourself. | 700 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE) |
609 | { | 701 | { |
610 | return 1; | 702 | return 1; |
611 | } | 703 | } |
612 | 704 | ||
613 | pingreq(source); | 705 | |
706 | memcpy(&ping_id, plain, sizeof(ping_id)); | ||
707 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | ||
708 | |||
709 | pingreq(source, packet + 1);//TODO: make this smarter? | ||
614 | 710 | ||
615 | return 0; | 711 | return 0; |
616 | 712 | ||
617 | } | 713 | } |
618 | 714 | ||
619 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)//tested | 715 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) |
620 | { | 716 | { |
621 | if(length > (5 + CLIENT_ID_SIZE + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port))) || | 717 | uint64_t ping_id; |
622 | (length - 5 - CLIENT_ID_SIZE) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0) | 718 | if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
719 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || | ||
720 | (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
721 | + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || | ||
722 | length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | ||
723 | + sizeof(Node_format) + ENCRYPTION_PADDING) | ||
623 | { | 724 | { |
624 | return 1; | 725 | return 1; |
625 | } | 726 | } |
626 | uint32_t num_nodes = (length - 5 - CLIENT_ID_SIZE) / (CLIENT_ID_SIZE + sizeof(IP_Port)); | 727 | uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
627 | uint32_t i; | 728 | + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); |
628 | uint32_t ping_id; | 729 | |
730 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | ||
731 | |||
732 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | ||
733 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
734 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); | ||
629 | 735 | ||
630 | memcpy(&ping_id, packet + 1, 4); | 736 | |
737 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) | ||
738 | { | ||
739 | return 1; | ||
740 | } | ||
741 | |||
742 | memcpy(&ping_id, plain, sizeof(ping_id)); | ||
631 | if(!is_gettingnodes(source, ping_id)) | 743 | if(!is_gettingnodes(source, ping_id)) |
632 | { | 744 | { |
633 | return 1; | 745 | return 1; |
634 | } | 746 | } |
635 | 747 | ||
636 | Node_format nodes_list[MAX_SENT_NODES]; | 748 | Node_format nodes_list[MAX_SENT_NODES]; |
637 | memcpy(nodes_list, packet + 5 + CLIENT_ID_SIZE, num_nodes * (CLIENT_ID_SIZE + sizeof(IP_Port))); | 749 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
638 | 750 | ||
751 | uint32_t i; | ||
639 | for(i = 0; i < num_nodes; i++) | 752 | for(i = 0; i < num_nodes; i++) |
640 | { | 753 | { |
641 | pingreq(nodes_list[i].ip_port); | 754 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); |
642 | } | 755 | } |
643 | 756 | ||
644 | addto_lists(source, packet + 5); | 757 | addto_lists(source, packet + 1); |
645 | return 0; | 758 | return 0; |
646 | 759 | ||
647 | } | 760 | } |
@@ -772,7 +885,7 @@ void doDHTFriends() | |||
772 | { | 885 | { |
773 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) | 886 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) |
774 | { | 887 | { |
775 | pingreq(friends_list[i].client_list[j].ip_port); | 888 | pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); |
776 | friends_list[i].client_list[j].last_pinged = temp_time; | 889 | friends_list[i].client_list[j].last_pinged = temp_time; |
777 | } | 890 | } |
778 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. | 891 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. |
@@ -786,7 +899,8 @@ void doDHTFriends() | |||
786 | { | 899 | { |
787 | rand_node = rand() % num_nodes; | 900 | rand_node = rand() % num_nodes; |
788 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, | 901 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, |
789 | friends_list[i].client_list[index[rand_node]].client_id); | 902 | friends_list[i].client_list[index[rand_node]].client_id, |
903 | friends_list[i].client_id); | ||
790 | friend_lastgetnode[i] = temp_time; | 904 | friend_lastgetnode[i] = temp_time; |
791 | } | 905 | } |
792 | } | 906 | } |
@@ -810,7 +924,7 @@ void doClose()//tested | |||
810 | { | 924 | { |
811 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) | 925 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) |
812 | { | 926 | { |
813 | pingreq(close_clientlist[i].ip_port); | 927 | pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); |
814 | close_clientlist[i].last_pinged = temp_time; | 928 | close_clientlist[i].last_pinged = temp_time; |
815 | } | 929 | } |
816 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. | 930 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)//if node is good. |
@@ -825,7 +939,8 @@ void doClose()//tested | |||
825 | { | 939 | { |
826 | rand_node = rand() % num_nodes; | 940 | rand_node = rand() % num_nodes; |
827 | getnodes(close_clientlist[index[rand_node]].ip_port, | 941 | getnodes(close_clientlist[index[rand_node]].ip_port, |
828 | close_clientlist[index[rand_node]].client_id); | 942 | close_clientlist[index[rand_node]].client_id, |
943 | self_public_key); | ||
829 | close_lastgetnodes = temp_time; | 944 | close_lastgetnodes = temp_time; |
830 | } | 945 | } |
831 | 946 | ||
@@ -842,10 +957,10 @@ void doDHT() | |||
842 | 957 | ||
843 | 958 | ||
844 | 959 | ||
845 | void DHT_bootstrap(IP_Port ip_port) | 960 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) |
846 | { | 961 | { |
847 | 962 | ||
848 | getnodes(ip_port, self_client_id); | 963 | getnodes(ip_port, public_key, self_public_key); |
849 | 964 | ||
850 | } | 965 | } |
851 | 966 | ||
@@ -26,13 +26,13 @@ | |||
26 | #ifndef DHT_H | 26 | #ifndef DHT_H |
27 | #define DHT_H | 27 | #define DHT_H |
28 | 28 | ||
29 | #include "network.h" | 29 | #include "net_crypto.h" |
30 | 30 | ||
31 | //Current time, unix format | 31 | //Current time, unix format |
32 | #define unix_time() ((uint32_t)time(NULL)) | 32 | #define unix_time() ((uint32_t)time(NULL)) |
33 | 33 | ||
34 | //size of the client_id in bytes | 34 | //size of the client_id in bytes |
35 | #define CLIENT_ID_SIZE 32 | 35 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES |
36 | 36 | ||
37 | 37 | ||
38 | 38 | ||
@@ -68,18 +68,14 @@ void doDHT(); | |||
68 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); | 68 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); |
69 | 69 | ||
70 | //Use this function to bootstrap the client | 70 | //Use this function to bootstrap the client |
71 | //Sends a get nodes request to the given ip port | 71 | //Sends a get nodes request to the given node with ip port and public_key |
72 | void DHT_bootstrap(IP_Port ip_port); | 72 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key); |
73 | 73 | ||
74 | 74 | ||
75 | //TODO: | 75 | //TODO: |
76 | //Add functions to save and load the state(client list, friends list) | 76 | //Add functions to save and load the state(client list, friends list) |
77 | 77 | ||
78 | 78 | ||
79 | //Global variables | ||
80 | |||
81 | //Our client id | ||
82 | extern uint8_t self_client_id[CLIENT_ID_SIZE]; | ||
83 | 79 | ||
84 | 80 | ||
85 | 81 | ||
diff --git a/core/Messenger.c b/core/Messenger.c index 57bc50e2..8236c117 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -42,10 +42,10 @@ typedef struct | |||
42 | 42 | ||
43 | #define MAX_NUM_FRIENDS 256 | 43 | #define MAX_NUM_FRIENDS 256 |
44 | 44 | ||
45 | Friend friendlist[MAX_NUM_FRIENDS]; | 45 | static Friend friendlist[MAX_NUM_FRIENDS]; |
46 | 46 | ||
47 | 47 | ||
48 | uint32_t numfriends; | 48 | static uint32_t numfriends; |
49 | 49 | ||
50 | 50 | ||
51 | //return the friend id associated to that public key. | 51 | //return the friend id associated to that public key. |
@@ -189,7 +189,7 @@ int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | 191 | ||
192 | void (*friend_request)(uint8_t *, uint8_t *, uint16_t); | 192 | static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); |
193 | 193 | ||
194 | //set the function that will be executed when a friend request is received. | 194 | //set the function that will be executed when a friend request is received. |
195 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) | 195 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) |
@@ -198,7 +198,7 @@ void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) | |||
198 | } | 198 | } |
199 | 199 | ||
200 | 200 | ||
201 | void (*friend_message)(int, uint8_t *, uint16_t); | 201 | static void (*friend_message)(int, uint8_t *, uint16_t); |
202 | 202 | ||
203 | //set the function that will be executed when a message from a friend is received. | 203 | //set the function that will be executed when a message from a friend is received. |
204 | void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)) | 204 | void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)) |
@@ -216,11 +216,10 @@ void initMessenger() | |||
216 | IP ip; | 216 | IP ip; |
217 | ip.i = 0; | 217 | ip.i = 0; |
218 | init_networking(ip, PORT); | 218 | init_networking(ip, PORT); |
219 | memcpy(self_client_id, self_public_key, crypto_box_PUBLICKEYBYTES); | ||
220 | 219 | ||
221 | } | 220 | } |
222 | 221 | ||
223 | void doFriends() | 222 | static void doFriends() |
224 | {//TODO: add incoming connections and some other stuff. | 223 | {//TODO: add incoming connections and some other stuff. |
225 | uint32_t i; | 224 | uint32_t i; |
226 | int len; | 225 | int len; |
@@ -280,7 +279,7 @@ void doFriends() | |||
280 | } | 279 | } |
281 | } | 280 | } |
282 | 281 | ||
283 | void doFriendRequest() | 282 | static void doFriendRequest() |
284 | { | 283 | { |
285 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 284 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
286 | uint8_t temp[MAX_DATA_SIZE]; | 285 | uint8_t temp[MAX_DATA_SIZE]; |
@@ -296,7 +295,7 @@ void doFriendRequest() | |||
296 | 295 | ||
297 | 296 | ||
298 | 297 | ||
299 | void doInbound() | 298 | static void doInbound() |
300 | { | 299 | { |
301 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 300 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
302 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 301 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
diff --git a/core/net_crypto.c b/core/net_crypto.c index 0bae2d2e..2af5239b 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -50,17 +50,17 @@ typedef struct | |||
50 | 50 | ||
51 | #define MAX_CRYPTO_CONNECTIONS 256 | 51 | #define MAX_CRYPTO_CONNECTIONS 256 |
52 | 52 | ||
53 | Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; | 53 | static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; |
54 | 54 | ||
55 | #define MAX_FRIEND_REQUESTS 32 | 55 | #define MAX_FRIEND_REQUESTS 32 |
56 | 56 | ||
57 | //keeps track of the connection numbers for friends request so we can check later if they were sent | 57 | //keeps track of the connection numbers for friends request so we can check later if they were sent |
58 | int outbound_friendrequests[MAX_FRIEND_REQUESTS]; | 58 | static int outbound_friendrequests[MAX_FRIEND_REQUESTS]; |
59 | 59 | ||
60 | #define MAX_INCOMING 64 | 60 | #define MAX_INCOMING 64 |
61 | 61 | ||
62 | //keeps track of the connection numbers for friends request so we can check later if they were sent | 62 | //keeps track of the connection numbers for friends request so we can check later if they were sent |
63 | int incoming_connections[MAX_INCOMING]; | 63 | static int incoming_connections[MAX_INCOMING]; |
64 | 64 | ||
65 | //encrypts plain of length length to encrypted of length + 16 using the | 65 | //encrypts plain of length length to encrypted of length + 16 using the |
66 | //public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 66 | //public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
@@ -587,7 +587,7 @@ int new_incoming(int id) | |||
587 | 587 | ||
588 | //TODO: optimize this | 588 | //TODO: optimize this |
589 | //handle all new incoming connections. | 589 | //handle all new incoming connections. |
590 | void handle_incomings() | 590 | static void handle_incomings() |
591 | { | 591 | { |
592 | int income; | 592 | int income; |
593 | while(1) | 593 | while(1) |
@@ -601,7 +601,7 @@ void handle_incomings() | |||
601 | } | 601 | } |
602 | 602 | ||
603 | //handle received packets for not yet established crypto connections. | 603 | //handle received packets for not yet established crypto connections. |
604 | void receive_crypto() | 604 | static void receive_crypto() |
605 | { | 605 | { |
606 | uint32_t i; | 606 | uint32_t i; |
607 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) | 607 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
@@ -687,7 +687,7 @@ void initNetCrypto() | |||
687 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); | 687 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); |
688 | } | 688 | } |
689 | 689 | ||
690 | void killTimedout() | 690 | static void killTimedout() |
691 | { | 691 | { |
692 | uint32_t i; | 692 | uint32_t i; |
693 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) | 693 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) |
diff --git a/core/net_crypto.h b/core/net_crypto.h index fe655c92..4c3b53de 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -32,8 +32,9 @@ | |||
32 | #endif | 32 | #endif |
33 | //Our public key. | 33 | //Our public key. |
34 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 34 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; |
35 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
35 | 36 | ||
36 | 37 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) | |
37 | 38 | ||
38 | //encrypts plain of length length to encrypted of length + 16 using the | 39 | //encrypts plain of length length to encrypted of length + 16 using the |
39 | //public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 40 | //public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
@@ -51,6 +52,10 @@ int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, | |||
51 | uint8_t * encrypted, uint32_t length, uint8_t * plain); | 52 | uint8_t * encrypted, uint32_t length, uint8_t * plain); |
52 | 53 | ||
53 | 54 | ||
55 | //fill the given nonce with random bytes. | ||
56 | void random_nonce(uint8_t * nonce); | ||
57 | |||
58 | |||
54 | //return 0 if there is no received data in the buffer | 59 | //return 0 if there is no received data in the buffer |
55 | //return -1 if the packet was discarded. | 60 | //return -1 if the packet was discarded. |
56 | //return length of received data if successful | 61 | //return length of received data if successful |
diff --git a/core/network.h b/core/network.h index 894bedeb..4fa30905 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -39,8 +39,7 @@ | |||
39 | #include <winsock2.h> | 39 | #include <winsock2.h> |
40 | #include <windows.h> | 40 | #include <windows.h> |
41 | 41 | ||
42 | //we use libsodium (Portable version of NaCl) because stock NaCl doesn't compile on windows. | 42 | #undef VANILLA_NACL//make sure on windows we use libsodium |
43 | #include <sodium.h> | ||
44 | 43 | ||
45 | #else //Linux includes | 44 | #else //Linux includes |
46 | 45 | ||
@@ -50,13 +49,21 @@ | |||
50 | #include <errno.h> | 49 | #include <errno.h> |
51 | #include <sys/time.h> | 50 | #include <sys/time.h> |
52 | 51 | ||
52 | |||
53 | #endif | ||
54 | |||
55 | #ifndef VANILLA_NACL | ||
56 | //we use libsodium by default | ||
57 | #include <sodium.h> | ||
58 | #else | ||
59 | |||
53 | //TODO: Including stuff like this is bad. This needs fixing. | 60 | //TODO: Including stuff like this is bad. This needs fixing. |
54 | //We keep support for the original NaCl for now on UNIX like Operating Systems. | 61 | //We keep support for the original NaCl for now. |
55 | //Commented out for now | 62 | #include "../nacl/build/Linux/include/amd64/crypto_box.h" |
56 | //#include "../nacl/build/Linux/include/amd64/crypto_box.h" | ||
57 | 63 | ||
58 | #endif | 64 | #endif |
59 | 65 | ||
66 | |||
60 | #define MAX_UDP_PACKET_SIZE 65507 | 67 | #define MAX_UDP_PACKET_SIZE 65507 |
61 | 68 | ||
62 | typedef union | 69 | typedef union |
diff --git a/docs/DHT.txt b/docs/DHT.txt index 486aa38c..088f34ee 100644 --- a/docs/DHT.txt +++ b/docs/DHT.txt | |||
@@ -2,7 +2,7 @@ DHT protocol: | |||
2 | Follows pretty much the principle of the torrent DHT: http://www.bittorrent.org/beps/bep_0005.html (READ IT) | 2 | Follows pretty much the principle of the torrent DHT: http://www.bittorrent.org/beps/bep_0005.html (READ IT) |
3 | 3 | ||
4 | But: | 4 | But: |
5 | Vastly simplified packet format. | 5 | Vastly simplified packet format and encryption. |
6 | 6 | ||
7 | Boostrapping: | 7 | Boostrapping: |
8 | The first time you install the client we bootstrap it with a node on our servers.(bandwidth should not be a problem as the client only needs to be sent one reply.) | 8 | The first time you install the client we bootstrap it with a node on our servers.(bandwidth should not be a problem as the client only needs to be sent one reply.) |
@@ -75,13 +75,12 @@ DHT protocol: | |||
75 | 75 | ||
76 | Valid queries and Responses: | 76 | Valid queries and Responses: |
77 | 77 | ||
78 | Ping(Request and response): [byte with value: 00 for request, 01 for response][random 4 byte (ping_id)][char array (client node_id), length=32 bytes] | 78 | Ping(Request and response): [byte with value: 00 for request, 01 for response][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender: [random 8 byte (ping_id)]] |
79 | ping_id = a random integer, the response must contain the exact same number as the request | 79 | ping_id = a random integer, the response must contain the exact same number as the request |
80 | 80 | ||
81 | 81 | ||
82 | Get nodes (Request): | 82 | Get nodes (Request): |
83 | Packet contents: [byte with value: 02][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][char array: requested_node_id (node_id of which we want the ip), length=32 bytes] | 83 | Packet contents: [byte with value: 02][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[random 8 byte (ping_id)][char array: requested_node_id (node_id of which we want the ip), length=32 bytes]] |
84 | Valid replies: a send_nodes packet | 84 | Valid replies: a send_nodes packet |
85 | 85 | ||
86 | Send_nodes (response): [byte with value: 03][random 4 byte (ping_id)][char array (client node_id), length=32 bytes][Nodes in node format, length=40 * (number of nodes (maximum of 8 nodes)) bytes] | 86 | Send_nodes (response): [byte with value: 03][char array (client node_id), length=32 bytes][random 24 byte nonce][Encrypted with the nonce and private key of the sender:[random 8 byte (ping_id)][Nodes in node format, length=40 * (number of nodes (maximum of 8 nodes)) bytes]] |
87 | ex: 03[Node][Node][Node] \ No newline at end of file | ||
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 38ca4992..083e4d4b 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -3,10 +3,12 @@ | |||
3 | * | 3 | * |
4 | * Compile with: gcc -O2 -Wall -o test ../core/network.c DHT_test.c | 4 | * Compile with: gcc -O2 -Wall -o test ../core/network.c DHT_test.c |
5 | * | 5 | * |
6 | * Command line arguments are the ip and port of a node and the client_id (32 bytes) of the friend you want to find the ip_port of | 6 | * Command line arguments are the ip, port and public key of a node. |
7 | * EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef | 7 | * EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
8 | * | ||
9 | * The test will then ask you for the id (in hex format) of the friend you wish to add | ||
8 | */ | 10 | */ |
9 | #include "../core/network.h" | 11 | //#include "../core/network.h" |
10 | #include "../core/DHT.c" | 12 | #include "../core/DHT.c" |
11 | 13 | ||
12 | #include <string.h> | 14 | #include <string.h> |
@@ -94,15 +96,44 @@ void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) | |||
94 | printf("\n--------------------END-----------------------------\n\n\n"); | 96 | printf("\n--------------------END-----------------------------\n\n\n"); |
95 | } | 97 | } |
96 | 98 | ||
99 | //horrible function from one of my first C programs. | ||
100 | //only here because I was too lazy to write a proper one. | ||
101 | unsigned char * hex_string_to_bin(char hex_string[]) | ||
102 | { | ||
103 | unsigned char * val = malloc(strlen(hex_string)); | ||
104 | char * pos = hex_string; | ||
105 | int i=0; | ||
106 | while(i < strlen(hex_string)) | ||
107 | { | ||
108 | sscanf(pos,"%2hhx",&val[i]); | ||
109 | pos+=2; | ||
110 | i++; | ||
111 | } | ||
112 | return val; | ||
113 | } | ||
114 | |||
97 | int main(int argc, char *argv[]) | 115 | int main(int argc, char *argv[]) |
98 | { | 116 | { |
99 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); | 117 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); |
100 | 118 | ||
101 | if (argc < 4) { | 119 | if (argc < 4) { |
102 | printf("usage %s ip port client_id(of friend to find ip_port of)\n", argv[0]); | 120 | printf("usage %s ip port public_key\n", argv[0]); |
103 | exit(0); | 121 | exit(0); |
104 | } | 122 | } |
105 | DHT_addfriend((uint8_t *)argv[3]); | 123 | new_keys(); |
124 | printf("OUR ID: "); | ||
125 | uint32_t i; | ||
126 | for(i = 0; i < 32; i++) | ||
127 | { | ||
128 | if(self_public_key[i] < 16) | ||
129 | printf("0"); | ||
130 | printf("%hhX",self_public_key[i]); | ||
131 | } | ||
132 | |||
133 | char temp_id[128]; | ||
134 | printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); | ||
135 | scanf("%s", temp_id); | ||
136 | DHT_addfriend(hex_string_to_bin(temp_id)); | ||
106 | 137 | ||
107 | //initialize networking | 138 | //initialize networking |
108 | //bind to ip 0.0.0.0:PORT | 139 | //bind to ip 0.0.0.0:PORT |
@@ -110,8 +141,7 @@ int main(int argc, char *argv[]) | |||
110 | ip.i = 0; | 141 | ip.i = 0; |
111 | init_networking(ip, PORT); | 142 | init_networking(ip, PORT); |
112 | 143 | ||
113 | int randdomnum = random_int(); | 144 | |
114 | memcpy(self_client_id, &randdomnum, 4); | ||
115 | 145 | ||
116 | 146 | ||
117 | perror("Initialization"); | 147 | perror("Initialization"); |
@@ -122,7 +152,7 @@ int main(int argc, char *argv[]) | |||
122 | //bootstrap_ip_port.ip.c[2] = 0; | 152 | //bootstrap_ip_port.ip.c[2] = 0; |
123 | //bootstrap_ip_port.ip.c[3] = 1; | 153 | //bootstrap_ip_port.ip.c[3] = 1; |
124 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | 154 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); |
125 | DHT_bootstrap(bootstrap_ip_port); | 155 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); |
126 | 156 | ||
127 | IP_Port ip_port; | 157 | IP_Port ip_port; |
128 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 158 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 6b0e56fc..c049aa18 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * If it recieves a message from a friend it replies back. | 7 | * If it recieves a message from a friend it replies back. |
8 | * | 8 | * |
9 | * | 9 | * |
10 | * This is how I compile it: gcc -O2 -Wall -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/DHT.c ../core/Messenger.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/* Messenger_test.c | 10 | * This is how I compile it: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} Messenger_test.c |
11 | * | 11 | * |
12 | * | 12 | * |
13 | * Command line arguments are the ip and port of a node (for bootstrapping). | 13 | * Command line arguments are the ip and port of a node (for bootstrapping). |
@@ -77,8 +77,8 @@ void print_message(int friendnumber, uint8_t * string, uint16_t length) | |||
77 | 77 | ||
78 | int main(int argc, char *argv[]) | 78 | int main(int argc, char *argv[]) |
79 | { | 79 | { |
80 | if (argc < 3) { | 80 | if (argc < 4) { |
81 | printf("usage %s ip port (of the DHT bootstrap node)\n", argv[0]); | 81 | printf("usage %s ip port public_key (of the DHT bootstrap node)\n", argv[0]); |
82 | exit(0); | 82 | exit(0); |
83 | } | 83 | } |
84 | initMessenger(); | 84 | initMessenger(); |
@@ -96,14 +96,17 @@ int main(int argc, char *argv[]) | |||
96 | 96 | ||
97 | char temp_id[128]; | 97 | char temp_id[128]; |
98 | printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); | 98 | printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); |
99 | scanf("%s", temp_id); | 99 | if(scanf("%s", temp_id) != 1) |
100 | { | ||
101 | return 1; | ||
102 | } | ||
100 | int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); | 103 | int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); |
101 | 104 | ||
102 | perror("Initialization"); | 105 | perror("Initialization"); |
103 | IP_Port bootstrap_ip_port; | 106 | IP_Port bootstrap_ip_port; |
104 | bootstrap_ip_port.port = htons(atoi(argv[2])); | 107 | bootstrap_ip_port.port = htons(atoi(argv[2])); |
105 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | 108 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); |
106 | DHT_bootstrap(bootstrap_ip_port); | 109 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); |
107 | 110 | ||
108 | while(1) | 111 | while(1) |
109 | { | 112 | { |