diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 142 | ||||
-rw-r--r-- | core/DHT.h | 2 | ||||
-rw-r--r-- | core/LAN_discovery.c | 4 | ||||
-rw-r--r-- | core/Messenger.c | 6 | ||||
-rw-r--r-- | core/packets.h | 37 | ||||
-rw-r--r-- | core/ping.c | 127 | ||||
-rw-r--r-- | core/ping.h | 5 | ||||
-rw-r--r-- | core/util.c | 13 | ||||
-rw-r--r-- | core/util.h | 3 |
9 files changed, 198 insertions, 141 deletions
@@ -24,6 +24,7 @@ | |||
24 | /*----------------------------------------------------------------------------------*/ | 24 | /*----------------------------------------------------------------------------------*/ |
25 | 25 | ||
26 | #include "DHT.h" | 26 | #include "DHT.h" |
27 | #include "packets.h" | ||
27 | #include "ping.h" | 28 | #include "ping.h" |
28 | 29 | ||
29 | /* maximum number of clients stored per friend. */ | 30 | /* maximum number of clients stored per friend. */ |
@@ -351,7 +352,7 @@ static int replace_good( Client_data * list, | |||
351 | /* Attempt to add client with ip_port and client_id to the friends client list | 352 | /* Attempt to add client with ip_port and client_id to the friends client list |
352 | * and close_clientlist | 353 | * and close_clientlist |
353 | */ | 354 | */ |
354 | static void addto_lists(IP_Port ip_port, uint8_t * client_id) | 355 | void addto_lists(IP_Port ip_port, uint8_t * client_id) |
355 | { | 356 | { |
356 | uint32_t i; | 357 | uint32_t i; |
357 | 358 | ||
@@ -472,71 +473,6 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
472 | return 0; | 473 | return 0; |
473 | } | 474 | } |
474 | 475 | ||
475 | /* send a ping request, only works if none has been sent to that ip/port | ||
476 | * in the last 5 seconds. | ||
477 | */ | ||
478 | static int pingreq(IP_Port ip_port, uint8_t * public_key) | ||
479 | { | ||
480 | /* check if packet is gonna be sent to ourself */ | ||
481 | if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0)) | ||
482 | return 1; | ||
483 | |||
484 | uint64_t ping_id = add_ping(ip_port); | ||
485 | if(ping_id == 0) | ||
486 | return 1; | ||
487 | |||
488 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; | ||
489 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; | ||
490 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
491 | random_nonce(nonce); | ||
492 | |||
493 | int len = encrypt_data( public_key, | ||
494 | self_secret_key, | ||
495 | nonce, | ||
496 | (uint8_t *)&ping_id, | ||
497 | sizeof(ping_id), | ||
498 | encrypt ); | ||
499 | |||
500 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
501 | return -1; | ||
502 | |||
503 | data[0] = 0; | ||
504 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | ||
505 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
506 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
507 | |||
508 | return sendpacket(ip_port, data, sizeof(data)); | ||
509 | } | ||
510 | |||
511 | /* send a ping response */ | ||
512 | static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) | ||
513 | { | ||
514 | /* check if packet is gonna be sent to ourself */ | ||
515 | if(id_equal(public_key, self_public_key)) | ||
516 | return 1; | ||
517 | |||
518 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING]; | ||
519 | uint8_t encrypt[sizeof(ping_id) + ENCRYPTION_PADDING]; | ||
520 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
521 | random_nonce(nonce); | ||
522 | |||
523 | int len = encrypt_data( public_key, | ||
524 | self_secret_key, nonce, | ||
525 | (uint8_t *)&ping_id, | ||
526 | sizeof(ping_id), | ||
527 | encrypt ); | ||
528 | |||
529 | if(len != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
530 | return -1; | ||
531 | |||
532 | data[0] = 1; | ||
533 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | ||
534 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
535 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
536 | |||
537 | return sendpacket(ip_port, data, sizeof(data)); | ||
538 | } | ||
539 | |||
540 | /* send a getnodes request */ | 476 | /* send a getnodes request */ |
541 | static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) | 477 | static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) |
542 | { | 478 | { |
@@ -618,62 +554,6 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, | |||
618 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 554 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
619 | } | 555 | } |
620 | 556 | ||
621 | /* Packet handling functions, one to handle each types of packets we receive | ||
622 | * Returns 0 if handled correctly, 1 if packet is bad. | ||
623 | */ | ||
624 | static int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) | ||
625 | { | ||
626 | uint64_t ping_id; | ||
627 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | ||
628 | return 1; | ||
629 | |||
630 | /* check if packet is from ourself. */ | ||
631 | if(id_equal(packet + 1, self_public_key)) | ||
632 | return 1; | ||
633 | |||
634 | int len = decrypt_data( packet + 1, | ||
635 | self_secret_key, | ||
636 | packet + 1 + CLIENT_ID_SIZE, | ||
637 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
638 | sizeof(ping_id) + ENCRYPTION_PADDING, | ||
639 | (uint8_t *)&ping_id ); | ||
640 | |||
641 | if(len != sizeof(ping_id)) | ||
642 | return 1; | ||
643 | |||
644 | pingres(source, packet + 1, ping_id); | ||
645 | pingreq(source, packet + 1); /* TODO: make this smarter? */ | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) | ||
651 | { | ||
652 | uint64_t ping_id; | ||
653 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | ||
654 | return 1; | ||
655 | |||
656 | /* check if packet is from ourself. */ | ||
657 | if(id_equal(packet + 1, self_public_key)) | ||
658 | return 1; | ||
659 | |||
660 | int len = decrypt_data( packet + 1, | ||
661 | self_secret_key, | ||
662 | packet + 1 + CLIENT_ID_SIZE, | ||
663 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | ||
664 | sizeof(ping_id) + ENCRYPTION_PADDING, | ||
665 | (uint8_t *)&ping_id ); | ||
666 | |||
667 | if(len != sizeof(ping_id)) | ||
668 | return 1; | ||
669 | |||
670 | if(is_pinging(source, ping_id)) { | ||
671 | addto_lists(source, packet + 1); | ||
672 | return 0; | ||
673 | } | ||
674 | return 1; | ||
675 | } | ||
676 | |||
677 | static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | 557 | static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) |
678 | { | 558 | { |
679 | uint64_t ping_id; | 559 | uint64_t ping_id; |
@@ -701,7 +581,7 @@ static int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
701 | memcpy(&ping_id, plain, sizeof(ping_id)); | 581 | memcpy(&ping_id, plain, sizeof(ping_id)); |
702 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | 582 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); |
703 | 583 | ||
704 | pingreq(source, packet + 1); /* TODO: make this smarter? */ | 584 | send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ |
705 | 585 | ||
706 | return 0; | 586 | return 0; |
707 | } | 587 | } |
@@ -741,7 +621,7 @@ static int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
741 | 621 | ||
742 | uint32_t i; | 622 | uint32_t i; |
743 | for(i = 0; i < num_nodes; ++i) { | 623 | for(i = 0; i < num_nodes; ++i) { |
744 | pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); | 624 | send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id); |
745 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 625 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
746 | } | 626 | } |
747 | 627 | ||
@@ -831,8 +711,8 @@ static void doDHTFriends(void) | |||
831 | /* if node is not dead. */ | 711 | /* if node is not dead. */ |
832 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { | 712 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { |
833 | if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 713 | if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
834 | pingreq( friends_list[i].client_list[j].ip_port, | 714 | send_ping_request( friends_list[i].client_list[j].ip_port, |
835 | friends_list[i].client_list[j].client_id ); | 715 | (clientid_t*) &friends_list[i].client_list[j].client_id ); |
836 | friends_list[i].client_list[j].last_pinged = temp_time; | 716 | friends_list[i].client_list[j].last_pinged = temp_time; |
837 | } | 717 | } |
838 | /* if node is good. */ | 718 | /* if node is good. */ |
@@ -869,8 +749,8 @@ static void doClose(void) | |||
869 | /* if node is not dead. */ | 749 | /* if node is not dead. */ |
870 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { | 750 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { |
871 | if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 751 | if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
872 | pingreq( close_clientlist[i].ip_port, | 752 | send_ping_request( close_clientlist[i].ip_port, |
873 | close_clientlist[i].client_id ); | 753 | (clientid_t*) &close_clientlist[i].client_id ); |
874 | close_clientlist[i].last_pinged = temp_time; | 754 | close_clientlist[i].last_pinged = temp_time; |
875 | } | 755 | } |
876 | /* if node is good. */ | 756 | /* if node is good. */ |
@@ -1151,7 +1031,7 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t | |||
1151 | /*TODO: improve port guessing algorithm*/ | 1031 | /*TODO: improve port guessing algorithm*/ |
1152 | uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); | 1032 | uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); |
1153 | IP_Port pinging = {ip, htons(port)}; | 1033 | IP_Port pinging = {ip, htons(port)}; |
1154 | pingreq(pinging, friends_list[friend_num].client_id); | 1034 | send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id); |
1155 | } | 1035 | } |
1156 | friends_list[friend_num].punching_index = i; | 1036 | friends_list[friend_num].punching_index = i; |
1157 | } | 1037 | } |
@@ -1198,10 +1078,10 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | |||
1198 | { | 1078 | { |
1199 | switch (packet[0]) { | 1079 | switch (packet[0]) { |
1200 | case 0: | 1080 | case 0: |
1201 | return handle_pingreq(packet, length, source); | 1081 | return handle_ping_request(packet, length, source); |
1202 | 1082 | ||
1203 | case 1: | 1083 | case 1: |
1204 | return handle_pingres(packet, length, source); | 1084 | return handle_ping_response(packet, length, source); |
1205 | 1085 | ||
1206 | case 2: | 1086 | case 2: |
1207 | return handle_getnodes(packet, length, source); | 1087 | return handle_getnodes(packet, length, source); |
@@ -104,6 +104,8 @@ int DHT_load(uint8_t *data, uint32_t size); | |||
104 | returns 1 if we are */ | 104 | returns 1 if we are */ |
105 | int DHT_isconnected(); | 105 | int DHT_isconnected(); |
106 | 106 | ||
107 | void addto_lists(IP_Port ip_port, uint8_t * client_id); | ||
108 | |||
107 | #ifdef __cplusplus | 109 | #ifdef __cplusplus |
108 | } | 110 | } |
109 | #endif | 111 | #endif |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index 55953685..26b3930c 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -70,6 +70,10 @@ static uint32_t get_broadcast(void) | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | close(sock); | 72 | close(sock); |
73 | if(sock_holder == NULL) { | ||
74 | perror("[!] no broadcast device found"); | ||
75 | return 0; | ||
76 | } | ||
73 | 77 | ||
74 | return sock_holder->sin_addr.s_addr; | 78 | return sock_holder->sin_addr.s_addr; |
75 | } | 79 | } |
diff --git a/core/Messenger.c b/core/Messenger.c index d8bf3413..5532c9cc 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -116,7 +116,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
116 | return FAERR_ALREADYSENT; | 116 | return FAERR_ALREADYSENT; |
117 | 117 | ||
118 | uint32_t i; | 118 | uint32_t i; |
119 | for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ | 119 | for (i = 0; i < numfriends && i < MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ |
120 | if(friendlist[i].status == NOFRIEND) { | 120 | if(friendlist[i].status == NOFRIEND) { |
121 | DHT_addfriend(client_id); | 121 | DHT_addfriend(client_id); |
122 | friendlist[i].status = FRIEND_ADDED; | 122 | friendlist[i].status = FRIEND_ADDED; |
@@ -141,7 +141,7 @@ int m_addfriend_norequest(uint8_t * client_id) | |||
141 | if (getfriend_id(client_id) != -1) | 141 | if (getfriend_id(client_id) != -1) |
142 | return -1; | 142 | return -1; |
143 | uint32_t i; | 143 | uint32_t i; |
144 | for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ | 144 | for (i = 0; i < numfriends && i < MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */ |
145 | if(friendlist[i].status == NOFRIEND) { | 145 | if(friendlist[i].status == NOFRIEND) { |
146 | DHT_addfriend(client_id); | 146 | DHT_addfriend(client_id); |
147 | friendlist[i].status = FRIEND_REQUESTED; | 147 | friendlist[i].status = FRIEND_REQUESTED; |
@@ -352,7 +352,7 @@ static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length) | |||
352 | memcpy(thepacket + 2, status, length); | 352 | memcpy(thepacket + 2, status, length); |
353 | thepacket[0] = PACKET_ID_USERSTATUS; | 353 | thepacket[0] = PACKET_ID_USERSTATUS; |
354 | thepacket[1] = self_userstatus_kind; | 354 | thepacket[1] = self_userstatus_kind; |
355 | int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1); | 355 | int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 2); |
356 | free(thepacket); | 356 | free(thepacket); |
357 | return written; | 357 | return written; |
358 | } | 358 | } |
diff --git a/core/packets.h b/core/packets.h new file mode 100644 index 00000000..222b1425 --- /dev/null +++ b/core/packets.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * packet.h -- Packet structure | ||
3 | * | ||
4 | * This file is donated to the Tox Project. | ||
5 | * Copyright 2013 plutooo | ||
6 | */ | ||
7 | |||
8 | typedef struct { | ||
9 | uint8_t id[CLIENT_ID_SIZE]; | ||
10 | |||
11 | } __attribute__((packed)) clientid_t; | ||
12 | |||
13 | typedef enum { | ||
14 | PACKET_PING_REQ = 0, | ||
15 | PACKET_PING_RES = 1 | ||
16 | |||
17 | } packetid_t; | ||
18 | |||
19 | // Ping packet | ||
20 | typedef struct { | ||
21 | uint8_t magic; | ||
22 | clientid_t client_id; | ||
23 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
24 | uint64_t ping_id; | ||
25 | uint8_t padding[ENCRYPTION_PADDING]; | ||
26 | |||
27 | } __attribute__((packed)) pingreq_t; | ||
28 | |||
29 | // Pong packet | ||
30 | typedef struct { | ||
31 | uint8_t magic; | ||
32 | clientid_t client_id; | ||
33 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
34 | uint64_t ping_id; | ||
35 | uint8_t padding[ENCRYPTION_PADDING]; | ||
36 | |||
37 | } __attribute__((packed)) pingres_t; | ||
diff --git a/core/ping.c b/core/ping.c index ffabe221..6a1fbb7e 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -8,6 +8,9 @@ | |||
8 | #include <stdbool.h> | 8 | #include <stdbool.h> |
9 | #include <stdint.h> | 9 | #include <stdint.h> |
10 | 10 | ||
11 | #include "DHT.h" | ||
12 | #include "net_crypto.h" | ||
13 | #include "packets.h" | ||
11 | #include "network.h" | 14 | #include "network.h" |
12 | #include "util.h" | 15 | #include "util.h" |
13 | 16 | ||
@@ -20,10 +23,12 @@ typedef struct { | |||
20 | uint64_t timestamp; | 23 | uint64_t timestamp; |
21 | } pinged_t; | 24 | } pinged_t; |
22 | 25 | ||
23 | static pinged_t pings[PING_NUM_MAX]; | 26 | static pinged_t pings[PING_NUM_MAX]; |
24 | static size_t num_pings; | 27 | static size_t num_pings; |
25 | static size_t pos_pings; | 28 | static size_t pos_pings; |
29 | static clientid_t* self_id = (clientid_t*) &self_public_key; | ||
26 | 30 | ||
31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | ||
27 | 32 | ||
28 | void init_ping() | 33 | void init_ping() |
29 | { | 34 | { |
@@ -51,15 +56,16 @@ static void remove_timeouts() // O(n) | |||
51 | new_num--; | 56 | new_num--; |
52 | } | 57 | } |
53 | // Break here because list is sorted. | 58 | // Break here because list is sorted. |
54 | else | 59 | else { |
55 | break; | 60 | break; |
61 | } | ||
56 | } | 62 | } |
57 | 63 | ||
58 | num_pings = new_num; | 64 | num_pings = new_num; |
59 | pos_pings = new_pos % PING_NUM_MAX; | 65 | pos_pings = new_pos % PING_NUM_MAX; |
60 | } | 66 | } |
61 | 67 | ||
62 | uint64_t add_ping(IP_Port ipp) // O(n) | 68 | uint64_t add_ping(IP_Port ipp) // O(n) |
63 | { | 69 | { |
64 | size_t p; | 70 | size_t p; |
65 | 71 | ||
@@ -94,6 +100,7 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with | |||
94 | for (i=0; i<num_pings; i++) { | 100 | for (i=0; i<num_pings; i++) { |
95 | id = (pos_pings + i) % PING_NUM_MAX; | 101 | id = (pos_pings + i) % PING_NUM_MAX; |
96 | 102 | ||
103 | // ping_id = 0 means match any id | ||
97 | if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { | 104 | if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { |
98 | return true; | 105 | return true; |
99 | } | 106 | } |
@@ -101,3 +108,113 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with | |||
101 | 108 | ||
102 | return false; | 109 | return false; |
103 | } | 110 | } |
111 | |||
112 | int send_ping_request(IP_Port ipp, clientid_t* client_id) | ||
113 | { | ||
114 | pingreq_t pk; | ||
115 | int rc; | ||
116 | uint64_t ping_id; | ||
117 | |||
118 | if (is_pinging(ipp, 0) || id_eq(client_id, self_id)) | ||
119 | return 1; | ||
120 | |||
121 | // Generate random ping_id | ||
122 | ping_id = add_ping(ipp); | ||
123 | |||
124 | pk.magic = PACKET_PING_REQ; | ||
125 | id_cpy(&pk.client_id, self_id); // Our pubkey | ||
126 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce | ||
127 | |||
128 | // Encrypt ping_id using recipient privkey | ||
129 | rc = encrypt_data((uint8_t*) client_id, | ||
130 | self_secret_key, | ||
131 | (uint8_t*) &pk.nonce, | ||
132 | (uint8_t*) &ping_id, sizeof(ping_id), | ||
133 | (uint8_t*) &pk.ping_id); | ||
134 | |||
135 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
136 | return 1; | ||
137 | |||
138 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | ||
139 | } | ||
140 | |||
141 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) | ||
142 | { | ||
143 | pingres_t pk; | ||
144 | int rc; | ||
145 | |||
146 | if (id_eq(client_id, self_id)) | ||
147 | return 1; | ||
148 | |||
149 | pk.magic = PACKET_PING_RES; | ||
150 | id_cpy(&pk.client_id, self_id); // Our pubkey | ||
151 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce | ||
152 | |||
153 | // Encrypt ping_id using recipient privkey | ||
154 | rc = encrypt_data((uint8_t*) client_id, | ||
155 | self_secret_key, | ||
156 | (uint8_t*) &pk.nonce, | ||
157 | (uint8_t*) &ping_id, sizeof(ping_id), | ||
158 | (uint8_t*) &pk.ping_id); | ||
159 | |||
160 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | ||
161 | return 1; | ||
162 | |||
163 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | ||
164 | } | ||
165 | |||
166 | int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source) | ||
167 | { | ||
168 | pingreq_t* p = (pingreq_t*) packet; | ||
169 | int rc; | ||
170 | uint64_t ping_id; | ||
171 | |||
172 | if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id)) | ||
173 | return 1; | ||
174 | |||
175 | // Decrypt ping_id | ||
176 | rc = decrypt_data((uint8_t*) &p->client_id, | ||
177 | self_secret_key, | ||
178 | (uint8_t*) &p->nonce, | ||
179 | (uint8_t*) &p->ping_id, | ||
180 | sizeof(ping_id) + ENCRYPTION_PADDING, | ||
181 | (uint8_t*) &ping_id); | ||
182 | |||
183 | if (rc != sizeof(ping_id)) | ||
184 | return 1; | ||
185 | |||
186 | // Send response | ||
187 | send_ping_response(source, &p->client_id, ping_id); | ||
188 | send_ping_request(source, &p->client_id); // Make this smarter? | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source) | ||
194 | { | ||
195 | pingres_t* p = (pingres_t*) packet; | ||
196 | int rc; | ||
197 | uint64_t ping_id; | ||
198 | |||
199 | if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id)) | ||
200 | return 1; | ||
201 | |||
202 | // Decrypt ping_id | ||
203 | rc = decrypt_data((uint8_t*) &p->client_id, | ||
204 | self_secret_key, | ||
205 | (uint8_t*) &p->nonce, | ||
206 | (uint8_t*) &p->ping_id, | ||
207 | sizeof(ping_id) + ENCRYPTION_PADDING, | ||
208 | (uint8_t*) &ping_id); | ||
209 | |||
210 | if (rc != sizeof(ping_id)) | ||
211 | return 1; | ||
212 | |||
213 | // Make sure ping_id is correct | ||
214 | if(!is_pinging(source, ping_id)) | ||
215 | return 1; | ||
216 | |||
217 | // Associate source ip with client_id | ||
218 | addto_lists(source, (uint8_t*) &p->client_id); | ||
219 | return 0; | ||
220 | } | ||
diff --git a/core/ping.h b/core/ping.h index 1d23df97..2cab7d59 100644 --- a/core/ping.h +++ b/core/ping.h | |||
@@ -10,4 +10,7 @@ | |||
10 | void init_ping(); | 10 | void init_ping(); |
11 | uint64_t add_ping(IP_Port ipp); | 11 | uint64_t add_ping(IP_Port ipp); |
12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); | 12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); |
13 | 13 | int send_ping_request(IP_Port ipp, clientid_t* client_id); | |
14 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id); | ||
15 | int handle_ping_request(uint8_t* packet, uint32_t length, IP_Port source); | ||
16 | int handle_ping_response(uint8_t* packet, uint32_t length, IP_Port source); | ||
diff --git a/core/util.c b/core/util.c index 4ce9271e..d201bcb4 100644 --- a/core/util.c +++ b/core/util.c | |||
@@ -9,7 +9,8 @@ | |||
9 | #include <stdint.h> | 9 | #include <stdint.h> |
10 | #include <stdbool.h> | 10 | #include <stdbool.h> |
11 | 11 | ||
12 | #include "network.h" | 12 | #include "DHT.h" |
13 | #include "packets.h" | ||
13 | 14 | ||
14 | uint64_t now() | 15 | uint64_t now() |
15 | { | 16 | { |
@@ -32,3 +33,13 @@ bool ipp_eq(IP_Port a, IP_Port b) | |||
32 | { | 33 | { |
33 | return (a.ip.i == b.ip.i) && (a.port == b.port); | 34 | return (a.ip.i == b.ip.i) && (a.port == b.port); |
34 | } | 35 | } |
36 | |||
37 | bool id_eq(clientid_t* dest, clientid_t* src) | ||
38 | { | ||
39 | return memcmp(dest, src, sizeof(clientid_t)) == 0; | ||
40 | } | ||
41 | |||
42 | void id_cpy(clientid_t* dest, clientid_t* src) | ||
43 | { | ||
44 | memcpy(dest, src, sizeof(clientid_t)); | ||
45 | } | ||
diff --git a/core/util.h b/core/util.h index aab2ead9..a93be08a 100644 --- a/core/util.h +++ b/core/util.h | |||
@@ -8,3 +8,6 @@ | |||
8 | uint64_t now(); | 8 | uint64_t now(); |
9 | uint64_t random_64b(); | 9 | uint64_t random_64b(); |
10 | bool ipp_eq(IP_Port a, IP_Port b); | 10 | bool ipp_eq(IP_Port a, IP_Port b); |
11 | bool id_eq(clientid_t* dest, clientid_t* src); | ||
12 | void id_cpy(clientid_t* dest, clientid_t* src); | ||
13 | |||