diff options
-rw-r--r-- | core/DHT.c | 44 | ||||
-rw-r--r-- | core/DHT.h | 16 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 65 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 19 | ||||
-rw-r--r-- | core/net_crypto.c | 622 | ||||
-rw-r--r-- | core/net_crypto.h | 108 | ||||
-rw-r--r-- | core/network.c | 8 | ||||
-rw-r--r-- | core/network.h | 4 | ||||
-rw-r--r-- | testing/DHT_cryptosendfiletest.c | 251 | ||||
-rw-r--r-- | testing/DHT_test.c | 6 |
10 files changed, 1087 insertions, 56 deletions
@@ -27,13 +27,13 @@ | |||
27 | 27 | ||
28 | #include "DHT.h" | 28 | #include "DHT.h" |
29 | 29 | ||
30 | char self_client_id[CLIENT_ID_SIZE]; | 30 | uint8_t self_client_id[CLIENT_ID_SIZE]; |
31 | 31 | ||
32 | //Compares client_id1 and client_id2 with client_id | 32 | //Compares client_id1 and client_id2 with client_id |
33 | //return 0 if both are same distance | 33 | //return 0 if both are same distance |
34 | //return 1 if client_id1 is closer. | 34 | //return 1 if client_id1 is closer. |
35 | //return 2 if client_id2 is closer. | 35 | //return 2 if client_id2 is closer. |
36 | int id_closest(char * client_id, char * client_id1, char * client_id2)//tested | 36 | int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2)//tested |
37 | { | 37 | { |
38 | uint32_t i; | 38 | uint32_t i; |
39 | for(i = 0; i < CLIENT_ID_SIZE; i++) | 39 | for(i = 0; i < CLIENT_ID_SIZE; i++) |
@@ -58,7 +58,7 @@ int id_closest(char * client_id, char * client_id1, char * client_id2)//tested | |||
58 | //if the ip_port is already in the list but associated to a different ip, change it. | 58 | //if the ip_port is already in the list but associated to a different ip, change it. |
59 | //return True(1) or False(0) | 59 | //return True(1) or False(0) |
60 | //TODO: maybe optimize this. | 60 | //TODO: maybe optimize this. |
61 | int client_in_list(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port) | 61 | int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) |
62 | { | 62 | { |
63 | uint32_t i, j; | 63 | uint32_t i, j; |
64 | uint32_t temp_time = unix_time(); | 64 | uint32_t temp_time = unix_time(); |
@@ -92,7 +92,7 @@ int client_in_list(Client_data * list, uint32_t length, char * client_id, IP_Por | |||
92 | 92 | ||
93 | //check if client with client_id is already in node format list of length length. | 93 | //check if client with client_id is already in node format list of length length. |
94 | //return True(1) or False(0) | 94 | //return True(1) or False(0) |
95 | int client_in_nodelist(Node_format * list, uint32_t length, char * client_id) | 95 | int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) |
96 | { | 96 | { |
97 | uint32_t i, j; | 97 | uint32_t i, j; |
98 | for(i = 0; i < length; i++) | 98 | for(i = 0; i < length; i++) |
@@ -126,7 +126,7 @@ int client_in_nodelist(Node_format * list, uint32_t length, char * client_id) | |||
126 | //Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: | 126 | //Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: |
127 | //put them in the nodes_list and return how many were found. | 127 | //put them in the nodes_list and return how many were found. |
128 | //TODO: Make this function much more efficient. | 128 | //TODO: Make this function much more efficient. |
129 | int get_close_nodes(char * client_id, Node_format * nodes_list) | 129 | int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) |
130 | { | 130 | { |
131 | uint32_t i, j, k; | 131 | uint32_t i, j, k; |
132 | int num_nodes=0; | 132 | int num_nodes=0; |
@@ -191,7 +191,7 @@ int get_close_nodes(char * client_id, Node_format * nodes_list) | |||
191 | //replace first bad (or empty) node with this one | 191 | //replace first bad (or empty) node with this one |
192 | //return 0 if successfull | 192 | //return 0 if successfull |
193 | //return 1 if not (list contains no bad nodes) | 193 | //return 1 if not (list contains no bad nodes) |
194 | int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port)//tested | 194 | int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port)//tested |
195 | { | 195 | { |
196 | uint32_t i; | 196 | uint32_t i; |
197 | uint32_t temp_time = unix_time(); | 197 | uint32_t temp_time = unix_time(); |
@@ -210,7 +210,7 @@ int replace_bad(Client_data * list, uint32_t length, char * client_id, IP_Port i | |||
210 | } | 210 | } |
211 | 211 | ||
212 | //replace the first good node that is further to the comp_client_id than that of the client_id in the list | 212 | //replace the first good node that is further to the comp_client_id than that of the client_id in the list |
213 | int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port ip_port, char * comp_client_id) | 213 | int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id) |
214 | { | 214 | { |
215 | uint32_t i; | 215 | uint32_t i; |
216 | uint32_t temp_time = unix_time(); | 216 | uint32_t temp_time = unix_time(); |
@@ -230,7 +230,7 @@ int replace_good(Client_data * list, uint32_t length, char * client_id, IP_Port | |||
230 | } | 230 | } |
231 | 231 | ||
232 | //Attempt to add client with ip_port and client_id to the friends client list and close_clientlist | 232 | //Attempt to add client with ip_port and client_id to the friends client list and close_clientlist |
233 | void addto_lists(IP_Port ip_port, char * client_id) | 233 | void addto_lists(IP_Port ip_port, uint8_t * client_id) |
234 | { | 234 | { |
235 | uint32_t i; | 235 | uint32_t i; |
236 | 236 | ||
@@ -414,7 +414,7 @@ int pingreq(IP_Port ip_port) | |||
414 | return 1; | 414 | return 1; |
415 | } | 415 | } |
416 | 416 | ||
417 | char data[5 + CLIENT_ID_SIZE]; | 417 | uint8_t data[5 + CLIENT_ID_SIZE]; |
418 | data[0] = 0; | 418 | data[0] = 0; |
419 | memcpy(data + 1, &ping_id, 4); | 419 | memcpy(data + 1, &ping_id, 4); |
420 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); | 420 | memcpy(data + 5, self_client_id, CLIENT_ID_SIZE); |
@@ -427,7 +427,7 @@ int pingreq(IP_Port ip_port) | |||
427 | //send a ping response | 427 | //send a ping response |
428 | int pingres(IP_Port ip_port, uint32_t ping_id) | 428 | int pingres(IP_Port ip_port, uint32_t ping_id) |
429 | { | 429 | { |
430 | char data[5 + CLIENT_ID_SIZE]; | 430 | uint8_t data[5 + CLIENT_ID_SIZE]; |
431 | data[0] = 1; | 431 | data[0] = 1; |
432 | 432 | ||
433 | memcpy(data + 1, &ping_id, 4); | 433 | memcpy(data + 1, &ping_id, 4); |
@@ -438,7 +438,7 @@ int pingres(IP_Port ip_port, uint32_t ping_id) | |||
438 | } | 438 | } |
439 | 439 | ||
440 | //send a getnodes request | 440 | //send a getnodes request |
441 | int getnodes(IP_Port ip_port, char * client_id) | 441 | int getnodes(IP_Port ip_port, uint8_t * client_id) |
442 | { | 442 | { |
443 | if(is_gettingnodes(ip_port, 0)) | 443 | if(is_gettingnodes(ip_port, 0)) |
444 | { | 444 | { |
@@ -452,7 +452,7 @@ int getnodes(IP_Port ip_port, char * client_id) | |||
452 | return 1; | 452 | return 1; |
453 | } | 453 | } |
454 | 454 | ||
455 | char data[5 + CLIENT_ID_SIZE*2]; | 455 | uint8_t data[5 + CLIENT_ID_SIZE*2]; |
456 | data[0] = 2; | 456 | data[0] = 2; |
457 | 457 | ||
458 | memcpy(data + 1, &ping_id, 4); | 458 | memcpy(data + 1, &ping_id, 4); |
@@ -465,9 +465,9 @@ int getnodes(IP_Port ip_port, char * client_id) | |||
465 | 465 | ||
466 | 466 | ||
467 | //send a send nodes response | 467 | //send a send nodes response |
468 | int sendnodes(IP_Port ip_port, char * client_id, uint32_t ping_id) | 468 | int sendnodes(IP_Port ip_port, uint8_t * client_id, uint32_t ping_id) |
469 | { | 469 | { |
470 | char data[5 + CLIENT_ID_SIZE + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES]; | 470 | uint8_t data[5 + CLIENT_ID_SIZE + (CLIENT_ID_SIZE + sizeof(IP_Port))*MAX_SENT_NODES]; |
471 | Node_format nodes_list[MAX_SENT_NODES]; | 471 | Node_format nodes_list[MAX_SENT_NODES]; |
472 | 472 | ||
473 | int num_nodes = get_close_nodes(client_id, nodes_list); | 473 | int num_nodes = get_close_nodes(client_id, nodes_list); |
@@ -493,7 +493,7 @@ int sendnodes(IP_Port ip_port, char * client_id, uint32_t ping_id) | |||
493 | //Packet handling functions | 493 | //Packet handling functions |
494 | //One to handle each types of packets we recieve | 494 | //One to handle each types of packets we recieve |
495 | //return 0 if handled correctly, 1 if packet is bad. | 495 | //return 0 if handled correctly, 1 if packet is bad. |
496 | int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested | 496 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)//tested |
497 | { | 497 | { |
498 | if(length != 5 + CLIENT_ID_SIZE) | 498 | if(length != 5 + CLIENT_ID_SIZE) |
499 | { | 499 | { |
@@ -518,7 +518,7 @@ int handle_pingreq(char * packet, uint32_t length, IP_Port source)//tested | |||
518 | 518 | ||
519 | } | 519 | } |
520 | 520 | ||
521 | int handle_pingres(char * packet, uint32_t length, IP_Port source) | 521 | int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) |
522 | { | 522 | { |
523 | if(length != (5 + CLIENT_ID_SIZE)) | 523 | if(length != (5 + CLIENT_ID_SIZE)) |
524 | { | 524 | { |
@@ -536,7 +536,7 @@ int handle_pingres(char * packet, uint32_t length, IP_Port source) | |||
536 | 536 | ||
537 | } | 537 | } |
538 | 538 | ||
539 | int handle_getnodes(char * packet, uint32_t length, IP_Port source) | 539 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) |
540 | { | 540 | { |
541 | if(length != (5 + CLIENT_ID_SIZE*2)) | 541 | if(length != (5 + CLIENT_ID_SIZE*2)) |
542 | { | 542 | { |
@@ -559,7 +559,7 @@ int handle_getnodes(char * packet, uint32_t length, IP_Port source) | |||
559 | 559 | ||
560 | } | 560 | } |
561 | 561 | ||
562 | int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested | 562 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)//tested |
563 | { | 563 | { |
564 | if(length > (5 + CLIENT_ID_SIZE + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port))) || | 564 | if(length > (5 + CLIENT_ID_SIZE + MAX_SENT_NODES * (CLIENT_ID_SIZE + sizeof(IP_Port))) || |
565 | (length - 5 - CLIENT_ID_SIZE) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0) | 565 | (length - 5 - CLIENT_ID_SIZE) % (CLIENT_ID_SIZE + sizeof(IP_Port)) != 0) |
@@ -593,7 +593,7 @@ int handle_sendnodes(char * packet, uint32_t length, IP_Port source)//tested | |||
593 | 593 | ||
594 | 594 | ||
595 | 595 | ||
596 | int addfriend(char * client_id) | 596 | int addfriend(uint8_t * client_id) |
597 | { | 597 | { |
598 | //TODO:Maybe make the array of friends dynamic instead of a static array with MAX_FRIENDS | 598 | //TODO:Maybe make the array of friends dynamic instead of a static array with MAX_FRIENDS |
599 | if(MAX_FRIENDS > num_friends) | 599 | if(MAX_FRIENDS > num_friends) |
@@ -610,7 +610,7 @@ int addfriend(char * client_id) | |||
610 | 610 | ||
611 | 611 | ||
612 | 612 | ||
613 | int delfriend(char * client_id) | 613 | int delfriend(uint8_t * client_id) |
614 | { | 614 | { |
615 | uint32_t i; | 615 | uint32_t i; |
616 | for(i = 0; i < num_friends; i++) | 616 | for(i = 0; i < num_friends; i++) |
@@ -630,7 +630,7 @@ int delfriend(char * client_id) | |||
630 | 630 | ||
631 | 631 | ||
632 | //TODO: Optimize this. | 632 | //TODO: Optimize this. |
633 | IP_Port getfriendip(char * client_id) | 633 | IP_Port getfriendip(uint8_t * client_id) |
634 | { | 634 | { |
635 | uint32_t i, j; | 635 | uint32_t i, j; |
636 | IP_Port empty = {{{0}}, 0}; | 636 | IP_Port empty = {{{0}}, 0}; |
@@ -660,7 +660,7 @@ IP_Port getfriendip(char * client_id) | |||
660 | 660 | ||
661 | 661 | ||
662 | 662 | ||
663 | int DHT_handlepacket(char * packet, uint32_t length, IP_Port source) | 663 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) |
664 | { | 664 | { |
665 | switch (packet[0]) { | 665 | switch (packet[0]) { |
666 | case 0: | 666 | case 0: |
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | typedef struct | 37 | typedef struct |
38 | { | 38 | { |
39 | char client_id[CLIENT_ID_SIZE]; | 39 | uint8_t client_id[CLIENT_ID_SIZE]; |
40 | IP_Port ip_port; | 40 | IP_Port ip_port; |
41 | uint32_t timestamp; | 41 | uint32_t timestamp; |
42 | uint32_t last_pinged; | 42 | uint32_t last_pinged; |
@@ -45,7 +45,7 @@ typedef struct | |||
45 | #define MAX_FRIEND_CLIENTS 8 | 45 | #define MAX_FRIEND_CLIENTS 8 |
46 | typedef struct | 46 | typedef struct |
47 | { | 47 | { |
48 | char client_id[CLIENT_ID_SIZE]; | 48 | uint8_t client_id[CLIENT_ID_SIZE]; |
49 | Client_data client_list[MAX_FRIEND_CLIENTS]; | 49 | Client_data client_list[MAX_FRIEND_CLIENTS]; |
50 | 50 | ||
51 | }Friend; | 51 | }Friend; |
@@ -53,7 +53,7 @@ typedef struct | |||
53 | 53 | ||
54 | typedef struct | 54 | typedef struct |
55 | { | 55 | { |
56 | char client_id[CLIENT_ID_SIZE]; | 56 | uint8_t client_id[CLIENT_ID_SIZE]; |
57 | IP_Port ip_port; | 57 | IP_Port ip_port; |
58 | }Node_format; | 58 | }Node_format; |
59 | 59 | ||
@@ -70,13 +70,13 @@ typedef struct | |||
70 | //client_id must be CLIENT_ID_SIZE bytes long. | 70 | //client_id must be CLIENT_ID_SIZE bytes long. |
71 | //returns 0 if success | 71 | //returns 0 if success |
72 | //returns 1 if failure (friends list is full) | 72 | //returns 1 if failure (friends list is full) |
73 | int addfriend(char * client_id); | 73 | int addfriend(uint8_t * client_id); |
74 | 74 | ||
75 | //Delete a friend from the friends list | 75 | //Delete a friend from the friends list |
76 | //client_id must be CLIENT_ID_SIZE bytes long. | 76 | //client_id must be CLIENT_ID_SIZE bytes long. |
77 | //returns 0 if success | 77 | //returns 0 if success |
78 | //returns 1 if failure (client_id not in friends list) | 78 | //returns 1 if failure (client_id not in friends list) |
79 | int delfriend(char * client_id); | 79 | int delfriend(uint8_t * client_id); |
80 | 80 | ||
81 | 81 | ||
82 | //Get ip of friend | 82 | //Get ip of friend |
@@ -86,7 +86,7 @@ int delfriend(char * client_id); | |||
86 | //returns ip if success | 86 | //returns ip if success |
87 | //returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) | 87 | //returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) |
88 | //returns ip of 1 if friend is not in list. | 88 | //returns ip of 1 if friend is not in list. |
89 | IP_Port getfriendip(char * client_id); | 89 | IP_Port getfriendip(uint8_t * client_id); |
90 | 90 | ||
91 | 91 | ||
92 | //Run this function at least a couple times per second (It's the main loop) | 92 | //Run this function at least a couple times per second (It's the main loop) |
@@ -95,7 +95,7 @@ void doDHT(); | |||
95 | //if we recieve a DHT packet we call this function so it can be handled. | 95 | //if we recieve a DHT packet we call this function so it can be handled. |
96 | //Return 0 if packet is handled correctly. | 96 | //Return 0 if packet is handled correctly. |
97 | //return 1 if it didn't handle the packet or if the packet was shit. | 97 | //return 1 if it didn't handle the packet or if the packet was shit. |
98 | int DHT_handlepacket(char * packet, uint32_t length, IP_Port source); | 98 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); |
99 | 99 | ||
100 | //Use this function to bootstrap the client | 100 | //Use this function to bootstrap the client |
101 | //Sends a get nodes request to the given ip port | 101 | //Sends a get nodes request to the given ip port |
@@ -109,7 +109,7 @@ void bootstrap(IP_Port ip_port); | |||
109 | //Global variables | 109 | //Global variables |
110 | 110 | ||
111 | //Our client id | 111 | //Our client id |
112 | extern char self_client_id[CLIENT_ID_SIZE]; | 112 | extern uint8_t self_client_id[CLIENT_ID_SIZE]; |
113 | 113 | ||
114 | 114 | ||
115 | //TODO: Move these out of here and put them into the .c file. | 115 | //TODO: Move these out of here and put them into the .c file. |
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index bcbfb18a..b249760a 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -47,18 +47,19 @@ | |||
47 | 47 | ||
48 | typedef struct | 48 | typedef struct |
49 | { | 49 | { |
50 | char data[MAX_DATA_SIZE]; | 50 | uint8_t data[MAX_DATA_SIZE]; |
51 | uint16_t size; | 51 | uint16_t size; |
52 | }Data; | 52 | }Data; |
53 | 53 | ||
54 | typedef struct | 54 | typedef struct |
55 | { | 55 | { |
56 | IP_Port ip_port; | 56 | IP_Port ip_port; |
57 | char status;//0 if connection is dead, 1 if attempting handshake, | 57 | uint8_t status;//0 if connection is dead, 1 if attempting handshake, |
58 | //2 if handshake is done (we start sending SYNC packets) | 58 | //2 if handshake is done (we start sending SYNC packets) |
59 | //3 if we are sending SYNC packets and can send data | 59 | //3 if we are sending SYNC packets and can send data |
60 | //4 if the connection has timed out. | ||
60 | 61 | ||
61 | char inbound; //1 or 2 if connection was initiated by someone else, 0 if not. | 62 | uint8_t inbound; //1 or 2 if connection was initiated by someone else, 0 if not. |
62 | //2 if incoming_connection() has not returned it yet, 1 if it has. | 63 | //2 if incoming_connection() has not returned it yet, 1 if it has. |
63 | 64 | ||
64 | uint16_t SYNC_rate;//current SYNC packet send rate packets per second. | 65 | uint16_t SYNC_rate;//current SYNC packet send rate packets per second. |
@@ -66,6 +67,7 @@ typedef struct | |||
66 | uint64_t last_SYNC; //time at which our last SYNC packet was sent. | 67 | uint64_t last_SYNC; //time at which our last SYNC packet was sent. |
67 | uint64_t last_sent; //time at which our last data or handshake packet was sent. | 68 | uint64_t last_sent; //time at which our last data or handshake packet was sent. |
68 | uint64_t last_recv; //time at which we last recieved something from the other | 69 | uint64_t last_recv; //time at which we last recieved something from the other |
70 | uint64_t killat; //time at which to kill the connection | ||
69 | Data sendbuffer[MAX_QUEUE_NUM];//packet send buffer. | 71 | Data sendbuffer[MAX_QUEUE_NUM];//packet send buffer. |
70 | Data recvbuffer[MAX_QUEUE_NUM];//packet recieve buffer. | 72 | Data recvbuffer[MAX_QUEUE_NUM];//packet recieve buffer. |
71 | uint32_t handshake_id1; | 73 | uint32_t handshake_id1; |
@@ -160,6 +162,7 @@ int new_connection(IP_Port ip_port) | |||
160 | connections[i].SYNC_rate = SYNC_RATE; | 162 | connections[i].SYNC_rate = SYNC_RATE; |
161 | connections[i].data_rate = DATA_SYNC_RATE; | 163 | connections[i].data_rate = DATA_SYNC_RATE; |
162 | connections[i].last_recv = current_time(); | 164 | connections[i].last_recv = current_time(); |
165 | connections[i].killat = ~0; | ||
163 | connections[i].send_counter = 0; | 166 | connections[i].send_counter = 0; |
164 | return i; | 167 | return i; |
165 | } | 168 | } |
@@ -187,6 +190,7 @@ int new_inconnection(IP_Port ip_port) | |||
187 | connections[i].SYNC_rate = SYNC_RATE; | 190 | connections[i].SYNC_rate = SYNC_RATE; |
188 | connections[i].data_rate = DATA_SYNC_RATE; | 191 | connections[i].data_rate = DATA_SYNC_RATE; |
189 | connections[i].last_recv = current_time(); | 192 | connections[i].last_recv = current_time(); |
193 | connections[i].killat = ~0; | ||
190 | connections[i].send_counter = 127; | 194 | connections[i].send_counter = 127; |
191 | return i; | 195 | return i; |
192 | } | 196 | } |
@@ -225,11 +229,28 @@ int kill_connection(int connection_id) | |||
225 | return -1; | 229 | return -1; |
226 | } | 230 | } |
227 | 231 | ||
232 | //kill connection in seconds seconds. | ||
233 | //return -1 if it can not kill the connection. | ||
234 | //return 0 if it will kill it | ||
235 | int kill_connection_in(int connection_id, uint32_t seconds) | ||
236 | { | ||
237 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) | ||
238 | { | ||
239 | if(connections[connection_id].status > 0) | ||
240 | { | ||
241 | connections[connection_id].killat = current_time() + 1000000UL*seconds; | ||
242 | return 0; | ||
243 | } | ||
244 | } | ||
245 | return -1; | ||
246 | } | ||
247 | |||
228 | //check if connection is connected | 248 | //check if connection is connected |
229 | //return 0 no. | 249 | //return 0 no. |
230 | //return 1 if attempting handshake | 250 | //return 1 if attempting handshake |
231 | //return 2 if handshake is done | 251 | //return 2 if handshake is done |
232 | //return 3 if fully connected | 252 | //return 3 if fully connected |
253 | //return 4 if timed out and wating to be killed | ||
233 | int is_connected(int connection_id) | 254 | int is_connected(int connection_id) |
234 | { | 255 | { |
235 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 256 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
@@ -262,9 +283,19 @@ uint32_t recvqueue(int connection_id) | |||
262 | return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; | 283 | return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; |
263 | } | 284 | } |
264 | 285 | ||
286 | //returns the id of the next packet in the queue | ||
287 | //return -1 if no packet in queue | ||
288 | char id_packet(int connection_id) | ||
289 | { | ||
290 | if(recvqueue(connection_id) != 0 && connections[connection_id].status != 0) | ||
291 | { | ||
292 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; | ||
293 | } | ||
294 | return -1; | ||
295 | } | ||
265 | //return 0 if there is no received data in the buffer. | 296 | //return 0 if there is no received data in the buffer. |
266 | //return length of received packet if successful | 297 | //return length of received packet if successful |
267 | int read_packet(int connection_id, char * data) | 298 | int read_packet(int connection_id, uint8_t * data) |
268 | { | 299 | { |
269 | if(recvqueue(connection_id) != 0) | 300 | if(recvqueue(connection_id) != 0) |
270 | { | 301 | { |
@@ -280,7 +311,7 @@ int read_packet(int connection_id, char * data) | |||
280 | 311 | ||
281 | //return 0 if data could not be put in packet queue | 312 | //return 0 if data could not be put in packet queue |
282 | //return 1 if data was put into the queue | 313 | //return 1 if data was put into the queue |
283 | int write_packet(int connection_id, char * data, uint32_t length) | 314 | int write_packet(int connection_id, uint8_t * data, uint32_t length) |
284 | { | 315 | { |
285 | if(length > MAX_DATA_SIZE) | 316 | if(length > MAX_DATA_SIZE) |
286 | { | 317 | { |
@@ -338,7 +369,7 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
338 | 369 | ||
339 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 370 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) |
340 | { | 371 | { |
341 | char packet[1 + 4 + 4]; | 372 | uint8_t packet[1 + 4 + 4]; |
342 | uint32_t temp; | 373 | uint32_t temp; |
343 | 374 | ||
344 | packet[0] = 16; | 375 | packet[0] = 16; |
@@ -354,7 +385,7 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i | |||
354 | int send_SYNC(uint32_t connection_id) | 385 | int send_SYNC(uint32_t connection_id) |
355 | { | 386 | { |
356 | 387 | ||
357 | char packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; | 388 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; |
358 | uint16_t index = 0; | 389 | uint16_t index = 0; |
359 | 390 | ||
360 | IP_Port ip_port = connections[connection_id].ip_port; | 391 | IP_Port ip_port = connections[connection_id].ip_port; |
@@ -382,7 +413,7 @@ int send_data_packet(uint32_t connection_id, uint32_t packet_num) | |||
382 | { | 413 | { |
383 | uint32_t index = packet_num % MAX_QUEUE_NUM; | 414 | uint32_t index = packet_num % MAX_QUEUE_NUM; |
384 | uint32_t temp; | 415 | uint32_t temp; |
385 | char packet[1 + 4 + MAX_DATA_SIZE]; | 416 | uint8_t packet[1 + 4 + MAX_DATA_SIZE]; |
386 | packet[0] = 18; | 417 | packet[0] = 18; |
387 | temp = htonl(packet_num); | 418 | temp = htonl(packet_num); |
388 | memcpy(packet + 1, &temp, 4); | 419 | memcpy(packet + 1, &temp, 4); |
@@ -421,7 +452,7 @@ int send_DATA(uint32_t connection_id) | |||
421 | //Packet handling functions | 452 | //Packet handling functions |
422 | //One to handle each type of packets we recieve | 453 | //One to handle each type of packets we recieve |
423 | //return 0 if handled correctly, 1 if packet is bad. | 454 | //return 0 if handled correctly, 1 if packet is bad. |
424 | int handle_handshake(char * packet, uint32_t length, IP_Port source) | 455 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) |
425 | { | 456 | { |
426 | if(length != (1 + 4 + 4)) | 457 | if(length != (1 + 4 + 4)) |
427 | { | 458 | { |
@@ -538,7 +569,7 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
538 | return 1; | 569 | return 1; |
539 | } | 570 | } |
540 | 571 | ||
541 | int handle_SYNC(char * packet, uint32_t length, IP_Port source) | 572 | int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source) |
542 | { | 573 | { |
543 | 574 | ||
544 | if(!SYNC_valid(length)) | 575 | if(!SYNC_valid(length)) |
@@ -578,7 +609,7 @@ int handle_SYNC(char * packet, uint32_t length, IP_Port source) | |||
578 | 609 | ||
579 | //add a packet to the recieved buffer and set the recv_packetnum of the connection to its proper value. | 610 | //add a packet to the recieved buffer and set the recv_packetnum of the connection to its proper value. |
580 | //return 1 if data was too big, 0 if not. | 611 | //return 1 if data was too big, 0 if not. |
581 | int add_recv(int connection_id, uint32_t data_num, char * data, uint16_t size) | 612 | int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size) |
582 | { | 613 | { |
583 | if(size > MAX_DATA_SIZE) | 614 | if(size > MAX_DATA_SIZE) |
584 | { | 615 | { |
@@ -616,7 +647,7 @@ int add_recv(int connection_id, uint32_t data_num, char * data, uint16_t size) | |||
616 | return 0; | 647 | return 0; |
617 | } | 648 | } |
618 | 649 | ||
619 | int handle_data(char * packet, uint32_t length, IP_Port source) | 650 | int handle_data(uint8_t * packet, uint32_t length, IP_Port source) |
620 | { | 651 | { |
621 | int connection = getconnection_id(source); | 652 | int connection = getconnection_id(source); |
622 | 653 | ||
@@ -641,7 +672,7 @@ int handle_data(char * packet, uint32_t length, IP_Port source) | |||
641 | //END of packet handling functions | 672 | //END of packet handling functions |
642 | 673 | ||
643 | 674 | ||
644 | int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source) | 675 | int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) |
645 | { | 676 | { |
646 | 677 | ||
647 | switch (packet[0]) { | 678 | switch (packet[0]) { |
@@ -681,7 +712,13 @@ void doNew() | |||
681 | 712 | ||
682 | } | 713 | } |
683 | //kill all timed out connections | 714 | //kill all timed out connections |
684 | if( connections[i].status > 0 && (connections[i].last_recv + CONNEXION_TIMEOUT * 1000000UL) < temp_time) | 715 | if( connections[i].status > 0 && (connections[i].last_recv + CONNEXION_TIMEOUT * 1000000UL) < temp_time && |
716 | connections[i].status != 4) | ||
717 | { | ||
718 | //kill_connection(i); | ||
719 | connections[i].status = 4; | ||
720 | } | ||
721 | if(connections[i].status > 0 && connections[i].killat < temp_time) | ||
685 | { | 722 | { |
686 | kill_connection(i); | 723 | kill_connection(i); |
687 | } | 724 | } |
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h index 8bdeb43e..18224088 100644 --- a/core/Lossless_UDP.h +++ b/core/Lossless_UDP.h | |||
@@ -41,6 +41,10 @@ | |||
41 | //if there already was an existing connection to that ip_port return its number. | 41 | //if there already was an existing connection to that ip_port return its number. |
42 | int new_connection(IP_Port ip_port); | 42 | int new_connection(IP_Port ip_port); |
43 | 43 | ||
44 | //get connection id from IP_Port | ||
45 | //return -1 if there are no connections like we are looking for | ||
46 | //return id if it found it | ||
47 | int getconnection_id(IP_Port ip_port); | ||
44 | 48 | ||
45 | //returns an integer corresponding to the next connection in our imcoming connection list | 49 | //returns an integer corresponding to the next connection in our imcoming connection list |
46 | //return -1 if there are no new incoming connections in the list. | 50 | //return -1 if there are no new incoming connections in the list. |
@@ -51,20 +55,28 @@ int incoming_connection(); | |||
51 | //return 0 if killed successfully | 55 | //return 0 if killed successfully |
52 | int kill_connection(int connection_id); | 56 | int kill_connection(int connection_id); |
53 | 57 | ||
58 | //kill connection in seconds seconds. | ||
59 | //return -1 if it can not kill the connection. | ||
60 | //return 0 if it will kill it | ||
61 | int kill_connection_in(int connection_id, uint32_t seconds); | ||
54 | 62 | ||
55 | //returns the ip_port of the corresponding connection. | 63 | //returns the ip_port of the corresponding connection. |
56 | //return 0 if there is no such connection. | 64 | //return 0 if there is no such connection. |
57 | IP_Port connection_ip(int connection_id); | 65 | IP_Port connection_ip(int connection_id); |
58 | 66 | ||
67 | //returns the id of the next packet in the queue | ||
68 | //return -1 if no packet in queue | ||
69 | char id_packet(int connection_id); | ||
59 | 70 | ||
60 | //return 0 if there is no received data in the buffer. | 71 | //return 0 if there is no received data in the buffer. |
61 | //return length of recieved packet if successful | 72 | //return length of recieved packet if successful |
62 | int read_packet(int connection_id, char * data); | 73 | int read_packet(int connection_id, uint8_t * data); |
63 | 74 | ||
64 | 75 | ||
65 | //return 0 if data could not be put in packet queue | 76 | //return 0 if data could not be put in packet queue |
66 | //return 1 if data was put into the queue | 77 | //return 1 if data was put into the queue |
67 | int write_packet(int connection_id, char * data, uint32_t length); | 78 | int write_packet(int connection_id, uint8_t * data, uint32_t length); |
79 | |||
68 | 80 | ||
69 | 81 | ||
70 | //returns the number of packets in the queue waiting to be successfully sent. | 82 | //returns the number of packets in the queue waiting to be successfully sent. |
@@ -80,6 +92,7 @@ uint32_t recvqueue(int connection_id); | |||
80 | //return 1 if attempting handshake | 92 | //return 1 if attempting handshake |
81 | //return 2 if handshake is done | 93 | //return 2 if handshake is done |
82 | //return 3 if fully connected | 94 | //return 3 if fully connected |
95 | //return 4 if timed out and wating to be killed | ||
83 | int is_connected(int connection_id); | 96 | int is_connected(int connection_id); |
84 | 97 | ||
85 | 98 | ||
@@ -91,6 +104,6 @@ void doLossless_UDP(); | |||
91 | //if we receive a Lossless_UDP packet we call this function so it can be handled. | 104 | //if we receive a Lossless_UDP packet we call this function so it can be handled. |
92 | //Return 0 if packet is handled correctly. | 105 | //Return 0 if packet is handled correctly. |
93 | //return 1 if it didn't handle the packet or if the packet was shit. | 106 | //return 1 if it didn't handle the packet or if the packet was shit. |
94 | int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source); | 107 | int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); |
95 | 108 | ||
96 | #endif | 109 | #endif |
diff --git a/core/net_crypto.c b/core/net_crypto.c new file mode 100644 index 00000000..38a72205 --- /dev/null +++ b/core/net_crypto.c | |||
@@ -0,0 +1,622 @@ | |||
1 | /* net_crypto.c | ||
2 | * | ||
3 | * Functions for the core network crypto. | ||
4 | * See also: docs/Crypto.txt | ||
5 | * | ||
6 | * NOTE: This code has to be perfect. We don't mess around with encryption. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | |||
11 | #include "net_crypto.h" | ||
12 | |||
13 | |||
14 | //Our public and secret keys. | ||
15 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
16 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
17 | |||
18 | |||
19 | typedef struct | ||
20 | { | ||
21 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
22 | uint8_t recv_nonce[crypto_box_NONCEBYTES];//nonce of recieved packets | ||
23 | uint8_t sent_nonce[crypto_box_NONCEBYTES];//nonce of sent packets. | ||
24 | uint8_t status;//0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
25 | //(we have recieved a hanshake but no empty data packet), 3 if the connection is established. | ||
26 | //4 if the connection is timed out. | ||
27 | uint16_t number; //Lossless_UDP connection number corresponding to this connection. | ||
28 | |||
29 | }Crypto_Connection; | ||
30 | |||
31 | #define MAX_CRYPTO_CONNECTIONS 256 | ||
32 | |||
33 | Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; | ||
34 | |||
35 | #define MAX_FRIEND_REQUESTS 32 | ||
36 | |||
37 | //keeps track of the connection numbers for friends request so we can check later if they were sent | ||
38 | int outbound_friendrequests[MAX_FRIEND_REQUESTS]; | ||
39 | |||
40 | #define MAX_INCOMING 64 | ||
41 | |||
42 | //keeps track of the connection numbers for friends request so we can check later if they were sent | ||
43 | int incoming_connections[MAX_INCOMING]; | ||
44 | |||
45 | //encrypts plain of length length to encrypted of length + 16 using the | ||
46 | //public key(32 bytes) of the reciever and a 24 byte nonce | ||
47 | //return -1 if there was a problem. | ||
48 | //return length of encrypted data if everything was fine. | ||
49 | int encrypt_data(uint8_t * public_key, uint8_t * nonce, uint8_t * plain, uint32_t length, uint8_t * encrypted) | ||
50 | { | ||
51 | if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) | ||
52 | { | ||
53 | return -1; | ||
54 | } | ||
55 | |||
56 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; | ||
57 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; | ||
58 | uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0}; | ||
59 | |||
60 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length);//pad the message with 32 0 bytes. | ||
61 | |||
62 | crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, self_secret_key); | ||
63 | |||
64 | //if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero | ||
65 | if(memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) | ||
66 | { | ||
67 | return -1; | ||
68 | } | ||
69 | //unpad the encrypted message | ||
70 | memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); | ||
71 | return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; | ||
72 | } | ||
73 | |||
74 | //decrypts encrypted of length length to plain of length length - 16 using the | ||
75 | //public key(32 bytes) of the sender and a 24 byte nonce | ||
76 | //return -1 if there was a problem(decryption failed) | ||
77 | //return length of plain data if everything was fine. | ||
78 | int decrypt_data(uint8_t * public_key, uint8_t * nonce, uint8_t * encrypted, uint32_t length, uint8_t * plain) | ||
79 | { | ||
80 | if(length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) | ||
81 | { | ||
82 | return -1; | ||
83 | } | ||
84 | uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; | ||
85 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; | ||
86 | uint8_t zeroes[crypto_box_ZEROBYTES] = {0}; | ||
87 | |||
88 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length);//pad the message with 16 0 bytes. | ||
89 | |||
90 | if(crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, | ||
91 | nonce, public_key, self_secret_key) == -1) | ||
92 | { | ||
93 | return -1; | ||
94 | } | ||
95 | //if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero | ||
96 | if(memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0) | ||
97 | { | ||
98 | return -1; | ||
99 | } | ||
100 | //unpad the plain message | ||
101 | memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES); | ||
102 | return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; | ||
103 | } | ||
104 | |||
105 | //increment the given nonce by 1 | ||
106 | void increment_nonce(uint8_t * nonce) | ||
107 | { | ||
108 | uint32_t i; | ||
109 | for(i = 0; i < crypto_box_NONCEBYTES; i++) | ||
110 | { | ||
111 | nonce[i]++; | ||
112 | if(nonce[i] != 0) | ||
113 | { | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | |||
119 | //fill the given nonce with random bytes. | ||
120 | //TODO: make this more optimized | ||
121 | void random_nonce(uint8_t * nonce) | ||
122 | { | ||
123 | uint32_t i; | ||
124 | for(i = 0; i < crypto_box_NONCEBYTES; i++) | ||
125 | { | ||
126 | nonce[i] = random_int() % 256; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | //return 0 if there is no received data in the buffer | ||
131 | //return -1 if the packet was discarded. | ||
132 | //return length of recieved data if successful | ||
133 | int read_cryptpacket(int crypt_connection_id, uint8_t * data) | ||
134 | { | ||
135 | if(crypto_connections[crypt_connection_id].status != 3) | ||
136 | { | ||
137 | return 0; | ||
138 | } | ||
139 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
140 | int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); | ||
141 | if(length == 0) | ||
142 | { | ||
143 | return 0; | ||
144 | } | ||
145 | if(temp_data[0] != 3) | ||
146 | { | ||
147 | return -1; | ||
148 | } | ||
149 | int len = decrypt_data(crypto_connections[crypt_connection_id].public_key, | ||
150 | crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); | ||
151 | if(len != -1) | ||
152 | { | ||
153 | increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); | ||
154 | return len; | ||
155 | } | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | |||
160 | //return 0 if data could not be put in packet queue | ||
161 | //return 1 if data was put into the queue | ||
162 | int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length) | ||
163 | { | ||
164 | if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | if(crypto_connections[crypt_connection_id].status != 3) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
173 | int len = encrypt_data(crypto_connections[crypt_connection_id].public_key, | ||
174 | crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); | ||
175 | if(len == -1) | ||
176 | { | ||
177 | return 0; | ||
178 | } | ||
179 | temp_data[0] = 3; | ||
180 | if(write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) | ||
181 | { | ||
182 | return 0; | ||
183 | } | ||
184 | increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); | ||
185 | return 1; | ||
186 | } | ||
187 | |||
188 | //send a friend request to peer with public_key and ip_port. | ||
189 | //Data represents the data we send with the friends request. | ||
190 | //returns -1 on failure | ||
191 | //returns a positive friend request id that can be used later to see if it was sent correctly on success. | ||
192 | int send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, uint32_t length) | ||
193 | { | ||
194 | if(length > MAX_DATA_SIZE - 1 - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES) | ||
195 | { | ||
196 | return -1; | ||
197 | } | ||
198 | uint32_t i; | ||
199 | for(i = 0; i < MAX_FRIEND_REQUESTS; i++) | ||
200 | { | ||
201 | if(outbound_friendrequests[i] == -1) | ||
202 | { | ||
203 | break; | ||
204 | } | ||
205 | } | ||
206 | if(i == MAX_FRIEND_REQUESTS) | ||
207 | { | ||
208 | return -1; | ||
209 | } | ||
210 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
211 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
212 | random_nonce(nonce); | ||
213 | int len = encrypt_data(public_key, nonce, data, length, 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | ||
214 | if(len == -1) | ||
215 | { | ||
216 | return -1; | ||
217 | } | ||
218 | temp_data[0] = 1; | ||
219 | memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | ||
220 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | ||
221 | int id = new_connection(ip_port); | ||
222 | if(id == -1) | ||
223 | { | ||
224 | return -1; | ||
225 | } | ||
226 | if(write_packet(id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES) == 1) | ||
227 | { | ||
228 | outbound_friendrequests[i] = id; | ||
229 | return i; | ||
230 | } | ||
231 | return -1; | ||
232 | } | ||
233 | |||
234 | //return -1 if failure | ||
235 | //return 0 if connection is still trying to send the request. | ||
236 | //return 1 if sent correctly | ||
237 | //return 2 if connection timed out | ||
238 | int check_friendrequest(int friend_request) | ||
239 | { | ||
240 | if(friend_request < 0 || friend_request > MAX_FRIEND_REQUESTS) | ||
241 | { | ||
242 | return -1; | ||
243 | } | ||
244 | if(outbound_friendrequests[friend_request] == -1) | ||
245 | { | ||
246 | return -1; | ||
247 | } | ||
248 | if(sendqueue(outbound_friendrequests[friend_request]) == 0) | ||
249 | { | ||
250 | kill_connection(outbound_friendrequests[friend_request]); | ||
251 | outbound_friendrequests[friend_request] = -1; | ||
252 | return 1; | ||
253 | } | ||
254 | int status = is_connected(outbound_friendrequests[friend_request]); | ||
255 | if(status == 4) | ||
256 | { | ||
257 | kill_connection(outbound_friendrequests[friend_request]); | ||
258 | outbound_friendrequests[friend_request] = -1; | ||
259 | return 2; | ||
260 | } | ||
261 | if(status == 0) | ||
262 | { | ||
263 | outbound_friendrequests[friend_request] = -1; | ||
264 | return 2; | ||
265 | } | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | //Send a crypto handshake packet containing an encrypted secret nonce to peer with connection_id and public_key | ||
270 | //the packet is encrypted with a random nonce which is sent in plain text with the packet | ||
271 | int send_cryptohandshake(int connection_id, uint8_t * public_key, uint8_t * secret_nonce) | ||
272 | { | ||
273 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
274 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
275 | random_nonce(nonce); | ||
276 | int len = encrypt_data(public_key, nonce, secret_nonce, crypto_box_NONCEBYTES, | ||
277 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | ||
278 | if(len == -1) | ||
279 | { | ||
280 | return 0; | ||
281 | } | ||
282 | temp_data[0] = 2; | ||
283 | memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | ||
284 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | ||
285 | return write_packet(connection_id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | ||
286 | } | ||
287 | |||
288 | //Extract secret nonce and public_key from a packet(data) with length length | ||
289 | //return 1 if successful | ||
290 | //return 0 if failure | ||
291 | int handle_cryptohandshake(uint8_t * public_key, uint8_t * secret_nonce, uint8_t * data, uint16_t length) | ||
292 | { | ||
293 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); | ||
294 | if(length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + pad) | ||
295 | { | ||
296 | return 0; | ||
297 | } | ||
298 | if(data[0] != 2) | ||
299 | { | ||
300 | return 0; | ||
301 | } | ||
302 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); | ||
303 | int len = decrypt_data(public_key, data + 1 + crypto_box_PUBLICKEYBYTES, | ||
304 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, crypto_box_NONCEBYTES + pad, secret_nonce); | ||
305 | if(len != crypto_box_NONCEBYTES) | ||
306 | { | ||
307 | return 0; | ||
308 | } | ||
309 | return 1; | ||
310 | } | ||
311 | |||
312 | |||
313 | //puts the public key of the friend if public_key, the data from the request | ||
314 | //in data if a friend request was sent to us and returns the length of the data. | ||
315 | //return -1 if no valid friend requests. | ||
316 | int handle_friendrequest(uint8_t * public_key, uint8_t * data) | ||
317 | { | ||
318 | uint32_t i; | ||
319 | for(i = 0; i < MAX_INCOMING; i++) | ||
320 | { | ||
321 | if(incoming_connections[i] != -1) | ||
322 | { | ||
323 | if(id_packet(incoming_connections[i]) == 1) | ||
324 | { | ||
325 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
326 | uint16_t len = read_packet(incoming_connections[i], temp_data); | ||
327 | if(len > crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1 | ||
328 | - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES) | ||
329 | { | ||
330 | memcpy(public_key, temp_data + 1, crypto_box_PUBLICKEYBYTES); | ||
331 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
332 | memcpy(nonce, temp_data + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_NONCEBYTES); | ||
333 | int len1 = decrypt_data(public_key, nonce, temp_data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | ||
334 | len - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + 1), data); | ||
335 | if(len1 != -1) | ||
336 | { | ||
337 | kill_connection_in(incoming_connections[i], 1); //conection is useless now, kill it in 1 seconds | ||
338 | incoming_connections[i] = -1; | ||
339 | return len1; | ||
340 | } | ||
341 | } | ||
342 | kill_connection(incoming_connections[i]); //conection is useless now, kill it. | ||
343 | incoming_connections[i] = -1; | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | return -1; | ||
348 | } | ||
349 | |||
350 | |||
351 | //Start a secure connection with other peer who has public_key and ip_port | ||
352 | //returns -1 if failure | ||
353 | //returns crypt_connection_id of the initialized connection if everything went well. | ||
354 | int crypto_connect(uint8_t * public_key, IP_Port ip_port) | ||
355 | { | ||
356 | uint32_t i; | ||
357 | if(getconnection_id(ip_port) != -1) | ||
358 | { | ||
359 | return -1; | ||
360 | } | ||
361 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) | ||
362 | { | ||
363 | if(crypto_connections[i].status == 0) | ||
364 | { | ||
365 | int id = new_connection(ip_port); | ||
366 | if(id == -1) | ||
367 | { | ||
368 | return -1; | ||
369 | } | ||
370 | crypto_connections[i].number = id; | ||
371 | crypto_connections[i].status = 1; | ||
372 | random_nonce(crypto_connections[i].recv_nonce); | ||
373 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | ||
374 | if(send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce) == 1) | ||
375 | { | ||
376 | increment_nonce(crypto_connections[i].recv_nonce); | ||
377 | return i; | ||
378 | } | ||
379 | return -1;//this should never happen. | ||
380 | } | ||
381 | } | ||
382 | return -1; | ||
383 | } | ||
384 | |||
385 | //handle an incoming connection | ||
386 | //return -1 if no crypto inbound connection | ||
387 | //return incomming connection id (Lossless_UDP one) if there is an incomming crypto connection | ||
388 | //Put the public key of the peer in public_key and the secret_nonce from the handshake into secret_nonce | ||
389 | //to accept it see: accept_crypto_inbound(...) | ||
390 | //to refuse it just call kill_connection(...) on the connection id | ||
391 | int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce) | ||
392 | { | ||
393 | uint32_t i; | ||
394 | for(i = 0; i < MAX_INCOMING; i++) | ||
395 | { | ||
396 | if(incoming_connections[i] != -1) | ||
397 | { | ||
398 | if(id_packet(incoming_connections[i]) == 2) | ||
399 | { | ||
400 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
401 | uint16_t len = read_packet(incoming_connections[i], temp_data); | ||
402 | if(handle_cryptohandshake(public_key, secret_nonce, temp_data, len)) | ||
403 | { | ||
404 | int connection_id = incoming_connections[i]; | ||
405 | incoming_connections[i] = -1;//remove this connection from the incoming connection list. | ||
406 | return connection_id; | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | return -1; | ||
412 | } | ||
413 | |||
414 | //kill a crypto connection | ||
415 | //return 0 if killed successfully | ||
416 | //return 1 if there was a problem. | ||
417 | int crypto_kill(int crypt_connection_id) | ||
418 | { | ||
419 | if(crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | ||
420 | { | ||
421 | return 1; | ||
422 | } | ||
423 | if(crypto_connections[crypt_connection_id].status != 0) | ||
424 | { | ||
425 | crypto_connections[crypt_connection_id].status = 0; | ||
426 | kill_connection(crypto_connections[crypt_connection_id].number); | ||
427 | return 0; | ||
428 | } | ||
429 | return 1; | ||
430 | } | ||
431 | |||
432 | |||
433 | //accept an incoming connection using the parameters provided by crypto_inbound | ||
434 | //return -1 if not successful | ||
435 | //returns the crypt_connection_id if successful | ||
436 | int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * secret_nonce) | ||
437 | { | ||
438 | uint32_t i; | ||
439 | if(connection_id == -1) | ||
440 | { | ||
441 | return -1; | ||
442 | } | ||
443 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) | ||
444 | { | ||
445 | if(crypto_connections[i].status == 0) | ||
446 | { | ||
447 | crypto_connections[i].number = connection_id; | ||
448 | crypto_connections[i].status = 2; | ||
449 | random_nonce(crypto_connections[i].recv_nonce); | ||
450 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | ||
451 | increment_nonce(crypto_connections[i].sent_nonce); | ||
452 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | ||
453 | if(send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce) == 1) | ||
454 | { | ||
455 | increment_nonce(crypto_connections[i].recv_nonce); | ||
456 | uint32_t zero = 0; | ||
457 | crypto_connections[i].status = 3;//connection status needs to be 3 for write_cryptpacket() to work | ||
458 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | ||
459 | crypto_connections[i].status = 2;//set it to its proper value right after. | ||
460 | return i; | ||
461 | } | ||
462 | return -1;//this should never happen. | ||
463 | } | ||
464 | } | ||
465 | return -1; | ||
466 | } | ||
467 | |||
468 | //return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
469 | //(we have recieved a hanshake but no empty data packet), 3 if the connection is established. | ||
470 | //4 if the connection is timed out and wating to be killed | ||
471 | int is_cryptoconnected(int crypt_connection_id) | ||
472 | { | ||
473 | if(crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) | ||
474 | { | ||
475 | return crypto_connections[crypt_connection_id].status; | ||
476 | } | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | |||
481 | //Generate our public and private keys | ||
482 | //Only call this function the first time the program starts. | ||
483 | void new_keys() | ||
484 | { | ||
485 | crypto_box_keypair(self_public_key,self_secret_key); | ||
486 | } | ||
487 | |||
488 | //TODO: optimize this | ||
489 | //adds an incoming connection to the incoming_connection list. | ||
490 | //returns 0 if successful | ||
491 | //returns 1 if failure | ||
492 | int new_incoming(int id) | ||
493 | { | ||
494 | uint32_t i; | ||
495 | for(i = 0; i < MAX_INCOMING; i++) | ||
496 | { | ||
497 | if(incoming_connections[i] == -1) | ||
498 | { | ||
499 | incoming_connections[i] = id; | ||
500 | return 0; | ||
501 | } | ||
502 | } | ||
503 | return 1; | ||
504 | } | ||
505 | |||
506 | //TODO: optimize this | ||
507 | //handle all new incoming connections. | ||
508 | void handle_incomings() | ||
509 | { | ||
510 | int income; | ||
511 | while(1) | ||
512 | { | ||
513 | income = incoming_connection(); | ||
514 | if(income == -1) | ||
515 | { | ||
516 | break; | ||
517 | } | ||
518 | if(new_incoming(income)) | ||
519 | { | ||
520 | break; | ||
521 | } | ||
522 | } | ||
523 | } | ||
524 | |||
525 | //handle recieved packets for not yet established crypto connections. | ||
526 | void recieve_crypto() | ||
527 | { | ||
528 | uint32_t i; | ||
529 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) | ||
530 | { | ||
531 | if(crypto_connections[i].status == 1) | ||
532 | { | ||
533 | if(id_packet(crypto_connections[i].number) == 2)//handle handshake packet. | ||
534 | { | ||
535 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
536 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | ||
537 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
538 | uint16_t len = read_packet(crypto_connections[i].number, temp_data); | ||
539 | if(handle_cryptohandshake(public_key, secret_nonce, temp_data, len)) | ||
540 | { | ||
541 | if(memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
542 | { | ||
543 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | ||
544 | increment_nonce(crypto_connections[i].sent_nonce); | ||
545 | uint32_t zero = 0; | ||
546 | crypto_connections[i].status = 3;//connection status needs to be 3 for write_cryptpacket() to work | ||
547 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | ||
548 | crypto_connections[i].status = 2;//set it to its proper value right after. | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | else if(id_packet(crypto_connections[i].number) != -1) | ||
553 | { | ||
554 | //This should not happen | ||
555 | //kill the connection if it does | ||
556 | crypto_kill(crypto_connections[i].number); | ||
557 | } | ||
558 | |||
559 | } | ||
560 | if(crypto_connections[i].status == 2) | ||
561 | { | ||
562 | if(id_packet(crypto_connections[i].number) == 3) | ||
563 | { | ||
564 | uint8_t temp_data[MAX_DATA_SIZE]; | ||
565 | uint8_t data[MAX_DATA_SIZE]; | ||
566 | int length = read_packet(crypto_connections[i].number, temp_data); | ||
567 | int len = decrypt_data(crypto_connections[i].public_key, | ||
568 | crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); | ||
569 | uint32_t zero = 0; | ||
570 | if(len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) | ||
571 | { | ||
572 | increment_nonce(crypto_connections[i].recv_nonce); | ||
573 | crypto_connections[i].status = 3; | ||
574 | } | ||
575 | else | ||
576 | { | ||
577 | //This should not happen | ||
578 | //kill the connection if it does | ||
579 | crypto_kill(crypto_connections[i].number); | ||
580 | } | ||
581 | } | ||
582 | else if(id_packet(crypto_connections[i].number) != -1) | ||
583 | { | ||
584 | //This should not happen | ||
585 | //kill the connection if it does | ||
586 | crypto_kill(crypto_connections[i].number); | ||
587 | } | ||
588 | } | ||
589 | } | ||
590 | } | ||
591 | |||
592 | //run this to (re)initialize net_crypto | ||
593 | //sets all the global connection variables to their default values. | ||
594 | void initNetCrypto() | ||
595 | { | ||
596 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); | ||
597 | memset(outbound_friendrequests, -1 ,sizeof(outbound_friendrequests)); | ||
598 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); | ||
599 | } | ||
600 | |||
601 | void killTimedout() | ||
602 | { | ||
603 | uint32_t i; | ||
604 | for(i = 0; i < MAX_CRYPTO_CONNECTIONS; i++) | ||
605 | { | ||
606 | if(is_connected(crypto_connections[i].number) == 4) | ||
607 | { | ||
608 | crypto_connections[i].status = 4; | ||
609 | } | ||
610 | } | ||
611 | } | ||
612 | |||
613 | //main loop | ||
614 | void doNetCrypto() | ||
615 | { | ||
616 | //TODO:check if friend requests were sent correctly | ||
617 | //handle new incoming connections | ||
618 | //handle friend requests | ||
619 | handle_incomings(); | ||
620 | recieve_crypto(); | ||
621 | killTimedout(); | ||
622 | } | ||
diff --git a/core/net_crypto.h b/core/net_crypto.h new file mode 100644 index 00000000..850bcd13 --- /dev/null +++ b/core/net_crypto.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /* net_crypto.h | ||
2 | * | ||
3 | * Functions for the core network crypto. | ||
4 | * | ||
5 | */ | ||
6 | |||
7 | #ifndef NET_CRYPTO_H | ||
8 | #define NET_CRYPTO_H | ||
9 | |||
10 | #include "Lossless_UDP.h" | ||
11 | |||
12 | //TODO: move this to network.h | ||
13 | #ifndef WIN32 | ||
14 | #include "../nacl/build/Linux/include/amd64/crypto_box.h" | ||
15 | #endif | ||
16 | //Our public key. | ||
17 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
18 | |||
19 | |||
20 | |||
21 | //encrypts plain of length length to encrypted of length + 16 using the | ||
22 | //public key(32 bytes) of the reciever and a 24 byte nonce | ||
23 | //return -1 if there was a problem. | ||
24 | //return length of encrypted data if everything was fine. | ||
25 | int encrypt_data(uint8_t * public_key, uint8_t * nonce, uint8_t * plain, uint32_t length, uint8_t * encrypted); | ||
26 | |||
27 | |||
28 | //decrypts encrypted of length length to plain of length length - 16 using the | ||
29 | //public key(32 bytes) of the sender and a 24 byte nonce | ||
30 | //return -1 if there was a problem(decryption failed) | ||
31 | //return length of plain data if everything was fine. | ||
32 | int decrypt_data(uint8_t * public_key, uint8_t * nonce, uint8_t * encrypted, uint32_t length, uint8_t * plain); | ||
33 | |||
34 | |||
35 | //return 0 if there is no received data in the buffer | ||
36 | //return -1 if the packet was discarded. | ||
37 | //return length of recieved data if successful | ||
38 | int read_cryptpacket(int crypt_connection_id, uint8_t * data); | ||
39 | |||
40 | |||
41 | //return 0 if data could not be put in packet queue | ||
42 | //return 1 if data was put into the queue | ||
43 | int write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length); | ||
44 | |||
45 | //send a friend request to peer with public_key and ip_port. | ||
46 | //Data represents the data we send with the friends request. | ||
47 | //returns -1 on failure | ||
48 | //returns a positive friend request id that can be used later to see if it was sent correctly on success. | ||
49 | int send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, uint32_t length); | ||
50 | |||
51 | |||
52 | //return -1 if failure | ||
53 | //return 0 if connection is still trying to send the request. | ||
54 | //return 1 if sent correctly | ||
55 | //return 2 if connection timed out | ||
56 | int check_friendrequest(int friend_request); | ||
57 | |||
58 | |||
59 | //puts the public key of the friend if public_key, the data from the request | ||
60 | //in data if a friend request was sent to us and returns the length of the data. | ||
61 | //return -1 if no valid friend requests. | ||
62 | int handle_friendrequest(uint8_t * public_key, uint8_t * data); | ||
63 | |||
64 | |||
65 | //Start a secure connection with other peer who has public_key and ip_port | ||
66 | //returns -1 if failure | ||
67 | //returns crypt_connection_id of the initialized connection if everything went well. | ||
68 | int crypto_connect(uint8_t * public_key, IP_Port ip_port); | ||
69 | |||
70 | |||
71 | //kill a crypto connection | ||
72 | //return 0 if killed successfully | ||
73 | //return 1 if there was a problem. | ||
74 | int crypto_kill(int crypt_connection_id); | ||
75 | |||
76 | //handle an incoming connection | ||
77 | //return -1 if no crypto inbound connection | ||
78 | //return incomming connection id (Lossless_UDP one) if there is an incomming crypto connection | ||
79 | //Put the public key of the peer in public_key and the secret_nonce from the handshake into secret_nonce | ||
80 | //to accept it see: accept_crypto_inbound(...) | ||
81 | //to refuse it just call kill_connection(...) on the connection id | ||
82 | int crypto_inbound(uint8_t * public_key, uint8_t * secret_nonce); | ||
83 | |||
84 | |||
85 | //accept an incoming connection using the parameters provided by crypto_inbound | ||
86 | //return -1 if not successful | ||
87 | //returns the crypt_connection_id if successful | ||
88 | int accept_crypto_inbound(int connection_id, uint8_t * public_key, uint8_t * secret_nonce); | ||
89 | |||
90 | //return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
91 | //(we have recieved a hanshake but no empty data packet), 3 if the connection is established. | ||
92 | //4 if the connection is timed out and wating to be killed | ||
93 | int is_cryptoconnected(int crypt_connection_id); | ||
94 | |||
95 | |||
96 | //Generate our public and private keys | ||
97 | //Only call this function the first time the program starts. | ||
98 | void new_keys(); | ||
99 | |||
100 | //run this to (re)initialize net_crypto | ||
101 | //sets all the global connection variables to their default values. | ||
102 | void initNetCrypto(); | ||
103 | |||
104 | //main loop | ||
105 | void doNetCrypto(); | ||
106 | |||
107 | |||
108 | #endif | ||
diff --git a/core/network.c b/core/network.c index 601066cd..6b5f9970 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -63,10 +63,10 @@ static int sock; | |||
63 | 63 | ||
64 | //Basic network functions: | 64 | //Basic network functions: |
65 | //Function to send packet(data) of length length to ip_port | 65 | //Function to send packet(data) of length length to ip_port |
66 | int sendpacket(IP_Port ip_port, char * data, uint32_t length) | 66 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) |
67 | { | 67 | { |
68 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; | 68 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; |
69 | return sendto(sock, data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | 69 | return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); |
70 | 70 | ||
71 | } | 71 | } |
72 | 72 | ||
@@ -74,7 +74,7 @@ int sendpacket(IP_Port ip_port, char * data, uint32_t length) | |||
74 | //the packet data into data | 74 | //the packet data into data |
75 | //the packet length into length. | 75 | //the packet length into length. |
76 | //dump all empty packets. | 76 | //dump all empty packets. |
77 | int recievepacket(IP_Port * ip_port, char * data, uint32_t * length) | 77 | int recievepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) |
78 | { | 78 | { |
79 | ADDR addr; | 79 | ADDR addr; |
80 | #ifdef WIN32 | 80 | #ifdef WIN32 |
@@ -82,7 +82,7 @@ int recievepacket(IP_Port * ip_port, char * data, uint32_t * length) | |||
82 | #else | 82 | #else |
83 | uint32_t addrlen = sizeof(addr); | 83 | uint32_t addrlen = sizeof(addr); |
84 | #endif | 84 | #endif |
85 | (*(int32_t *)length) = recvfrom(sock, data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); | 85 | (*(int32_t *)length) = recvfrom(sock,(char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen); |
86 | if(*(int32_t *)length <= 0) | 86 | if(*(int32_t *)length <= 0) |
87 | { | 87 | { |
88 | //nothing received | 88 | //nothing received |
diff --git a/core/network.h b/core/network.h index c8fdce5c..9606d237 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -95,12 +95,12 @@ uint32_t random_int(); | |||
95 | //Basic network functions: | 95 | //Basic network functions: |
96 | 96 | ||
97 | //Function to send packet(data) of length length to ip_port | 97 | //Function to send packet(data) of length length to ip_port |
98 | int sendpacket(IP_Port ip_port, char * data, uint32_t length); | 98 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length); |
99 | 99 | ||
100 | //Function to recieve data, ip and port of sender is put into ip_port | 100 | //Function to recieve data, ip and port of sender is put into ip_port |
101 | //the packet data into data | 101 | //the packet data into data |
102 | //the packet length into length. | 102 | //the packet length into length. |
103 | int recievepacket(IP_Port * ip_port, char * data, uint32_t * length); | 103 | int recievepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length); |
104 | 104 | ||
105 | //initialize networking | 105 | //initialize networking |
106 | //bind to ip and port | 106 | //bind to ip and port |
diff --git a/testing/DHT_cryptosendfiletest.c b/testing/DHT_cryptosendfiletest.c new file mode 100644 index 00000000..787e279e --- /dev/null +++ b/testing/DHT_cryptosendfiletest.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* DHT cryptosendfiletest | ||
2 | * | ||
3 | * This program sends or recieves a friend request. | ||
4 | * | ||
5 | * it also sends the encrypted data from a file to another client. | ||
6 | * Receives the file data that that client sends us. | ||
7 | * | ||
8 | * NOTE: this program simulates 33% packet loss. | ||
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 ../nacl/build/Linux/lib/amd64/* DHT_cryptosendfiletest.c | ||
11 | * | ||
12 | * | ||
13 | * Command line arguments are the ip and port of a node (for bootstrapping). | ||
14 | * | ||
15 | * Saves all received data to: received.txt | ||
16 | * | ||
17 | * EX: ./test 127.0.0.1 33445 filename.txt | ||
18 | */ | ||
19 | #include "../core/network.h" | ||
20 | #include "../core/DHT.h" | ||
21 | #include "../core/net_crypto.h" | ||
22 | |||
23 | #include <string.h> | ||
24 | |||
25 | //Sleep function (x = milliseconds) | ||
26 | #ifdef WIN32 | ||
27 | |||
28 | #define c_sleep(x) Sleep(1*x) | ||
29 | |||
30 | #else | ||
31 | #include <unistd.h> | ||
32 | #include <arpa/inet.h> | ||
33 | #define c_sleep(x) usleep(1000*x) | ||
34 | |||
35 | #endif | ||
36 | |||
37 | #define PORT 33445 | ||
38 | |||
39 | void printip(IP_Port ip_port) | ||
40 | { | ||
41 | printf("\nIP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); | ||
42 | } | ||
43 | |||
44 | |||
45 | //horrible function from one of my first C programs. | ||
46 | //only here because I was too lazy to write a proper one. | ||
47 | unsigned char * hex_string_to_bin(char hex_string[]) | ||
48 | { | ||
49 | unsigned char * val = malloc(strlen(hex_string)); | ||
50 | char * pos = hex_string; | ||
51 | int i=0; | ||
52 | while(i < strlen(hex_string)) | ||
53 | { | ||
54 | sscanf(pos,"%2hhx",&val[i]); | ||
55 | pos+=2; | ||
56 | i++; | ||
57 | } | ||
58 | return val; | ||
59 | } | ||
60 | |||
61 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
62 | |||
63 | int main(int argc, char *argv[]) | ||
64 | { | ||
65 | if (argc < 4) { | ||
66 | printf("usage %s ip port filename(of file to send)\n", argv[0]); | ||
67 | exit(0); | ||
68 | } | ||
69 | new_keys(); | ||
70 | printf("OUR ID: "); | ||
71 | uint32_t i; | ||
72 | for(i = 0; i < 32; i++) | ||
73 | { | ||
74 | if(self_public_key[i] < 16) | ||
75 | printf("0"); | ||
76 | printf("%hhX",self_public_key[i]); | ||
77 | } | ||
78 | printf("\n"); | ||
79 | |||
80 | memcpy(self_client_id, self_public_key, 32); | ||
81 | |||
82 | char temp_id[128]; | ||
83 | printf("Enter the client_id of the friend to connect to (32 bytes HEX format):\n"); | ||
84 | scanf("%s", temp_id); | ||
85 | |||
86 | uint8_t friend_id[32]; | ||
87 | memcpy(friend_id, hex_string_to_bin(temp_id), 32); | ||
88 | |||
89 | |||
90 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); | ||
91 | |||
92 | |||
93 | addfriend(friend_id); | ||
94 | IP_Port friend_ip; | ||
95 | int connection = -1; | ||
96 | int inconnection = -1; | ||
97 | |||
98 | uint8_t acceptedfriend_public_key[crypto_box_PUBLICKEYBYTES]; | ||
99 | int friendrequest = -1; | ||
100 | uint8_t request_data[512]; | ||
101 | |||
102 | //initialize networking | ||
103 | //bind to ip 0.0.0.0:PORT | ||
104 | IP ip; | ||
105 | ip.i = 0; | ||
106 | init_networking(ip, PORT); | ||
107 | initNetCrypto(); | ||
108 | |||
109 | |||
110 | |||
111 | perror("Initialization"); | ||
112 | IP_Port bootstrap_ip_port; | ||
113 | bootstrap_ip_port.port = htons(atoi(argv[2])); | ||
114 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | ||
115 | bootstrap(bootstrap_ip_port); | ||
116 | |||
117 | IP_Port ip_port; | ||
118 | uint8_t data[MAX_UDP_PACKET_SIZE]; | ||
119 | uint32_t length; | ||
120 | |||
121 | uint8_t buffer1[128]; | ||
122 | int read1 = 0; | ||
123 | uint8_t buffer2[128]; | ||
124 | int read2 = 0; | ||
125 | FILE *file1 = fopen(argv[3], "rb"); | ||
126 | if ( file1==NULL ){printf("Error opening file.\n");return 1;} | ||
127 | FILE *file2 = fopen("received.txt", "wb"); | ||
128 | if ( file2==NULL ){return 1;} | ||
129 | read1 = fread(buffer1, 1, 128, file1); | ||
130 | |||
131 | while(1) | ||
132 | { | ||
133 | |||
134 | while(recievepacket(&ip_port, data, &length) != -1) | ||
135 | { | ||
136 | if(rand() % 3 != 1)//simulate packet loss | ||
137 | { | ||
138 | if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) | ||
139 | { | ||
140 | //if packet is not recognized | ||
141 | printf("Received unhandled packet with length: %u\n", length); | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | printf("Received handled packet with length: %u\n", length); | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | friend_ip = getfriendip((uint8_t *)friend_id); | ||
150 | if(friend_ip.ip.i != 0) | ||
151 | { | ||
152 | if(connection == -1 && friendrequest == -1) | ||
153 | { | ||
154 | printf("Sending friend request to peer:"); | ||
155 | printip(friend_ip); | ||
156 | friendrequest = send_friendrequest(friend_id, friend_ip, "Hello World", 12); | ||
157 | //connection = crypto_connect((uint8_t *)friend_id, friend_ip); | ||
158 | //connection = new_connection(friend_ip); | ||
159 | } | ||
160 | if(check_friendrequest(friendrequest) == 1) | ||
161 | { | ||
162 | printf("Started connecting to friend:"); | ||
163 | connection = crypto_connect((uint8_t *)friend_id, friend_ip); | ||
164 | } | ||
165 | } | ||
166 | if(inconnection == -1) | ||
167 | { | ||
168 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | ||
169 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
170 | inconnection = crypto_inbound(public_key, secret_nonce); | ||
171 | inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce); | ||
172 | //inconnection = incoming_connection(); | ||
173 | if(inconnection != -1) | ||
174 | { | ||
175 | printf("Someone connected to us:\n"); | ||
176 | // printip(connection_ip(inconnection)); | ||
177 | } | ||
178 | } | ||
179 | if(handle_friendrequest(acceptedfriend_public_key, request_data) > 1) | ||
180 | { | ||
181 | printf("RECIEVED FRIEND REQUEST: %s\n", request_data); | ||
182 | } | ||
183 | |||
184 | //if someone connected to us write what he sends to a file | ||
185 | //also send him our file. | ||
186 | if(inconnection != -1) | ||
187 | { | ||
188 | if(write_cryptpacket(inconnection, buffer1, read1)) | ||
189 | { | ||
190 | printf("Wrote data1.\n"); | ||
191 | read1 = fread(buffer1, 1, 128, file1); | ||
192 | } | ||
193 | read2 = read_cryptpacket(inconnection, buffer2); | ||
194 | if(read2 != 0) | ||
195 | { | ||
196 | printf("Received data1.\n"); | ||
197 | if(!fwrite(buffer2, read2, 1, file2)) | ||
198 | { | ||
199 | printf("file write error1\n"); | ||
200 | } | ||
201 | if(read2 < 128) | ||
202 | { | ||
203 | printf("Closed file1 %u\n", read2); | ||
204 | fclose(file2); | ||
205 | } | ||
206 | } | ||
207 | else if(is_cryptoconnected(inconnection) == 4)//if buffer is empty and the connection timed out. | ||
208 | { | ||
209 | crypto_kill(inconnection); | ||
210 | } | ||
211 | } | ||
212 | //if we are connected to a friend send him data from the file. | ||
213 | //also put what he sends us in a file. | ||
214 | if(is_cryptoconnected(connection) >= 3) | ||
215 | { | ||
216 | if(write_cryptpacket(0, buffer1, read1)) | ||
217 | { | ||
218 | printf("Wrote data2.\n"); | ||
219 | read1 = fread(buffer1, 1, 128, file1); | ||
220 | } | ||
221 | read2 = read_cryptpacket(0, buffer2); | ||
222 | if(read2 != 0) | ||
223 | { | ||
224 | printf("Received data2.\n"); | ||
225 | if(!fwrite(buffer2, read2, 1, file2)) | ||
226 | { | ||
227 | printf("file write error2\n"); | ||
228 | } | ||
229 | if(read2 < 128) | ||
230 | { | ||
231 | printf("Closed file2 %u\n", read2); | ||
232 | fclose(file2); | ||
233 | } | ||
234 | } | ||
235 | else if(is_cryptoconnected(connection) == 4)//if buffer is empty and the connection timed out. | ||
236 | { | ||
237 | crypto_kill(connection); | ||
238 | } | ||
239 | } | ||
240 | doDHT(); | ||
241 | doLossless_UDP(); | ||
242 | doNetCrypto(); | ||
243 | //print_clientlist(); | ||
244 | //print_friendlist(); | ||
245 | //c_sleep(300); | ||
246 | c_sleep(1); | ||
247 | } | ||
248 | |||
249 | shutdown_networking(); | ||
250 | return 0; | ||
251 | } \ No newline at end of file | ||
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 4c1a9cd8..9100c01a 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -80,7 +80,7 @@ void print_friendlist() | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | void printpacket(char * data, uint32_t length, IP_Port ip_port) | 83 | void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) |
84 | { | 84 | { |
85 | uint32_t i; | 85 | uint32_t i; |
86 | printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); | 86 | printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); |
@@ -102,7 +102,7 @@ int main(int argc, char *argv[]) | |||
102 | printf("usage %s ip port client_id(of friend to find ip_port of)\n", argv[0]); | 102 | printf("usage %s ip port client_id(of friend to find ip_port of)\n", argv[0]); |
103 | exit(0); | 103 | exit(0); |
104 | } | 104 | } |
105 | addfriend(argv[3]); | 105 | addfriend((uint8_t *)argv[3]); |
106 | 106 | ||
107 | //initialize networking | 107 | //initialize networking |
108 | //bind to ip 0.0.0.0:PORT | 108 | //bind to ip 0.0.0.0:PORT |
@@ -125,7 +125,7 @@ int main(int argc, char *argv[]) | |||
125 | bootstrap(bootstrap_ip_port); | 125 | bootstrap(bootstrap_ip_port); |
126 | 126 | ||
127 | IP_Port ip_port; | 127 | IP_Port ip_port; |
128 | char data[MAX_UDP_PACKET_SIZE]; | 128 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
129 | uint32_t length; | 129 | uint32_t length; |
130 | 130 | ||
131 | while(1) | 131 | while(1) |