diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 150 | ||||
-rw-r--r-- | core/LAN_discovery.c | 61 | ||||
-rw-r--r-- | core/LAN_discovery.h | 7 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 427 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 96 | ||||
-rw-r--r-- | core/net_crypto.c | 23 | ||||
-rw-r--r-- | core/network.c | 47 | ||||
-rw-r--r-- | core/network.h | 16 |
8 files changed, 539 insertions, 288 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 | uint32_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 | uint32_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 |
@@ -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. */ |
@@ -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 |
@@ -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 | { |
@@ -676,15 +700,6 @@ 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() |
@@ -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,9 +986,6 @@ 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; |
@@ -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 | { |
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/Lossless_UDP.c b/core/Lossless_UDP.c index 6be8328f..4affc38f 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -21,67 +21,95 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* TODO: clean this file a bit. | 24 | /* |
25 | There are a couple of useless variables to get rid of. */ | 25 | * TODO: clean this file a bit. |
26 | * There are a couple of useless variables to get rid of. | ||
27 | */ | ||
28 | |||
26 | #include "Lossless_UDP.h" | 29 | #include "Lossless_UDP.h" |
27 | 30 | ||
28 | /* maximum data packets in sent and receive queues. */ | 31 | /* maximum data packets in sent and receive queues. */ |
29 | #define MAX_QUEUE_NUM 16 | 32 | #define MAX_QUEUE_NUM 16 |
30 | |||
31 | /* maximum length of the data in the data packets */ | ||
32 | /* #define MAX_DATA_SIZE 1024 */ /* defined in Lossless_UDP.h */ | ||
33 | 33 | ||
34 | /* maximum number of data packets in the buffer */ | 34 | /* maximum number of data packets in the buffer */ |
35 | #define BUFFER_PACKET_NUM (16-1) | 35 | #define BUFFER_PACKET_NUM (16-1) |
36 | 36 | ||
37 | /* Lossless UDP connection timeout. | 37 | /* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ |
38 | timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ | ||
39 | #define CONNEXION_TIMEOUT 5 | 38 | #define CONNEXION_TIMEOUT 5 |
40 | 39 | ||
41 | /* initial amount of sync/hanshake packets to send per second. */ | 40 | /* initial amount of sync/hanshake packets to send per second. */ |
42 | #define SYNC_RATE 2 | 41 | #define SYNC_RATE 2 |
43 | 42 | ||
44 | /* initial send rate of data. */ | 43 | /* initial send rate of data. */ |
45 | #define DATA_SYNC_RATE 30 | 44 | #define DATA_SYNC_RATE 30 |
46 | 45 | ||
47 | typedef struct { | 46 | typedef struct { |
48 | uint8_t data[MAX_DATA_SIZE]; | 47 | uint8_t data[MAX_DATA_SIZE]; |
49 | uint16_t size; | 48 | uint16_t size; |
50 | } Data; | 49 | } Data; |
51 | 50 | ||
52 | typedef struct { | 51 | typedef struct { |
53 | IP_Port ip_port; | 52 | IP_Port ip_port; |
54 | uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, | 53 | |
55 | 2 if handshake is done (we start sending SYNC packets) | 54 | /* |
56 | 3 if we are sending SYNC packets and can send data | 55 | * 0 if connection is dead, 1 if attempting handshake, |
57 | 4 if the connection has timed out. */ | 56 | * 2 if handshake is done (we start sending SYNC packets) |
58 | 57 | * 3 if we are sending SYNC packets and can send data | |
59 | uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. | 58 | * 4 if the connection has timed out. |
60 | 2 if incoming_connection() has not returned it yet, 1 if it has. */ | 59 | */ |
61 | 60 | uint8_t status; | |
62 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | 61 | |
63 | uint16_t data_rate; /* current data packet send rate packets per second. */ | 62 | /* |
64 | uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ | 63 | * 1 or 2 if connection was initiated by someone else, 0 if not. |
65 | uint64_t last_sent; /* time at which our last data or handshake packet was sent. */ | 64 | * 2 if incoming_connection() has not returned it yet, 1 if it has. |
66 | uint64_t last_recvSYNC; /* time at which we last received a SYNC packet from the other */ | 65 | */ |
67 | uint64_t last_recvdata; /* time at which we last received a DATA packet from the other */ | 66 | uint8_t inbound; |
68 | uint64_t killat; /* time at which to kill the connection */ | 67 | |
69 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | 68 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ |
70 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | 69 | uint16_t data_rate; /* current data packet send rate packets per second. */ |
71 | uint32_t handshake_id1; | 70 | |
72 | uint32_t handshake_id2; | 71 | uint64_t last_SYNC; /* time our last SYNC packet was sent. */ |
73 | uint32_t recv_packetnum; /* number of data packets received (also used as handshake_id1) */ | 72 | uint64_t last_sent; /* time our last data or handshake packet was sent. */ |
74 | uint32_t orecv_packetnum; /* number of packets received by the other peer */ | 73 | uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */ |
75 | uint32_t sent_packetnum; /* number of data packets sent */ | 74 | uint64_t last_recvdata; /* time we last received a DATA packet from the other */ |
76 | uint32_t osent_packetnum; /* number of packets sent by the other peer. */ | 75 | uint64_t killat; /* time to kill the connection */ |
77 | uint32_t sendbuff_packetnum; /* number of latest packet written onto the sendbuffer */ | 76 | |
78 | uint32_t successful_sent; /* we know all packets before that number were successfully sent */ | 77 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ |
79 | uint32_t successful_read; /* packet number of last packet read with the read_packet function */ | 78 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ |
80 | uint32_t req_packets[BUFFER_PACKET_NUM]; /* list of currently requested packet numbers(by the other person) */ | 79 | |
81 | uint16_t num_req_paquets; /* total number of currently requested packets(by the other person) */ | 80 | uint32_t handshake_id1; |
82 | uint8_t recv_counter; | 81 | uint32_t handshake_id2; |
83 | uint8_t send_counter; | 82 | |
84 | uint8_t timeout; /* connection timeout in seconds. */ | 83 | /* number of data packets received (also used as handshake_id1) */ |
84 | uint32_t recv_packetnum; | ||
85 | |||
86 | /* number of packets received by the other peer */ | ||
87 | uint32_t orecv_packetnum; | ||
88 | |||
89 | /* number of data packets sent */ | ||
90 | uint32_t sent_packetnum; | ||
91 | |||
92 | /* number of packets sent by the other peer. */ | ||
93 | uint32_t osent_packetnum; | ||
94 | |||
95 | /* number of latest packet written onto the sendbuffer */ | ||
96 | uint32_t sendbuff_packetnum; | ||
97 | |||
98 | /* we know all packets before that number were successfully sent */ | ||
99 | uint32_t successful_sent; | ||
100 | |||
101 | /* packet number of last packet read with the read_packet function */ | ||
102 | uint32_t successful_read; | ||
103 | |||
104 | /* list of currently requested packet numbers(by the other person) */ | ||
105 | uint32_t req_packets[BUFFER_PACKET_NUM]; | ||
106 | |||
107 | /* total number of currently requested packets(by the other person) */ | ||
108 | uint16_t num_req_paquets; | ||
109 | |||
110 | uint8_t recv_counter; | ||
111 | uint8_t send_counter; | ||
112 | uint8_t timeout; /* connection timeout in seconds. */ | ||
85 | } Connection; | 113 | } Connection; |
86 | 114 | ||
87 | 115 | ||
@@ -94,26 +122,33 @@ static uint32_t connections_number; /* Number of connections in connections arra | |||
94 | 122 | ||
95 | /* Functions */ | 123 | /* Functions */ |
96 | 124 | ||
97 | /* get connection id from IP_Port | 125 | /* |
98 | return -1 if there are no connections like we are looking for | 126 | * Get connection id from IP_Port |
99 | return id if it found it */ | 127 | * Return -1 if there are no connections like we are looking for |
128 | * Return id if it found it | ||
129 | */ | ||
100 | int getconnection_id(IP_Port ip_port) | 130 | int getconnection_id(IP_Port ip_port) |
101 | { | 131 | { |
102 | uint32_t i; | 132 | uint32_t i; |
103 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 133 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
104 | if (connections[i].ip_port.ip.i == ip_port.ip.i && | 134 | if (connections[i].ip_port.ip.i == ip_port.ip.i && |
105 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) | 135 | connections[i].ip_port.port == ip_port.port && |
136 | connections[i].status > 0) | ||
106 | return i; | 137 | return i; |
107 | } | 138 | } |
139 | |||
108 | return -1; | 140 | return -1; |
109 | } | 141 | } |
110 | 142 | ||
111 | /* table of random numbers used below. */ | 143 | /* table of random numbers used below. */ |
112 | static uint32_t randtable[6][256]; | 144 | static uint32_t randtable[6][256]; |
113 | 145 | ||
114 | /* generate a handshake_id which depends on the ip_port. | 146 | /* |
115 | this function will always give one unique handshake_id per ip_port. | 147 | * Generate a handshake_id which depends on the ip_port. |
116 | TODO: make this better */ | 148 | * This function will always give one unique handshake_id per ip_port. |
149 | * | ||
150 | * TODO: make this better | ||
151 | */ | ||
117 | uint32_t handshake_id(IP_Port source) | 152 | uint32_t handshake_id(IP_Port source) |
118 | { | 153 | { |
119 | uint32_t id = 0, i; | 154 | uint32_t id = 0, i; |
@@ -124,21 +159,27 @@ uint32_t handshake_id(IP_Port source) | |||
124 | } | 159 | } |
125 | if (id == 0) /* id can't be zero */ | 160 | if (id == 0) /* id can't be zero */ |
126 | id = 1; | 161 | id = 1; |
162 | |||
127 | return id; | 163 | return id; |
128 | } | 164 | } |
129 | 165 | ||
130 | /* change the hnshake id associated with that ip_port | 166 | /* |
131 | TODO: make this better */ | 167 | * Change the hanshake id associated with that ip_port |
168 | * | ||
169 | * TODO: make this better | ||
170 | */ | ||
132 | void change_handshake(IP_Port source) | 171 | void change_handshake(IP_Port source) |
133 | { | 172 | { |
134 | uint8_t rand = random_int() % 4; | 173 | uint8_t rand = random_int() % 4; |
135 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); | 174 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); |
136 | } | 175 | } |
137 | 176 | ||
138 | /* initialize a new connection to ip_port | 177 | /* |
139 | returns an integer corresponding to the connection id. | 178 | * Initialize a new connection to ip_port |
140 | return -1 if it could not initialize the connection. | 179 | * Returns an integer corresponding to the connection idt |
141 | if there already was an existing connection to that ip_port return its number. */ | 180 | * Return -1 if it could not initialize the connectiont |
181 | * If there already was an existing connection to that ip_port return its number. | ||
182 | */ | ||
142 | int new_connection(IP_Port ip_port) | 183 | int new_connection(IP_Port ip_port) |
143 | { | 184 | { |
144 | int connect = getconnection_id(ip_port); | 185 | int connect = getconnection_id(ip_port); |
@@ -148,8 +189,10 @@ int new_connection(IP_Port ip_port) | |||
148 | if(connections_number == connections_length) { | 189 | if(connections_number == connections_length) { |
149 | Connection * temp; | 190 | Connection * temp; |
150 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 191 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); |
192 | |||
151 | if(temp == NULL) | 193 | if(temp == NULL) |
152 | return -1; | 194 | return -1; |
195 | |||
153 | memset(&temp[connections_length], 0, sizeof(Connection)); | 196 | memset(&temp[connections_length], 0, sizeof(Connection)); |
154 | ++connections_length; | 197 | ++connections_length; |
155 | connections = temp; | 198 | connections = temp; |
@@ -159,31 +202,37 @@ int new_connection(IP_Port ip_port) | |||
159 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 202 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
160 | if(connections[i].status == 0) { | 203 | if(connections[i].status == 0) { |
161 | memset(&connections[i], 0, sizeof(Connection)); | 204 | memset(&connections[i], 0, sizeof(Connection)); |
162 | connections[i].ip_port = ip_port; | 205 | |
163 | connections[i].status = 1; | 206 | connections[i] = (Connection) { |
164 | connections[i].inbound = 0; | 207 | .ip_port = ip_port, |
165 | connections[i].handshake_id1 = handshake_id(ip_port); | 208 | .status = 1, |
166 | connections[i].sent_packetnum = connections[i].handshake_id1; | 209 | .inbound = 0, |
167 | connections[i].sendbuff_packetnum = connections[i].handshake_id1; | 210 | .handshake_id1 = handshake_id(ip_port), |
168 | connections[i].successful_sent = connections[i].handshake_id1; | 211 | .sent_packetnum = connections[i].handshake_id1, |
169 | connections[i].SYNC_rate = SYNC_RATE; | 212 | .sendbuff_packetnum = connections[i].handshake_id1, |
170 | connections[i].data_rate = DATA_SYNC_RATE; | 213 | .successful_sent = connections[i].handshake_id1, |
171 | connections[i].last_recvSYNC = current_time(); | 214 | .SYNC_rate = SYNC_RATE, |
172 | connections[i].last_sent = current_time(); | 215 | .data_rate = DATA_SYNC_RATE, |
173 | connections[i].killat = ~0; | 216 | .last_recvSYNC = current_time(), |
174 | connections[i].send_counter = 0; | 217 | .last_sent = current_time(), |
175 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 218 | .killat = ~0, |
176 | connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 219 | .send_counter = 0, |
220 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | ||
221 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT | ||
222 | }; | ||
177 | ++connections_number; | 223 | ++connections_number; |
224 | |||
178 | return i; | 225 | return i; |
179 | } | 226 | } |
180 | } | 227 | } |
181 | return -1; | 228 | return -1; |
182 | } | 229 | } |
183 | 230 | ||
184 | /* initialize a new inbound connection from ip_port | 231 | /* |
185 | returns an integer corresponding to the connection id. | 232 | * Initialize a new inbound connection from ip_port |
186 | return -1 if it could not initialize the connection. */ | 233 | * Returns an integer corresponding to the connection id. |
234 | * Return -1 if it could not initialize the connection. | ||
235 | */ | ||
187 | int new_inconnection(IP_Port ip_port) | 236 | int new_inconnection(IP_Port ip_port) |
188 | { | 237 | { |
189 | if (getconnection_id(ip_port) != -1) | 238 | if (getconnection_id(ip_port) != -1) |
@@ -192,8 +241,10 @@ int new_inconnection(IP_Port ip_port) | |||
192 | if(connections_number == connections_length) { | 241 | if(connections_number == connections_length) { |
193 | Connection * temp; | 242 | Connection * temp; |
194 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 243 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); |
244 | |||
195 | if(temp == NULL) | 245 | if(temp == NULL) |
196 | return -1; | 246 | return -1; |
247 | |||
197 | memset(&temp[connections_length], 0, sizeof(Connection)); | 248 | memset(&temp[connections_length], 0, sizeof(Connection)); |
198 | ++connections_length; | 249 | ++connections_length; |
199 | connections = temp; | 250 | connections = temp; |
@@ -203,18 +254,23 @@ int new_inconnection(IP_Port ip_port) | |||
203 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 254 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
204 | if (connections[i].status == 0) { | 255 | if (connections[i].status == 0) { |
205 | memset(&connections[i], 0, sizeof(Connection)); | 256 | memset(&connections[i], 0, sizeof(Connection)); |
206 | connections[i].ip_port = ip_port; | 257 | |
207 | connections[i].status = 2; | 258 | connections[i] = (Connection){ |
208 | connections[i].inbound = 2; | 259 | .ip_port = ip_port, |
209 | connections[i].SYNC_rate = SYNC_RATE; | 260 | .status = 2, |
210 | connections[i].data_rate = DATA_SYNC_RATE; | 261 | .inbound = 2, |
211 | connections[i].last_recvSYNC = current_time(); | 262 | .SYNC_rate = SYNC_RATE, |
212 | connections[i].last_sent = current_time(); | 263 | .data_rate = DATA_SYNC_RATE, |
213 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 264 | .last_recvSYNC = current_time(), |
214 | connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 265 | .last_sent = current_time(), |
215 | /* if this connection isn't handled within the timeout kill it. */ | 266 | .send_counter = 127, |
216 | connections[i].killat = current_time() + 1000000UL*connections[i].timeout; | 267 | |
217 | connections[i].send_counter = 127; | 268 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ |
269 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT, | ||
270 | |||
271 | /* if this connection isn't handled within the timeout kill it. */ | ||
272 | .killat = current_time() + 1000000UL*connections[i].timeout | ||
273 | }; | ||
218 | ++connections_number; | 274 | ++connections_number; |
219 | return i; | 275 | return i; |
220 | } | 276 | } |
@@ -222,8 +278,10 @@ int new_inconnection(IP_Port ip_port) | |||
222 | return -1; | 278 | return -1; |
223 | } | 279 | } |
224 | 280 | ||
225 | /* returns an integer corresponding to the next connection in our incoming connection list | 281 | /* |
226 | return -1 if there are no new incoming connections in the list. */ | 282 | * Returns an integer corresponding to the next connection in our incoming connection list. |
283 | * Return -1 if there are no new incoming connections in the list. | ||
284 | */ | ||
227 | int incoming_connection() | 285 | int incoming_connection() |
228 | { | 286 | { |
229 | uint32_t i; | 287 | uint32_t i; |
@@ -233,9 +291,11 @@ int incoming_connection() | |||
233 | return i; | 291 | return i; |
234 | } | 292 | } |
235 | } | 293 | } |
294 | |||
236 | return -1; | 295 | return -1; |
237 | } | 296 | } |
238 | /*Try to free some memory from the connections array.*/ | 297 | |
298 | /* Try to free some memory from the connections array. */ | ||
239 | static void free_connections() | 299 | static void free_connections() |
240 | { | 300 | { |
241 | uint32_t i; | 301 | uint32_t i; |
@@ -245,16 +305,20 @@ static void free_connections() | |||
245 | 305 | ||
246 | if(connections_length == i) | 306 | if(connections_length == i) |
247 | return; | 307 | return; |
308 | |||
248 | Connection * temp; | 309 | Connection * temp; |
249 | temp = realloc(connections, sizeof(Connection) * i); | 310 | temp = realloc(connections, sizeof(Connection) * i); |
250 | if(temp == NULL && i != 0) | 311 | if(temp == NULL && i != 0) |
251 | return; | 312 | return; |
313 | |||
252 | connections = temp; | 314 | connections = temp; |
253 | connections_length = i; | 315 | connections_length = i; |
254 | } | 316 | } |
255 | 317 | ||
256 | /* return -1 if it could not kill the connection. | 318 | /* |
257 | return 0 if killed successfully */ | 319 | * Return -1 if it could not kill the connection. |
320 | * Return 0 if killed successfully | ||
321 | */ | ||
258 | int kill_connection(int connection_id) | 322 | int kill_connection(int connection_id) |
259 | { | 323 | { |
260 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 324 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { |
@@ -269,9 +333,11 @@ int kill_connection(int connection_id) | |||
269 | return -1; | 333 | return -1; |
270 | } | 334 | } |
271 | 335 | ||
272 | /* kill connection in seconds seconds. | 336 | /* |
273 | return -1 if it can not kill the connection. | 337 | * Kill connection in seconds. |
274 | return 0 if it will kill it */ | 338 | * Return -1 if it can not kill the connection. |
339 | * Return 0 if it will kill it. | ||
340 | */ | ||
275 | int kill_connection_in(int connection_id, uint32_t seconds) | 341 | int kill_connection_in(int connection_id, uint32_t seconds) |
276 | { | 342 | { |
277 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 343 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { |
@@ -283,12 +349,14 @@ int kill_connection_in(int connection_id, uint32_t seconds) | |||
283 | return -1; | 349 | return -1; |
284 | } | 350 | } |
285 | 351 | ||
286 | /* check if connection is connected | 352 | /* |
287 | return 0 no. | 353 | * Check if connection is connected: |
288 | return 1 if attempting handshake | 354 | * Return 0 no. |
289 | return 2 if handshake is done | 355 | * Return 1 if attempting handshake. |
290 | return 3 if fully connected | 356 | * Return 2 if handshake is done. |
291 | return 4 if timed out and waiting to be killed */ | 357 | * Return 3 if fully connected. |
358 | * Return 4 if timed out and waiting to be killed. | ||
359 | */ | ||
292 | int is_connected(int connection_id) | 360 | int is_connected(int connection_id) |
293 | { | 361 | { |
294 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 362 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
@@ -327,8 +395,10 @@ char id_packet(int connection_id) | |||
327 | { | 395 | { |
328 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 396 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) |
329 | return -1; | 397 | return -1; |
398 | |||
330 | if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) | 399 | if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) |
331 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; | 400 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; |
401 | |||
332 | return -1; | 402 | return -1; |
333 | } | 403 | } |
334 | 404 | ||
@@ -338,7 +408,7 @@ int read_packet(int connection_id, uint8_t * data) | |||
338 | { | 408 | { |
339 | if (recvqueue(connection_id) != 0) { | 409 | if (recvqueue(connection_id) != 0) { |
340 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; | 410 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; |
341 | uint16_t size = connections[connection_id].recvbuffer[index].size; | 411 | uint16_t size = connections[connection_id].recvbuffer[index].size; |
342 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); | 412 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); |
343 | ++connections[connection_id].successful_read; | 413 | ++connections[connection_id].successful_read; |
344 | connections[connection_id].recvbuffer[index].size = 0; | 414 | connections[connection_id].recvbuffer[index].size = 0; |
@@ -347,14 +417,15 @@ int read_packet(int connection_id, uint8_t * data) | |||
347 | return 0; | 417 | return 0; |
348 | } | 418 | } |
349 | 419 | ||
350 | /* return 0 if data could not be put in packet queue | 420 | /* |
351 | return 1 if data was put into the queue */ | 421 | * Return 0 if data could not be put in packet queue |
422 | * Return 1 if data was put into the queue | ||
423 | */ | ||
352 | int write_packet(int connection_id, uint8_t * data, uint32_t length) | 424 | int write_packet(int connection_id, uint8_t * data, uint32_t length) |
353 | { | 425 | { |
354 | if (length > MAX_DATA_SIZE) | 426 | if (length > MAX_DATA_SIZE || length == 0) |
355 | return 0; | ||
356 | if (length == 0) | ||
357 | return 0; | 427 | return 0; |
428 | |||
358 | if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { | 429 | if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { |
359 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | 430 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; |
360 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | 431 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); |
@@ -362,6 +433,7 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length) | |||
362 | connections[connection_id].sendbuff_packetnum++; | 433 | connections[connection_id].sendbuff_packetnum++; |
363 | return 1; | 434 | return 1; |
364 | } | 435 | } |
436 | |||
365 | return 0; | 437 | return 0; |
366 | } | 438 | } |
367 | 439 | ||
@@ -371,8 +443,11 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
371 | uint32_t number = 0; | 443 | uint32_t number = 0; |
372 | uint32_t i; | 444 | uint32_t i; |
373 | uint32_t temp; | 445 | uint32_t temp; |
374 | if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ | 446 | |
447 | /* don't request packets if the buffer is full. */ | ||
448 | if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) | ||
375 | return 0; | 449 | return 0; |
450 | |||
376 | for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { | 451 | for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { |
377 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { | 452 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { |
378 | temp = htonl(i); | 453 | temp = htonl(i); |
@@ -380,14 +455,19 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
380 | ++number; | 455 | ++number; |
381 | } | 456 | } |
382 | } | 457 | } |
458 | |||
383 | if(number == 0) | 459 | if(number == 0) |
384 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; | 460 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; |
461 | |||
385 | return number; | 462 | return number; |
386 | } | 463 | } |
387 | 464 | ||
388 | /* Packet sending functions | 465 | /* |
389 | One per packet type. | 466 | * BEGIN Packet sending functions |
390 | see docs/Lossless_UDP.txt for more information. */ | 467 | * One per packet type. |
468 | * see docs/Lossless_UDP.txt for more information. | ||
469 | */ | ||
470 | |||
391 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 471 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) |
392 | { | 472 | { |
393 | uint8_t packet[1 + 4 + 4]; | 473 | uint8_t packet[1 + 4 + 4]; |
@@ -398,21 +478,22 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i | |||
398 | memcpy(packet + 1, &temp, 4); | 478 | memcpy(packet + 1, &temp, 4); |
399 | temp = htonl(handshake_id2); | 479 | temp = htonl(handshake_id2); |
400 | memcpy(packet + 5, &temp, 4); | 480 | memcpy(packet + 5, &temp, 4); |
481 | |||
401 | return sendpacket(ip_port, packet, sizeof(packet)); | 482 | return sendpacket(ip_port, packet, sizeof(packet)); |
402 | } | 483 | } |
403 | 484 | ||
404 | int send_SYNC(uint32_t connection_id) | 485 | int send_SYNC(uint32_t connection_id) |
405 | { | 486 | { |
406 | |||
407 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; | 487 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; |
408 | uint16_t index = 0; | 488 | uint16_t index = 0; |
409 | 489 | ||
410 | IP_Port ip_port = connections[connection_id].ip_port; | 490 | IP_Port ip_port = connections[connection_id].ip_port; |
411 | uint8_t counter = connections[connection_id].send_counter; | 491 | uint8_t counter = connections[connection_id].send_counter; |
412 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); | 492 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); |
413 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); | 493 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); |
494 | |||
414 | uint32_t requested[BUFFER_PACKET_NUM]; | 495 | uint32_t requested[BUFFER_PACKET_NUM]; |
415 | uint32_t number = missing_packets(connection_id, requested); | 496 | uint32_t number = missing_packets(connection_id, requested); |
416 | 497 | ||
417 | packet[0] = 17; | 498 | packet[0] = 17; |
418 | index += 1; | 499 | index += 1; |
@@ -462,17 +543,24 @@ int send_DATA(uint32_t connection_id) | |||
462 | return 0; | 543 | return 0; |
463 | } | 544 | } |
464 | 545 | ||
465 | /* END of packet sending functions */ | 546 | /* |
547 | * END of packet sending functions | ||
548 | * | ||
549 | * | ||
550 | * BEGIN Packet handling functions | ||
551 | * One to handle each type of packets we receive | ||
552 | */ | ||
553 | |||
466 | 554 | ||
467 | /* Packet handling functions | 555 | /* Return 0 if handled correctly, 1 if packet is bad. */ |
468 | One to handle each type of packets we receive | ||
469 | return 0 if handled correctly, 1 if packet is bad. */ | ||
470 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 556 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) |
471 | { | 557 | { |
472 | if (length != (1 + 4 + 4)) | 558 | if (length != (1 + 4 + 4)) |
473 | return 1; | 559 | return 1; |
560 | |||
474 | uint32_t temp; | 561 | uint32_t temp; |
475 | uint32_t handshake_id1, handshake_id2; | 562 | uint32_t handshake_id1, handshake_id2; |
563 | |||
476 | int connection = getconnection_id(source); | 564 | int connection = getconnection_id(source); |
477 | memcpy(&temp, packet + 1, 4); | 565 | memcpy(&temp, packet + 1, 4); |
478 | handshake_id1 = ntohl(temp); | 566 | handshake_id1 = ntohl(temp); |
@@ -485,21 +573,22 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | |||
485 | } | 573 | } |
486 | if (is_connected(connection) != 1) | 574 | if (is_connected(connection) != 1) |
487 | return 1; | 575 | return 1; |
488 | if (handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */ | 576 | |
577 | /* if handshake_id2 is what we sent previously as handshake_id1 */ | ||
578 | if (handshake_id2 == connections[connection].handshake_id1) { | ||
489 | connections[connection].status = 2; | 579 | connections[connection].status = 2; |
490 | /* NOTE: is this necessary? | 580 | /* NOTE: is this necessary? |
491 | connections[connection].handshake_id2 = handshake_id1; */ | 581 | connections[connection].handshake_id2 = handshake_id1; */ |
492 | connections[connection].orecv_packetnum = handshake_id2; | 582 | connections[connection].orecv_packetnum = handshake_id2; |
493 | connections[connection].osent_packetnum = handshake_id1; | 583 | connections[connection].osent_packetnum = handshake_id1; |
494 | connections[connection].recv_packetnum = handshake_id1; | 584 | connections[connection].recv_packetnum = handshake_id1; |
495 | connections[connection].successful_read = handshake_id1; | 585 | connections[connection].successful_read = handshake_id1; |
496 | } | 586 | } |
497 | return 0; | ||
498 | 587 | ||
588 | return 0; | ||
499 | } | 589 | } |
500 | 590 | ||
501 | /* returns 1 if sync packet is valid | 591 | /* returns 1 if sync packet is valid 0 if not. */ |
502 | 0 if not. */ | ||
503 | int SYNC_valid(uint32_t length) | 592 | int SYNC_valid(uint32_t length) |
504 | { | 593 | { |
505 | if (length < 4 + 4 + 2) | 594 | if (length < 4 + 4 + 2) |
@@ -510,19 +599,19 @@ int SYNC_valid(uint32_t length) | |||
510 | return 1; | 599 | return 1; |
511 | } | 600 | } |
512 | 601 | ||
513 | /* case 1: */ | 602 | /* case 1 in handle_SYNC: */ |
514 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 603 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) |
515 | { | 604 | { |
516 | if (handshake_id(source) == recv_packetnum) { | 605 | if (handshake_id(source) == recv_packetnum) { |
517 | int x = new_inconnection(source); | 606 | int x = new_inconnection(source); |
518 | if (x != -1) { | 607 | if (x != -1) { |
519 | connections[x].orecv_packetnum = recv_packetnum; | 608 | connections[x].orecv_packetnum = recv_packetnum; |
520 | connections[x].sent_packetnum = recv_packetnum; | 609 | connections[x].sent_packetnum = recv_packetnum; |
521 | connections[x].sendbuff_packetnum = recv_packetnum; | 610 | connections[x].sendbuff_packetnum = recv_packetnum; |
522 | connections[x].successful_sent = recv_packetnum; | 611 | connections[x].successful_sent = recv_packetnum; |
523 | connections[x].osent_packetnum = sent_packetnum; | 612 | connections[x].osent_packetnum = sent_packetnum; |
524 | connections[x].recv_packetnum = sent_packetnum; | 613 | connections[x].recv_packetnum = sent_packetnum; |
525 | connections[x].successful_read = sent_packetnum; | 614 | connections[x].successful_read = sent_packetnum; |
526 | 615 | ||
527 | return x; | 616 | return x; |
528 | } | 617 | } |
@@ -530,7 +619,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
530 | return -1; | 619 | return -1; |
531 | } | 620 | } |
532 | 621 | ||
533 | /* case 2: */ | 622 | /* case 2 in handle_SYNC: */ |
534 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 623 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
535 | { | 624 | { |
536 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { | 625 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { |
@@ -543,7 +632,7 @@ int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
543 | } | 632 | } |
544 | return 1; | 633 | return 1; |
545 | } | 634 | } |
546 | /* case 3: */ | 635 | /* case 3 in handle_SYNC: */ |
547 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, | 636 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, |
548 | uint16_t number) | 637 | uint16_t number) |
549 | { | 638 | { |
@@ -553,17 +642,25 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
553 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ | 642 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ |
554 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); | 643 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); |
555 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); | 644 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); |
556 | if (comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */ | 645 | |
646 | /* packet valid */ | ||
647 | if (comp_1 <= BUFFER_PACKET_NUM && | ||
648 | comp_2 <= BUFFER_PACKET_NUM && | ||
649 | comp_counter < 10 && comp_counter != 0) { | ||
650 | |||
557 | connections[connection_id].orecv_packetnum = recv_packetnum; | 651 | connections[connection_id].orecv_packetnum = recv_packetnum; |
558 | connections[connection_id].osent_packetnum = sent_packetnum; | 652 | connections[connection_id].osent_packetnum = sent_packetnum; |
559 | connections[connection_id].successful_sent = recv_packetnum; | 653 | connections[connection_id].successful_sent = recv_packetnum; |
560 | connections[connection_id].last_recvSYNC = current_time(); | 654 | connections[connection_id].last_recvSYNC = current_time(); |
561 | connections[connection_id].recv_counter = counter; | 655 | connections[connection_id].recv_counter = counter; |
656 | |||
562 | ++connections[connection_id].send_counter; | 657 | ++connections[connection_id].send_counter; |
658 | |||
563 | for (i = 0; i < number; ++i) { | 659 | for (i = 0; i < number; ++i) { |
564 | temp = ntohl(req_packets[i]); | 660 | temp = ntohl(req_packets[i]); |
565 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); | 661 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); |
566 | } | 662 | } |
663 | |||
567 | connections[connection_id].num_req_paquets = number; | 664 | connections[connection_id].num_req_paquets = number; |
568 | return 0; | 665 | return 0; |
569 | } | 666 | } |
@@ -575,6 +672,7 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | |||
575 | 672 | ||
576 | if (!SYNC_valid(length)) | 673 | if (!SYNC_valid(length)) |
577 | return 1; | 674 | return 1; |
675 | |||
578 | int connection = getconnection_id(source); | 676 | int connection = getconnection_id(source); |
579 | uint8_t counter; | 677 | uint8_t counter; |
580 | uint32_t temp; | 678 | uint32_t temp; |
@@ -587,19 +685,27 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | |||
587 | recv_packetnum = ntohl(temp); | 685 | recv_packetnum = ntohl(temp); |
588 | memcpy(&temp,packet + 6, 4); | 686 | memcpy(&temp,packet + 6, 4); |
589 | sent_packetnum = ntohl(temp); | 687 | sent_packetnum = ntohl(temp); |
688 | |||
590 | if (number != 0) | 689 | if (number != 0) |
591 | memcpy(req_packets, packet + 10, 4 * number); | 690 | memcpy(req_packets, packet + 10, 4 * number); |
691 | |||
592 | if (connection == -1) | 692 | if (connection == -1) |
593 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); | 693 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); |
694 | |||
594 | if (connections[connection].status == 2) | 695 | if (connections[connection].status == 2) |
595 | return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); | 696 | return handle_SYNC2(connection, counter, |
697 | recv_packetnum, sent_packetnum); | ||
698 | |||
596 | if (connections[connection].status == 3) | 699 | if (connections[connection].status == 3) |
597 | return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); | 700 | return handle_SYNC3(connection, counter, recv_packetnum, |
701 | sent_packetnum, req_packets, number); | ||
598 | return 0; | 702 | return 0; |
599 | } | 703 | } |
600 | 704 | ||
601 | /* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value. | 705 | /* |
602 | return 1 if data was too big, 0 if not. */ | 706 | * Add a packet to the received buffer and set the recv_packetnum of the |
707 | * connection to its proper value. Return 1 if data was too big, 0 if not. | ||
708 | */ | ||
603 | int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | 709 | int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) |
604 | { | 710 | { |
605 | if (size > MAX_DATA_SIZE) | 711 | if (size > MAX_DATA_SIZE) |
@@ -608,16 +714,22 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | |||
608 | uint32_t i; | 714 | uint32_t i; |
609 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 715 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
610 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 716 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; |
717 | |||
611 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 718 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
612 | if (i == data_num) { | 719 | if (i == data_num) { |
613 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 720 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
721 | |||
614 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 722 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
615 | connections[connection_id].last_recvdata = current_time(); | 723 | connections[connection_id].last_recvdata = current_time(); |
616 | if (sent_packet < BUFFER_PACKET_NUM) | 724 | |
725 | if (sent_packet < BUFFER_PACKET_NUM) { | ||
617 | connections[connection_id].osent_packetnum = data_num; | 726 | connections[connection_id].osent_packetnum = data_num; |
727 | } | ||
728 | |||
618 | break; | 729 | break; |
619 | } | 730 | } |
620 | } | 731 | } |
732 | |||
621 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 733 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
622 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 734 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
623 | connections[connection_id].recv_packetnum = i; | 735 | connections[connection_id].recv_packetnum = i; |
@@ -635,25 +747,30 @@ int handle_data(uint8_t *packet, uint32_t length, IP_Port source) | |||
635 | if (connection == -1) | 747 | if (connection == -1) |
636 | return 1; | 748 | return 1; |
637 | 749 | ||
638 | if (connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ | 750 | /* Drop the data packet if connection is not connected. */ |
751 | if (connections[connection].status != 3) | ||
639 | return 1; | 752 | return 1; |
640 | 753 | ||
641 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) | 754 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) |
642 | return 1; | 755 | return 1; |
756 | |||
643 | uint32_t temp; | 757 | uint32_t temp; |
644 | uint32_t number; | 758 | uint32_t number; |
645 | uint16_t size = length - 1 - 4; | 759 | uint16_t size = length - 1 - 4; |
646 | 760 | ||
647 | memcpy(&temp, packet + 1, 4); | 761 | memcpy(&temp, packet + 1, 4); |
648 | number = ntohl(temp); | 762 | number = ntohl(temp); |
763 | |||
649 | return add_recv(connection, number, packet + 5, size); | 764 | return add_recv(connection, number, packet + 5, size); |
650 | } | 765 | } |
651 | 766 | ||
652 | /* END of packet handling functions */ | 767 | /* |
768 | * END of packet handling functions | ||
769 | */ | ||
653 | 770 | ||
654 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | 771 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) |
655 | { | 772 | { |
656 | switch (packet[0]) { //TODO: check if no break statement is correct??? | 773 | switch (packet[0]) { |
657 | case 16: | 774 | case 16: |
658 | return handle_handshake(packet, length, source); | 775 | return handle_handshake(packet, length, source); |
659 | 776 | ||
@@ -670,8 +787,10 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | |||
670 | return 0; | 787 | return 0; |
671 | } | 788 | } |
672 | 789 | ||
673 | /* Send handshake requests | 790 | /* |
674 | handshake packets are sent at the same rate as SYNC packets */ | 791 | * Send handshake requests |
792 | * handshake packets are sent at the same rate as SYNC packets | ||
793 | */ | ||
675 | void doNew() | 794 | void doNew() |
676 | { | 795 | { |
677 | uint32_t i; | 796 | uint32_t i; |
@@ -684,10 +803,13 @@ void doNew() | |||
684 | } | 803 | } |
685 | 804 | ||
686 | /* kill all timed out connections */ | 805 | /* kill all timed out connections */ |
687 | if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 806 | if (connections[i].status > 0 && |
688 | connections[i].status != 4) | 807 | (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && |
689 | /* kill_connection(i); */ | 808 | connections[i].status != 4) { |
690 | connections[i].status = 4; | 809 | connections[i].status = 4; |
810 | /* kill_connection(i); */ | ||
811 | } | ||
812 | |||
691 | if (connections[i].status > 0 && connections[i].killat < temp_time) | 813 | if (connections[i].status > 0 && connections[i].killat < temp_time) |
692 | kill_connection(i); | 814 | kill_connection(i); |
693 | } | 815 | } |
@@ -720,11 +842,13 @@ void doData() | |||
720 | } | 842 | } |
721 | } | 843 | } |
722 | 844 | ||
723 | /* TODO: flow control. | ||
724 | automatically adjusts send rates of packets for optimal transmission. */ | ||
725 | |||
726 | #define MAX_SYNC_RATE 10 | 845 | #define MAX_SYNC_RATE 10 |
727 | 846 | ||
847 | /* | ||
848 | * Automatically adjusts send rates of packets for optimal transmission. | ||
849 | * | ||
850 | * TODO: flow control. | ||
851 | */ | ||
728 | void adjustRates() | 852 | void adjustRates() |
729 | { | 853 | { |
730 | uint32_t i; | 854 | uint32_t i; |
@@ -744,8 +868,7 @@ void adjustRates() | |||
744 | } | 868 | } |
745 | } | 869 | } |
746 | 870 | ||
747 | /* Call this function a couple times per second | 871 | /* Call this function a couple times per second It's the main loop. */ |
748 | It's the main loop. */ | ||
749 | void doLossless_UDP() | 872 | void doLossless_UDP() |
750 | { | 873 | { |
751 | doNew(); | 874 | doNew(); |
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h index 033bc480..573e1ab9 100644 --- a/core/Lossless_UDP.h +++ b/core/Lossless_UDP.h | |||
@@ -33,70 +33,90 @@ extern "C" { | |||
33 | /* maximum length of the data in the data packets */ | 33 | /* maximum length of the data in the data packets */ |
34 | #define MAX_DATA_SIZE 1024 | 34 | #define MAX_DATA_SIZE 1024 |
35 | 35 | ||
36 | /* Functions */ | 36 | /* |
37 | 37 | * Initialize a new connection to ip_port | |
38 | /* initialize a new connection to ip_port | 38 | * Returns an integer corresponding to the connection id. |
39 | returns an integer corresponding to the connection id. | 39 | * Return -1 if it could not initialize the connection. |
40 | return -1 if it could not initialize the connection. | 40 | * Return number if there already was an existing connection to that ip_port. |
41 | if there already was an existing connection to that ip_port return its number. */ | 41 | */ |
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 | 44 | /* |
45 | return -1 if there are no connections like we are looking for | 45 | * Get connection id from IP_Port. |
46 | return id if it found it */ | 46 | * Return -1 if there are no connections like we are looking for. |
47 | * Return id if it found it . | ||
48 | */ | ||
47 | int getconnection_id(IP_Port ip_port); | 49 | int getconnection_id(IP_Port ip_port); |
48 | 50 | ||
49 | /* returns an integer corresponding to the next connection in our imcoming connection list | 51 | /* |
50 | return -1 if there are no new incoming connections in the list. */ | 52 | * Returns an int corresponding to the next connection in our imcoming connection list |
53 | * Return -1 if there are no new incoming connections in the list. | ||
54 | */ | ||
51 | int incoming_connection(); | 55 | int incoming_connection(); |
52 | 56 | ||
53 | /* return -1 if it could not kill the connection. | 57 | /* |
54 | return 0 if killed successfully */ | 58 | * Return -1 if it could not kill the connection. |
59 | * Return 0 if killed successfully | ||
60 | */ | ||
55 | int kill_connection(int connection_id); | 61 | int kill_connection(int connection_id); |
56 | 62 | ||
57 | /* kill connection in seconds seconds. | 63 | /* |
58 | return -1 if it can not kill the connection. | 64 | * Kill connection in seconds seconds. |
59 | return 0 if it will kill it */ | 65 | * Return -1 if it can not kill the connection. |
66 | * Return 0 if it will kill it | ||
67 | */ | ||
60 | int kill_connection_in(int connection_id, uint32_t seconds); | 68 | int kill_connection_in(int connection_id, uint32_t seconds); |
61 | 69 | ||
62 | /* returns the ip_port of the corresponding connection. | 70 | /* |
63 | return 0 if there is no such connection. */ | 71 | * Returns the ip_port of the corresponding connection. |
72 | * Return 0 if there is no such connection. | ||
73 | */ | ||
64 | IP_Port connection_ip(int connection_id); | 74 | IP_Port connection_ip(int connection_id); |
65 | 75 | ||
66 | /* returns the id of the next packet in the queue | 76 | /* |
67 | return -1 if no packet in queue */ | 77 | * Returns the id of the next packet in the queue |
78 | * Return -1 if no packet in queue | ||
79 | */ | ||
68 | char id_packet(int connection_id); | 80 | char id_packet(int connection_id); |
69 | 81 | ||
70 | /* return 0 if there is no received data in the buffer. | 82 | /* |
71 | return length of received packet if successful */ | 83 | * Return 0 if there is no received data in the buffer. |
84 | * Return length of received packet if successful | ||
85 | */ | ||
72 | int read_packet(int connection_id, uint8_t *data); | 86 | int read_packet(int connection_id, uint8_t *data); |
73 | 87 | ||
74 | /* return 0 if data could not be put in packet queue | 88 | /* |
75 | return 1 if data was put into the queue */ | 89 | * Return 0 if data could not be put in packet queue |
90 | * Return 1 if data was put into the queue | ||
91 | */ | ||
76 | int write_packet(int connection_id, uint8_t *data, uint32_t length); | 92 | int write_packet(int connection_id, uint8_t *data, uint32_t length); |
77 | 93 | ||
78 | /* returns the number of packets in the queue waiting to be successfully sent. */ | 94 | /* Returns the number of packets in the queue waiting to be successfully sent. */ |
79 | uint32_t sendqueue(int connection_id); | 95 | uint32_t sendqueue(int connection_id); |
80 | 96 | ||
81 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ | 97 | /* |
98 | * returns the number of packets in the queue waiting to be successfully | ||
99 | * read with read_packet(...) | ||
100 | */ | ||
82 | uint32_t recvqueue(int connection_id); | 101 | uint32_t recvqueue(int connection_id); |
83 | 102 | ||
84 | /* check if connection is connected | 103 | /* Check if connection is connected: |
85 | return 0 no. | 104 | * Return 0 no. |
86 | return 1 if attempting handshake | 105 | * Return 1 if attempting handshake. |
87 | return 2 if handshake is done | 106 | * Return 2 if handshake is done. |
88 | return 3 if fully connected | 107 | * Return 3 if fully connected. |
89 | return 4 if timed out and wating to be killed */ | 108 | * Return 4 if timed out and wating to be killed. |
109 | */ | ||
90 | int is_connected(int connection_id); | 110 | int is_connected(int connection_id); |
91 | 111 | ||
92 | /* Call this function a couple times per second | 112 | /* Call this function a couple times per second It's the main loop. */ |
93 | It's the main loop. */ | ||
94 | void doLossless_UDP(); | 113 | void doLossless_UDP(); |
95 | 114 | ||
96 | 115 | /* | |
97 | /* if we receive a Lossless_UDP packet we call this function so it can be handled. | 116 | * If we receive a Lossless_UDP packet, call this function so it can be handled. |
98 | return 0 if packet is handled correctly. | 117 | * Return 0 if packet is handled correctly. |
99 | return 1 if it didn't handle the packet or if the packet was shit. */ | 118 | * Return 1 if it didn't handle the packet or if the packet was shit. |
119 | */ | ||
100 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 120 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); |
101 | 121 | ||
102 | #ifdef __cplusplus | 122 | #ifdef __cplusplus |
diff --git a/core/net_crypto.c b/core/net_crypto.c index a437c5ee..2dbaa87c 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -65,14 +65,19 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
65 | 65 | ||
66 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; | 66 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; |
67 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; | 67 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; |
68 | uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0}; | ||
69 | 68 | ||
70 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ | 69 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ |
71 | 70 | ||
72 | crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); | 71 | crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); |
73 | 72 | ||
74 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ | 73 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero |
75 | if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) | 74 | apparently memcmp should not be used so we do this instead:*/ |
75 | uint32_t i; | ||
76 | uint32_t check = 0; | ||
77 | for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { | ||
78 | check |= temp_encrypted[i] ^ 0; | ||
79 | } | ||
80 | if(check != 0) | ||
76 | return -1; | 81 | return -1; |
77 | 82 | ||
78 | /* unpad the encrypted message */ | 83 | /* unpad the encrypted message */ |
@@ -92,7 +97,6 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
92 | 97 | ||
93 | uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; | 98 | uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; |
94 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; | 99 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; |
95 | uint8_t zeroes[crypto_box_ZEROBYTES] = {0}; | ||
96 | 100 | ||
97 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ | 101 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ |
98 | 102 | ||
@@ -100,8 +104,14 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
100 | nonce, public_key, secret_key) == -1) | 104 | nonce, public_key, secret_key) == -1) |
101 | return -1; | 105 | return -1; |
102 | 106 | ||
103 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */ | 107 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero |
104 | if (memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0) | 108 | apparently memcmp should not be used so we do this instead:*/ |
109 | uint32_t i; | ||
110 | uint32_t check = 0; | ||
111 | for(i = 0; i < crypto_box_ZEROBYTES; ++i) { | ||
112 | check |= temp_plain[i] ^ 0; | ||
113 | } | ||
114 | if(check != 0) | ||
105 | return -1; | 115 | return -1; |
106 | 116 | ||
107 | /* unpad the plain message */ | 117 | /* unpad the plain message */ |
@@ -365,6 +375,7 @@ int crypto_kill(int crypt_connection_id) | |||
365 | if (crypto_connections[crypt_connection_id].status != 0) { | 375 | if (crypto_connections[crypt_connection_id].status != 0) { |
366 | crypto_connections[crypt_connection_id].status = 0; | 376 | crypto_connections[crypt_connection_id].status = 0; |
367 | kill_connection(crypto_connections[crypt_connection_id].number); | 377 | kill_connection(crypto_connections[crypt_connection_id].number); |
378 | memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection)); | ||
368 | crypto_connections[crypt_connection_id].number = ~0; | 379 | crypto_connections[crypt_connection_id].number = ~0; |
369 | return 0; | 380 | return 0; |
370 | } | 381 | } |
diff --git a/core/network.c b/core/network.c index a7a4efcd..c58549bf 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -164,25 +164,42 @@ void shutdown_networking() | |||
164 | return; | 164 | return; |
165 | } | 165 | } |
166 | 166 | ||
167 | /* resolves provided address to a binary data in network byte order | 167 | /* |
168 | address is ASCII null terminated string | 168 | resolve_addr(): |
169 | address should represent IPv4, IPv6 or a hostname | 169 | address should represent IPv4 or a hostname with A record |
170 | on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i | 170 | |
171 | on failure returns -1 */ | 171 | returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i |
172 | int resolve_addr(const char *address) | 172 | returns 0 on failure |
173 | |||
174 | TODO: Fix ipv6 support | ||
175 | */ | ||
176 | uint32_t resolve_addr(const char *address) | ||
173 | { | 177 | { |
174 | struct addrinfo hints; | 178 | struct addrinfo *server = NULL; |
179 | struct addrinfo hints; | ||
180 | int rc; | ||
181 | uint32_t addr; | ||
182 | |||
175 | memset(&hints, 0, sizeof(hints)); | 183 | memset(&hints, 0, sizeof(hints)); |
176 | hints.ai_family = AF_UNSPEC; //support both IPv4 and IPv6 | 184 | hints.ai_family = AF_INET; // IPv4 only right now. |
177 | hints.ai_socktype = SOCK_DGRAM; //type of socket Tox uses | 185 | hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. |
178 | 186 | ||
179 | struct addrinfo *server = NULL; | 187 | rc = getaddrinfo(address, "echo", &hints, &server); |
180 | 188 | ||
181 | int success = getaddrinfo(address, "echo", &hints, &server); | 189 | // Lookup failed. |
182 | if(success != 0) | 190 | if(rc != 0) { |
183 | return -1; | 191 | return 0; |
192 | } | ||
193 | |||
194 | // IPv4 records only.. | ||
195 | if(server->ai_family != AF_INET) { | ||
196 | freeaddrinfo(server); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | |||
201 | addr = ((struct sockaddr_in*)server->ai_addr)->sin_addr.s_addr; | ||
184 | 202 | ||
185 | int resolved = ((struct sockaddr_in*)server->ai_addr)->sin_addr.s_addr; | ||
186 | freeaddrinfo(server); | 203 | freeaddrinfo(server); |
187 | return resolved; | 204 | return addr; |
188 | } | 205 | } |
diff --git a/core/network.h b/core/network.h index 3277070c..a5f7899b 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -116,12 +116,16 @@ int init_networking(IP ip, uint16_t port); | |||
116 | /* function to cleanup networking stuff(doesn't do much right now) */ | 116 | /* function to cleanup networking stuff(doesn't do much right now) */ |
117 | void shutdown_networking(); | 117 | void shutdown_networking(); |
118 | 118 | ||
119 | /* resolves provided address to a binary data in network byte order | 119 | /* |
120 | address is ASCII null terminated string | 120 | resolve_addr(): |
121 | address should represent IPv4, IPv6 or a hostname | 121 | address should represent IPv4 or a hostname with A record |
122 | on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i | 122 | |
123 | on failure returns -1 */ | 123 | returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i |
124 | int resolve_addr(const char *address); | 124 | returns 0 on failure |
125 | |||
126 | TODO: Fix ipv6 support | ||
127 | */ | ||
128 | uint32_t resolve_addr(const char *address); | ||
125 | 129 | ||
126 | #ifdef __cplusplus | 130 | #ifdef __cplusplus |
127 | } | 131 | } |