diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 186 | ||||
-rw-r--r-- | core/DHT.h | 2 | ||||
-rw-r--r-- | core/LAN_discovery.c | 61 | ||||
-rw-r--r-- | core/LAN_discovery.h | 7 | ||||
-rw-r--r-- | core/Messenger.c | 89 | ||||
-rw-r--r-- | core/Messenger.h | 36 | ||||
-rw-r--r-- | core/net_crypto.c | 48 |
7 files changed, 265 insertions, 164 deletions
@@ -21,67 +21,98 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "DHT.h" | 24 | /*----------------------------------------------------------------------------------*/ |
25 | 25 | ||
26 | typedef struct { | 26 | #include "DHT.h" |
27 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
28 | IP_Port ip_port; | ||
29 | uint32_t timestamp; | ||
30 | uint32_t last_pinged; | ||
31 | IP_Port ret_ip_port;/* The ip_port returned by this node for the friend | ||
32 | (for nodes in friends_list) or us (for nodes in close_clientlist) */ | ||
33 | uint32_t ret_timestamp; | ||
34 | } Client_data; | ||
35 | 27 | ||
36 | /* maximum number of clients stored per friend. */ | 28 | /* maximum number of clients stored per friend. */ |
37 | #define MAX_FRIEND_CLIENTS 8 | 29 | #define MAX_FRIEND_CLIENTS 8 |
38 | 30 | ||
39 | typedef struct { | 31 | /* A list of the clients mathematically closest to ours. */ |
40 | uint8_t client_id[CLIENT_ID_SIZE]; | 32 | #define LCLIENT_LIST 32 |
41 | Client_data client_list[MAX_FRIEND_CLIENTS]; | 33 | |
42 | uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ | 34 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ |
43 | 35 | #define LPING_ARRAY 256 | |
44 | /*Symetric NAT hole punching stuff*/ | 36 | |
45 | uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */ | 37 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 |
46 | uint32_t punching_index; | 38 | |
47 | uint32_t punching_timestamp; | 39 | /* the number of seconds for a non responsive node to become bad. */ |
48 | uint32_t recvNATping_timestamp; | 40 | #define BAD_NODE_TIMEOUT 70 |
49 | uint64_t NATping_id; | 41 | |
50 | uint32_t NATping_timestamp; | 42 | /* the max number of nodes to send with send nodes. */ |
51 | } Friend; | 43 | #define MAX_SENT_NODES 8 |
44 | |||
45 | /* ping timeout in seconds */ | ||
46 | #define PING_TIMEOUT 5 | ||
47 | |||
48 | /* The timeout after which a node is discarded completely. */ | ||
49 | #define Kill_NODE_TIMEOUT 300 | ||
50 | |||
51 | /* ping interval in seconds for each node in our lists. */ | ||
52 | #define PING_INTERVAL 60 | ||
53 | |||
54 | /* ping interval in seconds for each random sending of a get nodes request. */ | ||
55 | #define GET_NODE_INTERVAL 10 | ||
56 | |||
57 | #define MAX_PUNCHING_PORTS 32 | ||
58 | |||
59 | /*Interval in seconds between punching attempts*/ | ||
60 | #define PUNCH_INTERVAL 10 | ||
61 | |||
62 | /*----------------------------------------------------------------------------------*/ | ||
52 | 63 | ||
53 | typedef struct { | 64 | typedef struct { |
54 | uint8_t client_id[CLIENT_ID_SIZE]; | 65 | uint8_t client_id[CLIENT_ID_SIZE]; |
55 | IP_Port ip_port; | 66 | IP_Port ip_port; |
56 | } Node_format; | 67 | uint32_t timestamp; |
68 | uint32_t last_pinged; | ||
69 | |||
70 | /* Returned by this node. Either our friend or us */ | ||
71 | IP_Port ret_ip_port; | ||
72 | uint32_t ret_timestamp; | ||
73 | } Client_data; | ||
57 | 74 | ||
58 | typedef struct { | 75 | typedef struct { |
59 | IP_Port ip_port; | 76 | uint8_t client_id[CLIENT_ID_SIZE]; |
60 | uint64_t ping_id; | 77 | Client_data client_list[MAX_FRIEND_CLIENTS]; |
61 | uint32_t timestamp; | ||
62 | 78 | ||
63 | } Pinged; | 79 | /* time at which the last get_nodes request was sent. */ |
80 | uint32_t lastgetnode; | ||
64 | 81 | ||
65 | /* Our client id/public key */ | 82 | /* Symetric NAT hole punching stuff */ |
66 | uint8_t self_public_key[CLIENT_ID_SIZE]; | ||
67 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
68 | 83 | ||
69 | /* TODO: Move these out of here and put them into the .c file. | 84 | /* 1 if currently hole punching, otherwise 0 */ |
70 | A list of the clients mathematically closest to ours. */ | 85 | uint8_t hole_punching; |
71 | #define LCLIENT_LIST 32 | 86 | uint32_t punching_index; |
72 | static Client_data close_clientlist[LCLIENT_LIST]; | 87 | uint32_t punching_timestamp; |
88 | int64_t recvNATping_timestamp; | ||
89 | uint64_t NATping_id; | ||
90 | uint32_t NATping_timestamp; | ||
91 | } Friend; | ||
73 | 92 | ||
74 | static Friend * friends_list; | 93 | typedef struct { |
75 | static uint16_t num_friends; | 94 | uint8_t client_id[CLIENT_ID_SIZE]; |
95 | IP_Port ip_port; | ||
96 | } Node_format; | ||
76 | 97 | ||
77 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | 98 | typedef struct { |
78 | #define LPING_ARRAY 256 | 99 | IP_Port ip_port; |
100 | uint64_t ping_id; | ||
101 | int64_t timestamp; | ||
102 | } Pinged; | ||
79 | 103 | ||
80 | static Pinged pings[LPING_ARRAY]; | 104 | /*----------------------------------------------------------------------------------*/ |
81 | 105 | ||
82 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | 106 | /* Our client id/public key */ |
107 | uint8_t self_public_key[CLIENT_ID_SIZE]; | ||
108 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
109 | static Client_data close_clientlist[LCLIENT_LIST]; | ||
110 | static Friend * friends_list; | ||
111 | static uint16_t num_friends; | ||
112 | static Pinged pings[LPING_ARRAY]; | ||
113 | static Pinged send_nodes[LSEND_NODES_ARRAY]; | ||
83 | 114 | ||
84 | static Pinged send_nodes[LSEND_NODES_ARRAY]; | 115 | /*----------------------------------------------------------------------------------*/ |
85 | 116 | ||
86 | /* Compares client_id1 and client_id2 with client_id | 117 | /* Compares client_id1 and client_id2 with client_id |
87 | return 0 if both are same distance | 118 | return 0 if both are same distance |
@@ -107,7 +138,7 @@ int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) | |||
107 | int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) | 138 | int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) |
108 | { | 139 | { |
109 | uint32_t i; | 140 | uint32_t i; |
110 | uint32_t temp_time = unix_time(); | 141 | int64_t temp_time = unix_time(); |
111 | 142 | ||
112 | for(i = 0; i < length; ++i) { | 143 | for(i = 0; i < length; ++i) { |
113 | /*If ip_port is assigned to a different client_id replace it*/ | 144 | /*If ip_port is assigned to a different client_id replace it*/ |
@@ -150,11 +181,6 @@ static int friend_number(uint8_t * client_id) | |||
150 | return -1; | 181 | return -1; |
151 | } | 182 | } |
152 | 183 | ||
153 | /* the number of seconds for a non responsive node to become bad. */ | ||
154 | #define BAD_NODE_TIMEOUT 70 | ||
155 | /* the max number of nodes to send with send nodes. */ | ||
156 | #define MAX_SENT_NODES 8 | ||
157 | |||
158 | /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: | 184 | /* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: |
159 | put them in the nodes_list and return how many were found. | 185 | put them in the nodes_list and return how many were found. |
160 | TODO: Make this function much more efficient. */ | 186 | TODO: Make this function much more efficient. */ |
@@ -162,7 +188,7 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) | |||
162 | { | 188 | { |
163 | uint32_t i, j, k; | 189 | uint32_t i, j, k; |
164 | int num_nodes=0; | 190 | int num_nodes=0; |
165 | uint32_t temp_time = unix_time(); | 191 | int64_t temp_time = unix_time(); |
166 | for(i = 0; i < LCLIENT_LIST; ++i) | 192 | for(i = 0; i < LCLIENT_LIST; ++i) |
167 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && | 193 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && |
168 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { | 194 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { |
@@ -204,7 +230,7 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) | |||
204 | int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */ | 230 | int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */ |
205 | { | 231 | { |
206 | uint32_t i; | 232 | uint32_t i; |
207 | uint32_t temp_time = unix_time(); | 233 | int64_t temp_time = unix_time(); |
208 | for(i = 0; i < length; ++i) | 234 | for(i = 0; i < length; ++i) |
209 | if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */ | 235 | if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */ |
210 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 236 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
@@ -223,7 +249,7 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por | |||
223 | int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id) | 249 | int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id) |
224 | { | 250 | { |
225 | uint32_t i; | 251 | uint32_t i; |
226 | uint32_t temp_time = unix_time(); | 252 | int64_t temp_time = unix_time(); |
227 | 253 | ||
228 | for(i = 0; i < length; ++i) | 254 | for(i = 0; i < length; ++i) |
229 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { | 255 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { |
@@ -262,7 +288,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
262 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) | 288 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) |
263 | { | 289 | { |
264 | uint32_t i, j; | 290 | uint32_t i, j; |
265 | uint32_t temp_time = unix_time(); | 291 | int64_t temp_time = unix_time(); |
266 | if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { | 292 | if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { |
267 | for(i = 0; i < LCLIENT_LIST; ++i) | 293 | for(i = 0; i < LCLIENT_LIST; ++i) |
268 | if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { | 294 | if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { |
@@ -281,9 +307,6 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient | |||
281 | } | 307 | } |
282 | } | 308 | } |
283 | 309 | ||
284 | /* ping timeout in seconds */ | ||
285 | #define PING_TIMEOUT 5 | ||
286 | |||
287 | /* check if we are currently pinging an ip_port and/or a ping_id | 310 | /* check if we are currently pinging an ip_port and/or a ping_id |
288 | variables with values of zero will not be checked. | 311 | variables with values of zero will not be checked. |
289 | if we are already, return 1 | 312 | if we are already, return 1 |
@@ -293,7 +316,7 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id) | |||
293 | { | 316 | { |
294 | uint32_t i; | 317 | uint32_t i; |
295 | uint8_t pinging; | 318 | uint8_t pinging; |
296 | uint32_t temp_time = unix_time(); | 319 | int64_t temp_time = unix_time(); |
297 | 320 | ||
298 | for(i = 0; i < LPING_ARRAY; ++i ) | 321 | for(i = 0; i < LPING_ARRAY; ++i ) |
299 | if((pings[i].timestamp + PING_TIMEOUT) > temp_time) { | 322 | if((pings[i].timestamp + PING_TIMEOUT) > temp_time) { |
@@ -317,7 +340,7 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
317 | { | 340 | { |
318 | uint32_t i; | 341 | uint32_t i; |
319 | uint8_t pinging; | 342 | uint8_t pinging; |
320 | uint32_t temp_time = unix_time(); | 343 | int64_t temp_time = unix_time(); |
321 | 344 | ||
322 | for(i = 0; i < LSEND_NODES_ARRAY; ++i ) | 345 | for(i = 0; i < LSEND_NODES_ARRAY; ++i ) |
323 | if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { | 346 | if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { |
@@ -345,7 +368,7 @@ uint64_t add_pinging(IP_Port ip_port) | |||
345 | { | 368 | { |
346 | uint32_t i, j; | 369 | uint32_t i, j; |
347 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 370 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
348 | uint32_t temp_time = unix_time(); | 371 | int64_t temp_time = unix_time(); |
349 | 372 | ||
350 | for(i = 0; i < PING_TIMEOUT; ++i ) | 373 | for(i = 0; i < PING_TIMEOUT; ++i ) |
351 | for(j = 0; j < LPING_ARRAY; ++j ) | 374 | for(j = 0; j < LPING_ARRAY; ++j ) |
@@ -364,7 +387,7 @@ uint64_t add_gettingnodes(IP_Port ip_port) | |||
364 | { | 387 | { |
365 | uint32_t i, j; | 388 | uint32_t i, j; |
366 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 389 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
367 | uint32_t temp_time = unix_time(); | 390 | int64_t temp_time = unix_time(); |
368 | 391 | ||
369 | for(i = 0; i < PING_TIMEOUT; ++i ) | 392 | for(i = 0; i < PING_TIMEOUT; ++i ) |
370 | for(j = 0; j < LSEND_NODES_ARRAY; ++j ) | 393 | for(j = 0; j < LSEND_NODES_ARRAY; ++j ) |
@@ -619,7 +642,8 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
619 | return 0; | 642 | return 0; |
620 | } | 643 | } |
621 | 644 | ||
622 | /* END of packet handling functions */ | 645 | /*----------------------------------------------------------------------------------*/ |
646 | /*------------------------END of packet handling functions--------------------------*/ | ||
623 | 647 | ||
624 | int DHT_addfriend(uint8_t * client_id) | 648 | int DHT_addfriend(uint8_t * client_id) |
625 | { | 649 | { |
@@ -660,7 +684,7 @@ IP_Port DHT_getfriendip(uint8_t * client_id) | |||
660 | { | 684 | { |
661 | uint32_t i, j; | 685 | uint32_t i, j; |
662 | IP_Port empty = {{{0}}, 0}; | 686 | IP_Port empty = {{{0}}, 0}; |
663 | uint32_t temp_time = unix_time(); | 687 | int64_t temp_time = unix_time(); |
664 | for(i = 0; i < num_friends; ++i) | 688 | for(i = 0; i < num_friends; ++i) |
665 | /* Equal */ | 689 | /* Equal */ |
666 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { | 690 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { |
@@ -676,21 +700,12 @@ IP_Port DHT_getfriendip(uint8_t * client_id) | |||
676 | 700 | ||
677 | } | 701 | } |
678 | 702 | ||
679 | /* The timeout after which a node is discarded completely. */ | ||
680 | #define Kill_NODE_TIMEOUT 300 | ||
681 | |||
682 | /* ping interval in seconds for each node in our lists. */ | ||
683 | #define PING_INTERVAL 60 | ||
684 | |||
685 | /* ping interval in seconds for each random sending of a get nodes request. */ | ||
686 | #define GET_NODE_INTERVAL 10 | ||
687 | |||
688 | /* Ping each client in the "friends" list every 60 seconds. | 703 | /* Ping each client in the "friends" list every 60 seconds. |
689 | Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ | 704 | Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ |
690 | void doDHTFriends() | 705 | void doDHTFriends() |
691 | { | 706 | { |
692 | uint32_t i, j; | 707 | uint32_t i, j; |
693 | uint32_t temp_time = unix_time(); | 708 | int64_t temp_time = unix_time(); |
694 | uint32_t rand_node; | 709 | uint32_t rand_node; |
695 | uint32_t index[MAX_FRIEND_CLIENTS]; | 710 | uint32_t index[MAX_FRIEND_CLIENTS]; |
696 | 711 | ||
@@ -724,7 +739,7 @@ static uint32_t close_lastgetnodes; | |||
724 | void doClose() /* tested */ | 739 | void doClose() /* tested */ |
725 | { | 740 | { |
726 | uint32_t i; | 741 | uint32_t i; |
727 | uint32_t temp_time = unix_time(); | 742 | int64_t temp_time = unix_time(); |
728 | uint32_t num_nodes = 0; | 743 | uint32_t num_nodes = 0; |
729 | uint32_t rand_node; | 744 | uint32_t rand_node; |
730 | uint32_t index[LCLIENT_LIST]; | 745 | uint32_t index[LCLIENT_LIST]; |
@@ -777,7 +792,7 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) | |||
777 | { | 792 | { |
778 | int num_ips = 0; | 793 | int num_ips = 0; |
779 | uint32_t i; | 794 | uint32_t i; |
780 | uint32_t temp_time = unix_time(); | 795 | int64_t temp_time = unix_time(); |
781 | if(friend_num >= num_friends) | 796 | if(friend_num >= num_friends) |
782 | return -1; | 797 | return -1; |
783 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) | 798 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) |
@@ -798,7 +813,7 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | |||
798 | { | 813 | { |
799 | uint32_t i, j; | 814 | uint32_t i, j; |
800 | uint32_t sent = 0; | 815 | uint32_t sent = 0; |
801 | uint32_t temp_time = unix_time(); | 816 | int64_t temp_time = unix_time(); |
802 | for(i = 0; i < num_friends; ++i) | 817 | for(i = 0; i < num_friends; ++i) |
803 | /* Equal */ | 818 | /* Equal */ |
804 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { | 819 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { |
@@ -824,7 +839,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | |||
824 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 839 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
825 | int n = 0; | 840 | int n = 0; |
826 | uint32_t i; | 841 | uint32_t i; |
827 | uint32_t temp_time = unix_time(); | 842 | int64_t temp_time = unix_time(); |
828 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) | 843 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) |
829 | /*If ip is not zero and node is good */ | 844 | /*If ip is not zero and node is good */ |
830 | if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && | 845 | if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && |
@@ -855,7 +870,8 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) | |||
855 | return -1; | 870 | return -1; |
856 | } | 871 | } |
857 | 872 | ||
858 | /*BEGINNING OF NAT PUNCHING FUNCTIONS*/ | 873 | /*----------------------------------------------------------------------------------*/ |
874 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ | ||
859 | 875 | ||
860 | int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | 876 | int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) |
861 | { | 877 | { |
@@ -955,8 +971,6 @@ static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_ | |||
955 | return num; | 971 | return num; |
956 | } | 972 | } |
957 | 973 | ||
958 | #define MAX_PUNCHING_PORTS 32 | ||
959 | |||
960 | static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) | 974 | static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) |
961 | { | 975 | { |
962 | if(numports > MAX_FRIEND_CLIENTS || numports == 0) | 976 | if(numports > MAX_FRIEND_CLIENTS || numports == 0) |
@@ -972,13 +986,10 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t | |||
972 | friends_list[friend_num].punching_index = i; | 986 | friends_list[friend_num].punching_index = i; |
973 | } | 987 | } |
974 | 988 | ||
975 | /*Interval in seconds between punching attempts*/ | ||
976 | #define PUNCH_INTERVAL 10 | ||
977 | |||
978 | static void doNAT() | 989 | static void doNAT() |
979 | { | 990 | { |
980 | uint32_t i; | 991 | uint32_t i; |
981 | uint32_t temp_time = unix_time(); | 992 | int64_t temp_time = unix_time(); |
982 | for(i = 0; i < num_friends; ++i) { | 993 | for(i = 0; i < num_friends; ++i) { |
983 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 994 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
984 | int num = friend_iplist(ip_list, i); | 995 | int num = friend_iplist(ip_list, i); |
@@ -1008,7 +1019,8 @@ static void doNAT() | |||
1008 | } | 1019 | } |
1009 | } | 1020 | } |
1010 | 1021 | ||
1011 | /*END OF NAT PUNCHING FUNCTIONS*/ | 1022 | /*----------------------------------------------------------------------------------*/ |
1023 | /*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ | ||
1012 | 1024 | ||
1013 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | 1025 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) |
1014 | { | 1026 | { |
@@ -1066,7 +1078,7 @@ int DHT_load(uint8_t * data, uint32_t size) | |||
1066 | if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) | 1078 | if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) |
1067 | return -1; | 1079 | return -1; |
1068 | uint32_t i, j; | 1080 | uint32_t i, j; |
1069 | /* uint32_t temp_time = unix_time(); */ | 1081 | /* int64_t temp_time = unix_time(); */ |
1070 | uint16_t temp; | 1082 | uint16_t temp; |
1071 | 1083 | ||
1072 | temp = (size - sizeof(close_clientlist))/sizeof(Friend); | 1084 | temp = (size - sizeof(close_clientlist))/sizeof(Friend); |
@@ -1096,7 +1108,7 @@ int DHT_load(uint8_t * data, uint32_t size) | |||
1096 | int DHT_isconnected() | 1108 | int DHT_isconnected() |
1097 | { | 1109 | { |
1098 | uint32_t i; | 1110 | uint32_t i; |
1099 | uint32_t temp_time = unix_time(); | 1111 | int64_t temp_time = unix_time(); |
1100 | for(i = 0; i < LCLIENT_LIST; ++i) | 1112 | for(i = 0; i < LCLIENT_LIST; ++i) |
1101 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) | 1113 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) |
1102 | return 1; | 1114 | return 1; |
@@ -31,7 +31,7 @@ extern "C" { | |||
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | /* Current time, unix format */ | 33 | /* Current time, unix format */ |
34 | #define unix_time() ((uint32_t)time(NULL)) | 34 | #define unix_time() ((int64_t)time(NULL)) |
35 | 35 | ||
36 | /* size of the client_id in bytes */ | 36 | /* size of the client_id in bytes */ |
37 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES | 37 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index 0a23914d..72e00d32 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -23,13 +23,70 @@ | |||
23 | 23 | ||
24 | #include "LAN_discovery.h" | 24 | #include "LAN_discovery.h" |
25 | 25 | ||
26 | #define MAX_INTERFACES 16 | ||
26 | 27 | ||
27 | /*Return the broadcast ip | 28 | #ifdef __linux |
28 | TODO: make it return the real one, not the 255.255.255.255 one.*/ | 29 | /* get the first working broadcast address that's not from "lo" |
30 | * returns higher than 0 on success | ||
31 | * returns 0 on error */ | ||
32 | uint32_t get_broadcast(void) | ||
33 | { | ||
34 | /* not sure how many platforms this will | ||
35 | * run on, so it's wrapped in __linux for now */ | ||
36 | struct sockaddr_in *sock_holder = NULL; | ||
37 | struct ifreq i_faces[MAX_INTERFACES]; | ||
38 | struct ifconf ifconf; | ||
39 | int count = 0; | ||
40 | int sock = 0; | ||
41 | int i = 0; | ||
42 | |||
43 | /* configure ifconf for the ioctl call */ | ||
44 | if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | ||
45 | perror("[!] get_broadcast: socket() error"); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES); | ||
50 | |||
51 | ifconf.ifc_buf = (char *)i_faces; | ||
52 | ifconf.ifc_len = sizeof(i_faces); | ||
53 | count = ifconf.ifc_len / sizeof(struct ifreq); | ||
54 | if(ioctl(sock, SIOCGIFCONF, &ifconf) < 0) { | ||
55 | perror("get_broadcast: ioctl() error"); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | for(i = 0; i < count; i++) { | ||
60 | /* skip the loopback interface, as it's useless */ | ||
61 | if(strcmp(i_faces[i].ifr_name, "lo") != 0) { | ||
62 | if(ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { | ||
63 | perror("[!] get_broadcast: ioctl error"); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | /* just to clarify where we're getting the values from */ | ||
68 | sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | close(sock); | ||
73 | |||
74 | return sock_holder->sin_addr.s_addr; | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | /* Return the broadcast ip */ | ||
29 | IP broadcast_ip() | 79 | IP broadcast_ip() |
30 | { | 80 | { |
31 | IP ip; | 81 | IP ip; |
82 | #ifdef __linux | ||
83 | ip.i = get_broadcast(); | ||
84 | if(ip.i == 0) | ||
85 | /* error errored, but try anyway? */ | ||
86 | ip.i = ~0; | ||
87 | #else | ||
32 | ip.i = ~0; | 88 | ip.i = ~0; |
89 | #endif | ||
33 | return ip; | 90 | return ip; |
34 | } | 91 | } |
35 | 92 | ||
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h index 4ca65c03..96a6e6ad 100644 --- a/core/LAN_discovery.h +++ b/core/LAN_discovery.h | |||
@@ -28,6 +28,13 @@ | |||
28 | 28 | ||
29 | #include "DHT.h" | 29 | #include "DHT.h" |
30 | 30 | ||
31 | /* used for get_broadcast() */ | ||
32 | #ifdef __linux | ||
33 | #include <sys/ioctl.h> | ||
34 | #include <arpa/inet.h> | ||
35 | #include <linux/netdevice.h> | ||
36 | #endif | ||
37 | |||
31 | #ifdef __cplusplus | 38 | #ifdef __cplusplus |
32 | extern "C" { | 39 | extern "C" { |
33 | #endif | 40 | #endif |
diff --git a/core/Messenger.c b/core/Messenger.c index eb59b81a..3ffbe6ab 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -27,7 +27,7 @@ | |||
27 | typedef struct { | 27 | typedef struct { |
28 | uint8_t client_id[CLIENT_ID_SIZE]; | 28 | uint8_t client_id[CLIENT_ID_SIZE]; |
29 | int crypt_connection_id; | 29 | int crypt_connection_id; |
30 | int friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */ | 30 | int64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */ |
31 | uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */ | 31 | uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */ |
32 | uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */ | 32 | uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */ |
33 | uint8_t name[MAX_NAME_LENGTH]; | 33 | uint8_t name[MAX_NAME_LENGTH]; |
@@ -71,12 +71,6 @@ int getfriend_id(uint8_t *client_id) | |||
71 | return -1; | 71 | return -1; |
72 | } | 72 | } |
73 | 73 | ||
74 | /* Returns number of friends */ | ||
75 | int getnumfriends() | ||
76 | { | ||
77 | return numfriends; | ||
78 | } | ||
79 | |||
80 | /* copies the public key associated to that friend id into client_id buffer. | 74 | /* copies the public key associated to that friend id into client_id buffer. |
81 | make sure that client_id is of size CLIENT_ID_SIZE. | 75 | make sure that client_id is of size CLIENT_ID_SIZE. |
82 | return 0 if success | 76 | return 0 if success |
@@ -94,29 +88,36 @@ int getclient_id(int friend_id, uint8_t *client_id) | |||
94 | return -1; | 88 | return -1; |
95 | } | 89 | } |
96 | 90 | ||
97 | /* add a friend | 91 | /* |
98 | set the data that will be sent along with friend request | 92 | * add a friend |
99 | client_id is the client id of the friend | 93 | * set the data that will be sent along with friend request |
100 | data is the data and length is the length | 94 | * client_id is the client id of the friend |
101 | returns the friend number if success | 95 | * data is the data and length is the length |
102 | return -1 if key length is wrong. | 96 | * returns the friend number if success |
103 | return -2 if user's own key | 97 | * return FA_TOOLONG if message length is too long |
104 | return -3 if already a friend | 98 | * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte) |
105 | return -4 for other*/ | 99 | * return FAERR_OWNKEY if user's own key |
100 | * return FAERR_ALREADYSENT if friend request already sent or already a friend | ||
101 | * return FAERR_UNKNOWN for unknown error | ||
102 | */ | ||
106 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | 103 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) |
107 | { | 104 | { |
108 | if (length == 0 || length >= | 105 | if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES |
109 | (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) | 106 | - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES |
110 | return -1; | 107 | + crypto_box_ZEROBYTES)) |
108 | return FAERR_TOOLONG; | ||
109 | if (length < 1) | ||
110 | return FAERR_NOMESSAGE; | ||
111 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | 111 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) |
112 | return -2; | 112 | return FAERR_OWNKEY; |
113 | if (getfriend_id(client_id) != -1) | 113 | if (getfriend_id(client_id) != -1) |
114 | return -3; | 114 | return FAERR_ALREADYSENT; |
115 | |||
115 | uint32_t i; | 116 | uint32_t i; |
116 | for (i = 0; i <= numfriends; ++i) { /*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/ | 117 | for (i = 0; i <= numfriends; ++i) { /*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/ |
117 | if(friendlist[i].status == 0) { | 118 | if(friendlist[i].status == NOFRIEND) { |
118 | DHT_addfriend(client_id); | 119 | DHT_addfriend(client_id); |
119 | friendlist[i].status = 1; | 120 | friendlist[i].status = FRIEND_ADDED; |
120 | friendlist[i].crypt_connection_id = -1; | 121 | friendlist[i].crypt_connection_id = -1; |
121 | friendlist[i].friend_request_id = -1; | 122 | friendlist[i].friend_request_id = -1; |
122 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); | 123 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); |
@@ -129,7 +130,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
129 | return i; | 130 | return i; |
130 | } | 131 | } |
131 | } | 132 | } |
132 | return -4; | 133 | return FAERR_UNKNOWN; |
133 | } | 134 | } |
134 | 135 | ||
135 | int m_addfriend_norequest(uint8_t * client_id) | 136 | int m_addfriend_norequest(uint8_t * client_id) |
@@ -138,9 +139,9 @@ int m_addfriend_norequest(uint8_t * client_id) | |||
138 | return -1; | 139 | return -1; |
139 | uint32_t i; | 140 | uint32_t i; |
140 | for (i = 0; i <= numfriends; ++i) {/*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/ | 141 | for (i = 0; i <= numfriends; ++i) {/*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/ |
141 | if(friendlist[i].status == 0) { | 142 | if(friendlist[i].status == NOFRIEND) { |
142 | DHT_addfriend(client_id); | 143 | DHT_addfriend(client_id); |
143 | friendlist[i].status = 2; | 144 | friendlist[i].status = FRIEND_REQUESTED; |
144 | friendlist[i].crypt_connection_id = -1; | 145 | friendlist[i].crypt_connection_id = -1; |
145 | friendlist[i].friend_request_id = -1; | 146 | friendlist[i].friend_request_id = -1; |
146 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); | 147 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); |
@@ -168,7 +169,7 @@ int m_delfriend(int friendnumber) | |||
168 | uint32_t i; | 169 | uint32_t i; |
169 | 170 | ||
170 | for (i = numfriends; i != 0; --i) { | 171 | for (i = numfriends; i != 0; --i) { |
171 | if (friendlist[i-1].status != 0) | 172 | if (friendlist[i-1].status != NOFRIEND) |
172 | break; | 173 | break; |
173 | } | 174 | } |
174 | numfriends = i; | 175 | numfriends = i; |
@@ -176,15 +177,15 @@ int m_delfriend(int friendnumber) | |||
176 | return 0; | 177 | return 0; |
177 | } | 178 | } |
178 | 179 | ||
179 | /* return 4 if friend is online | 180 | /* return FRIEND_ONLINE if friend is online |
180 | return 3 if friend is confirmed | 181 | return FRIEND_CONFIRMED if friend is confirmed |
181 | return 2 if the friend request was sent | 182 | return FRIEND_REQUESTED if the friend request was sent |
182 | return 1 if the friend was added | 183 | return FRIEND_ADDED if the friend was added |
183 | return 0 if there is no friend with that number */ | 184 | return NOFRIEND if there is no friend with that number */ |
184 | int m_friendstatus(int friendnumber) | 185 | int m_friendstatus(int friendnumber) |
185 | { | 186 | { |
186 | if (friendnumber < 0 || friendnumber >= numfriends) | 187 | if (friendnumber < 0 || friendnumber >= numfriends) |
187 | return 0; | 188 | return NOFRIEND; |
188 | return friendlist[friendnumber].status; | 189 | return friendlist[friendnumber].status; |
189 | } | 190 | } |
190 | 191 | ||
@@ -195,7 +196,7 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | |||
195 | { | 196 | { |
196 | if (friendnumber < 0 || friendnumber >= numfriends) | 197 | if (friendnumber < 0 || friendnumber >= numfriends) |
197 | return 0; | 198 | return 0; |
198 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) | 199 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) |
199 | /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ | 200 | /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ |
200 | return 0; | 201 | return 0; |
201 | uint8_t temp[MAX_DATA_SIZE]; | 202 | uint8_t temp[MAX_DATA_SIZE]; |
@@ -384,15 +385,15 @@ static void doFriends() | |||
384 | int len; | 385 | int len; |
385 | uint8_t temp[MAX_DATA_SIZE]; | 386 | uint8_t temp[MAX_DATA_SIZE]; |
386 | for (i = 0; i < numfriends; ++i) { | 387 | for (i = 0; i < numfriends; ++i) { |
387 | if (friendlist[i].status == 1) { | 388 | if (friendlist[i].status == FRIEND_ADDED) { |
388 | int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); | 389 | int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); |
389 | if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */ | 390 | if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */ |
390 | friendlist[i].status = 2; | 391 | friendlist[i].status = FRIEND_REQUESTED; |
391 | else if (fr > 0) | 392 | else if (fr > 0) |
392 | friendlist[i].status = 2; | 393 | friendlist[i].status = FRIEND_REQUESTED; |
393 | } | 394 | } |
394 | if (friendlist[i].status == 2 || friendlist[i].status == 3) { /* friend is not online */ | 395 | if (friendlist[i].status == FRIEND_REQUESTED || friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ |
395 | if (friendlist[i].status == 2) { | 396 | if (friendlist[i].status == FRIEND_REQUESTED) { |
396 | if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ | 397 | if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ |
397 | send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); | 398 | send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); |
398 | friendlist[i].friend_request_id = unix_time(); | 399 | friendlist[i].friend_request_id = unix_time(); |
@@ -405,7 +406,7 @@ static void doFriends() | |||
405 | friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); | 406 | friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); |
406 | break; | 407 | break; |
407 | case 3: /* Connection is established */ | 408 | case 3: /* Connection is established */ |
408 | friendlist[i].status = 4; | 409 | friendlist[i].status = FRIEND_ONLINE; |
409 | break; | 410 | break; |
410 | case 4: | 411 | case 4: |
411 | crypto_kill(friendlist[i].crypt_connection_id); | 412 | crypto_kill(friendlist[i].crypt_connection_id); |
@@ -415,7 +416,7 @@ static void doFriends() | |||
415 | break; | 416 | break; |
416 | } | 417 | } |
417 | } | 418 | } |
418 | while (friendlist[i].status == 4) { /* friend is online */ | 419 | while (friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ |
419 | if (friendlist[i].name_sent == 0) { | 420 | if (friendlist[i].name_sent == 0) { |
420 | if (m_sendname(i, self_name, self_name_length)) | 421 | if (m_sendname(i, self_name, self_name_length)) |
421 | friendlist[i].name_sent = 1; | 422 | friendlist[i].name_sent = 1; |
@@ -455,7 +456,7 @@ static void doFriends() | |||
455 | if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ | 456 | if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ |
456 | crypto_kill(friendlist[i].crypt_connection_id); | 457 | crypto_kill(friendlist[i].crypt_connection_id); |
457 | friendlist[i].crypt_connection_id = -1; | 458 | friendlist[i].crypt_connection_id = -1; |
458 | friendlist[i].status = 3; | 459 | friendlist[i].status = FRIEND_CONFIRMED; |
459 | } | 460 | } |
460 | break; | 461 | break; |
461 | } | 462 | } |
@@ -476,7 +477,7 @@ static void doInbound() | |||
476 | friendlist[friend_id].crypt_connection_id = | 477 | friendlist[friend_id].crypt_connection_id = |
477 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); | 478 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); |
478 | 479 | ||
479 | friendlist[friend_id].status = 3; | 480 | friendlist[friend_id].status = FRIEND_CONFIRMED; |
480 | } | 481 | } |
481 | } | 482 | } |
482 | } | 483 | } |
@@ -484,7 +485,7 @@ static void doInbound() | |||
484 | /*Interval in seconds between LAN discovery packet sending*/ | 485 | /*Interval in seconds between LAN discovery packet sending*/ |
485 | #define LAN_DISCOVERY_INTERVAL 60 | 486 | #define LAN_DISCOVERY_INTERVAL 60 |
486 | 487 | ||
487 | static uint32_t last_LANdiscovery; | 488 | static int64_t last_LANdiscovery; |
488 | 489 | ||
489 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ | 490 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ |
490 | static void LANdiscovery() | 491 | static void LANdiscovery() |
diff --git a/core/Messenger.h b/core/Messenger.h index 9ce96fb4..acf62a32 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -42,18 +42,36 @@ extern "C" { | |||
42 | #define PACKET_ID_USERSTATUS 49 | 42 | #define PACKET_ID_USERSTATUS 49 |
43 | #define PACKET_ID_MESSAGE 64 | 43 | #define PACKET_ID_MESSAGE 64 |
44 | 44 | ||
45 | /* status definitions */ | ||
46 | #define FRIEND_ONLINE 4 | ||
47 | #define FRIEND_CONFIRMED 3 | ||
48 | #define FRIEND_REQUESTED 2 | ||
49 | #define FRIEND_ADDED 1 | ||
50 | #define NOFRIEND 0 | ||
51 | |||
52 | /* errors for m_addfriend | ||
53 | * FAERR - Friend Add Error */ | ||
54 | #define FAERR_TOOLONG -1 | ||
55 | #define FAERR_NOMESSAGE -2 | ||
56 | #define FAERR_OWNKEY -3 | ||
57 | #define FAERR_ALREADYSENT -4 | ||
58 | #define FAERR_UNKNOWN -5 | ||
59 | |||
45 | /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased | 60 | /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased |
46 | to an absurdly large number later */ | 61 | to an absurdly large number later */ |
47 | 62 | ||
48 | /* add a friend | 63 | /* |
49 | set the data that will be sent along with friend request | 64 | * add a friend |
50 | client_id is the client id of the friend | 65 | * set the data that will be sent along with friend request |
51 | data is the data and length is the length | 66 | * client_id is the client id of the friend |
52 | returns the friend number if success | 67 | * data is the data and length is the length |
53 | return -1 if key length is wrong. | 68 | * returns the friend number if success |
54 | return -2 if user's own key | 69 | * return -1 if message length is too long |
55 | return -3 if already a friend | 70 | * return -2 if no message (message length must be >= 1 byte) |
56 | return -4 for other*/ | 71 | * return -3 if user's own key |
72 | * return -4 if friend request already sent or already a friend | ||
73 | * return -5 for unknown error | ||
74 | */ | ||
57 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); | 75 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); |
58 | 76 | ||
59 | 77 | ||
diff --git a/core/net_crypto.c b/core/net_crypto.c index 34d481ca..31fb24be 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -48,6 +48,12 @@ typedef struct { | |||
48 | 48 | ||
49 | static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; | 49 | static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; |
50 | 50 | ||
51 | #define CONN_NO_CONNECTION 0 | ||
52 | #define CONN_HANDSHAKE_SENT 1 | ||
53 | #define CONN_NOT_CONFIRMED 2 | ||
54 | #define CONN_ESTABLISHED 3 | ||
55 | #define CONN_TIMED_OUT 4 | ||
56 | |||
51 | #define MAX_INCOMING 64 | 57 | #define MAX_INCOMING 64 |
52 | 58 | ||
53 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | 59 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ |
@@ -75,7 +81,7 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
75 | uint32_t i; | 81 | uint32_t i; |
76 | uint32_t check = 0; | 82 | uint32_t check = 0; |
77 | for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { | 83 | for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { |
78 | check |= temp_plain[i] ^ 0; | 84 | check |= temp_encrypted[i] ^ 0; |
79 | } | 85 | } |
80 | if(check != 0) | 86 | if(check != 0) |
81 | return -1; | 87 | return -1; |
@@ -147,7 +153,7 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
147 | { | 153 | { |
148 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 154 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) |
149 | return 0; | 155 | return 0; |
150 | if (crypto_connections[crypt_connection_id].status != 3) | 156 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
151 | return 0; | 157 | return 0; |
152 | uint8_t temp_data[MAX_DATA_SIZE]; | 158 | uint8_t temp_data[MAX_DATA_SIZE]; |
153 | int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); | 159 | int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); |
@@ -173,7 +179,7 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | |||
173 | return 0; | 179 | return 0; |
174 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) | 180 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) |
175 | return 0; | 181 | return 0; |
176 | if (crypto_connections[crypt_connection_id].status != 3) | 182 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
177 | return 0; | 183 | return 0; |
178 | uint8_t temp_data[MAX_DATA_SIZE]; | 184 | uint8_t temp_data[MAX_DATA_SIZE]; |
179 | int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, | 185 | int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, |
@@ -293,7 +299,7 @@ int getcryptconnection_id(uint8_t *public_key) | |||
293 | { | 299 | { |
294 | uint32_t i; | 300 | uint32_t i; |
295 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 301 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { |
296 | if (crypto_connections[i].status > 0) | 302 | if (crypto_connections[i].status != CONN_NO_CONNECTION) |
297 | if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) | 303 | if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) |
298 | return i; | 304 | return i; |
299 | } | 305 | } |
@@ -313,12 +319,12 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port) | |||
313 | return -1; | 319 | return -1; |
314 | } | 320 | } |
315 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 321 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { |
316 | if (crypto_connections[i].status == 0) { | 322 | if (crypto_connections[i].status == CONN_NO_CONNECTION) { |
317 | int id = new_connection(ip_port); | 323 | int id = new_connection(ip_port); |
318 | if (id == -1) | 324 | if (id == -1) |
319 | return -1; | 325 | return -1; |
320 | crypto_connections[i].number = id; | 326 | crypto_connections[i].number = id; |
321 | crypto_connections[i].status = 1; | 327 | crypto_connections[i].status = CONN_HANDSHAKE_SENT; |
322 | random_nonce(crypto_connections[i].recv_nonce); | 328 | random_nonce(crypto_connections[i].recv_nonce); |
323 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 329 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
324 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 330 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); |
@@ -372,8 +378,8 @@ int crypto_kill(int crypt_connection_id) | |||
372 | { | 378 | { |
373 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 379 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) |
374 | return 1; | 380 | return 1; |
375 | if (crypto_connections[crypt_connection_id].status != 0) { | 381 | if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { |
376 | crypto_connections[crypt_connection_id].status = 0; | 382 | crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; |
377 | kill_connection(crypto_connections[crypt_connection_id].number); | 383 | kill_connection(crypto_connections[crypt_connection_id].number); |
378 | memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection)); | 384 | memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection)); |
379 | crypto_connections[crypt_connection_id].number = ~0; | 385 | crypto_connections[crypt_connection_id].number = ~0; |
@@ -396,9 +402,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
396 | return -1; | 402 | return -1; |
397 | }*/ | 403 | }*/ |
398 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 404 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { |
399 | if(crypto_connections[i].status == 0) { | 405 | if(crypto_connections[i].status == CONN_NO_CONNECTION) { |
400 | crypto_connections[i].number = connection_id; | 406 | crypto_connections[i].number = connection_id; |
401 | crypto_connections[i].status = 2; | 407 | crypto_connections[i].status = CONN_NOT_CONFIRMED; |
402 | random_nonce(crypto_connections[i].recv_nonce); | 408 | random_nonce(crypto_connections[i].recv_nonce); |
403 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 409 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); |
404 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 410 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
@@ -411,9 +417,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
411 | crypto_connections[i].sessionpublic_key) == 1) { | 417 | crypto_connections[i].sessionpublic_key) == 1) { |
412 | increment_nonce(crypto_connections[i].recv_nonce); | 418 | increment_nonce(crypto_connections[i].recv_nonce); |
413 | uint32_t zero = 0; | 419 | uint32_t zero = 0; |
414 | crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ | 420 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
415 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 421 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); |
416 | crypto_connections[i].status = 2; /* set it to its proper value right after. */ | 422 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ |
417 | return i; | 423 | return i; |
418 | } | 424 | } |
419 | return -1; /* this should never happen. */ | 425 | return -1; /* this should never happen. */ |
@@ -429,7 +435,7 @@ int is_cryptoconnected(int crypt_connection_id) | |||
429 | { | 435 | { |
430 | if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) | 436 | if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) |
431 | return crypto_connections[crypt_connection_id].status; | 437 | return crypto_connections[crypt_connection_id].status; |
432 | return 0; | 438 | return CONN_NO_CONNECTION; |
433 | } | 439 | } |
434 | 440 | ||
435 | /* Generate our public and private keys | 441 | /* Generate our public and private keys |
@@ -488,7 +494,7 @@ static void receive_crypto() | |||
488 | { | 494 | { |
489 | uint32_t i; | 495 | uint32_t i; |
490 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 496 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { |
491 | if (crypto_connections[i].status == 1) { | 497 | if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { |
492 | uint8_t temp_data[MAX_DATA_SIZE]; | 498 | uint8_t temp_data[MAX_DATA_SIZE]; |
493 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 499 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
494 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 500 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
@@ -505,17 +511,17 @@ static void receive_crypto() | |||
505 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 511 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
506 | increment_nonce(crypto_connections[i].sent_nonce); | 512 | increment_nonce(crypto_connections[i].sent_nonce); |
507 | uint32_t zero = 0; | 513 | uint32_t zero = 0; |
508 | crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ | 514 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
509 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 515 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); |
510 | crypto_connections[i].status = 2; /* set it to its proper value right after. */ | 516 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ |
511 | } | 517 | } |
512 | } | 518 | } |
513 | } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does | 519 | } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does |
514 | crypto_kill(crypto_connections[i].number); | 520 | crypto_kill(crypto_connections[i].number); |
515 | 521 | ||
516 | } | 522 | } |
517 | if (crypto_connections[i].status == 2) { | 523 | if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { |
518 | if (id_packet(crypto_connections[i].number) == 3) { | 524 | if (id_packet(crypto_connections[i].number) == CONN_ESTABLISHED) { |
519 | uint8_t temp_data[MAX_DATA_SIZE]; | 525 | uint8_t temp_data[MAX_DATA_SIZE]; |
520 | uint8_t data[MAX_DATA_SIZE]; | 526 | uint8_t data[MAX_DATA_SIZE]; |
521 | int length = read_packet(crypto_connections[i].number, temp_data); | 527 | int length = read_packet(crypto_connections[i].number, temp_data); |
@@ -525,7 +531,7 @@ static void receive_crypto() | |||
525 | uint32_t zero = 0; | 531 | uint32_t zero = 0; |
526 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { | 532 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { |
527 | increment_nonce(crypto_connections[i].recv_nonce); | 533 | increment_nonce(crypto_connections[i].recv_nonce); |
528 | crypto_connections[i].status = 3; | 534 | crypto_connections[i].status = CONN_ESTABLISHED; |
529 | 535 | ||
530 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ | 536 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ |
531 | kill_connection_in(crypto_connections[i].number, 3000000); | 537 | kill_connection_in(crypto_connections[i].number, 3000000); |
@@ -554,8 +560,8 @@ static void killTimedout() | |||
554 | { | 560 | { |
555 | uint32_t i; | 561 | uint32_t i; |
556 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 562 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { |
557 | if (crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4) | 563 | if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4) |
558 | crypto_connections[i].status = 4; | 564 | crypto_connections[i].status = CONN_TIMED_OUT; |
559 | else if (is_connected(crypto_connections[i].number) == 4) { | 565 | else if (is_connected(crypto_connections[i].number) == 4) { |
560 | kill_connection(crypto_connections[i].number); | 566 | kill_connection(crypto_connections[i].number); |
561 | crypto_connections[i].number = ~0; | 567 | crypto_connections[i].number = ~0; |