diff options
-rw-r--r-- | core/DHT.c | 26 | ||||
-rw-r--r-- | core/LAN_discovery.c | 6 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 570 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 126 | ||||
-rw-r--r-- | core/Messenger.c | 58 | ||||
-rw-r--r-- | core/Messenger.h | 5 | ||||
-rw-r--r-- | core/friend_requests.c | 8 | ||||
-rw-r--r-- | core/net_crypto.c | 414 | ||||
-rw-r--r-- | core/net_crypto.h | 88 | ||||
-rw-r--r-- | core/network.c | 92 | ||||
-rw-r--r-- | core/network.h | 24 | ||||
-rw-r--r-- | core/ping.c | 8 | ||||
-rw-r--r-- | core/ping.h | 4 |
13 files changed, 760 insertions, 669 deletions
@@ -544,7 +544,7 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
544 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 544 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
545 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 545 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
546 | 546 | ||
547 | return sendpacket(ip_port, data, sizeof(data)); | 547 | return sendpacket(temp_net->sock, ip_port, data, sizeof(data)); |
548 | } | 548 | } |
549 | 549 | ||
550 | /* send a send nodes response */ | 550 | /* send a send nodes response */ |
@@ -586,10 +586,10 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
586 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 586 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
587 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 587 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
588 | 588 | ||
589 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 589 | return sendpacket(temp_net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
590 | } | 590 | } |
591 | 591 | ||
592 | static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length) | 592 | static int handle_getnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
593 | { | 593 | { |
594 | uint64_t ping_id; | 594 | uint64_t ping_id; |
595 | 595 | ||
@@ -621,7 +621,7 @@ static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length) | |||
621 | return 0; | 621 | return 0; |
622 | } | 622 | } |
623 | 623 | ||
624 | static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length) | 624 | static int handle_sendnodes(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
625 | { | 625 | { |
626 | uint64_t ping_id; | 626 | uint64_t ping_id; |
627 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 627 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
@@ -841,7 +841,7 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | |||
841 | 841 | ||
842 | for (i = 0; i < LCLIENT_LIST; ++i) { | 842 | for (i = 0; i < LCLIENT_LIST; ++i) { |
843 | if (id_equal(client_id, close_clientlist[i].client_id)) | 843 | if (id_equal(client_id, close_clientlist[i].client_id)) |
844 | return sendpacket(close_clientlist[i].ip_port, packet, length); | 844 | return sendpacket(temp_net->sock, close_clientlist[i].ip_port, packet, length); |
845 | } | 845 | } |
846 | 846 | ||
847 | return -1; | 847 | return -1; |
@@ -912,7 +912,7 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
912 | 912 | ||
913 | /*If ip is not zero and node is good */ | 913 | /*If ip is not zero and node is good */ |
914 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 914 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
915 | if (sendpacket(client->ip_port, packet, length) == length) | 915 | if (sendpacket(temp_net->sock, client->ip_port, packet, length) == length) |
916 | ++sent; | 916 | ++sent; |
917 | } | 917 | } |
918 | } | 918 | } |
@@ -951,7 +951,7 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
951 | if (n < 1) | 951 | if (n < 1) |
952 | return 0; | 952 | return 0; |
953 | 953 | ||
954 | if (sendpacket(ip_list[rand() % n], packet, length) == length) | 954 | if (sendpacket(temp_net->sock, ip_list[rand() % n], packet, length) == length) |
955 | return 1; | 955 | return 1; |
956 | 956 | ||
957 | return 0; | 957 | return 0; |
@@ -989,7 +989,7 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
989 | data[0] = type; | 989 | data[0] = type; |
990 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); | 990 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); |
991 | /* 254 is NAT ping request packet id */ | 991 | /* 254 is NAT ping request packet id */ |
992 | int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); | 992 | int len = create_request(self_public_key, self_secret_key, packet, public_key, data, sizeof(uint64_t) + 1, 254); |
993 | 993 | ||
994 | if (len == -1) | 994 | if (len == -1) |
995 | return -1; | 995 | return -1; |
@@ -1201,11 +1201,11 @@ static void do_toping() | |||
1201 | 1201 | ||
1202 | void DHT_init(void) | 1202 | void DHT_init(void) |
1203 | { | 1203 | { |
1204 | networking_registerhandler(0, &handle_ping_request); | 1204 | networking_registerhandler(temp_net, 0, &handle_ping_request, NULL); |
1205 | networking_registerhandler(1, &handle_ping_response); | 1205 | networking_registerhandler(temp_net, 1, &handle_ping_response, NULL); |
1206 | networking_registerhandler(2, &handle_getnodes); | 1206 | networking_registerhandler(temp_net, 2, &handle_getnodes, NULL); |
1207 | networking_registerhandler(3, &handle_sendnodes); | 1207 | networking_registerhandler(temp_net, 3, &handle_sendnodes, NULL); |
1208 | cryptopacket_registerhandler(254, &handle_NATping); | 1208 | cryptopacket_registerhandler(temp_net_crypto, 254, &handle_NATping); |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | void doDHT(void) | 1211 | void doDHT(void) |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index ad1337ef..3045e215 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -121,7 +121,7 @@ static int LAN_ip(IP ip) | |||
121 | return -1; | 121 | return -1; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int handle_LANdiscovery(IP_Port source, uint8_t *packet, uint32_t length) | 124 | static int handle_LANdiscovery(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
125 | { | 125 | { |
126 | if (LAN_ip(source.ip) == -1) | 126 | if (LAN_ip(source.ip) == -1) |
127 | return 1; | 127 | return 1; |
@@ -140,11 +140,11 @@ int send_LANdiscovery(uint16_t port) | |||
140 | data[0] = 33; | 140 | data[0] = 33; |
141 | memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 141 | memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); |
142 | IP_Port ip_port = {broadcast_ip(), port}; | 142 | IP_Port ip_port = {broadcast_ip(), port}; |
143 | return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); | 143 | return sendpacket(temp_net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); |
144 | } | 144 | } |
145 | 145 | ||
146 | 146 | ||
147 | void LANdiscovery_init(void) | 147 | void LANdiscovery_init(void) |
148 | { | 148 | { |
149 | networking_registerhandler(33, &handle_LANdiscovery); | 149 | networking_registerhandler(temp_net, 33, &handle_LANdiscovery, NULL); |
150 | } | 150 | } |
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index 506a06eb..3e71ffbb 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -28,97 +28,6 @@ | |||
28 | 28 | ||
29 | #include "Lossless_UDP.h" | 29 | #include "Lossless_UDP.h" |
30 | 30 | ||
31 | /* maximum data packets in sent and receive queues. */ | ||
32 | #define MAX_QUEUE_NUM 16 | ||
33 | |||
34 | /* maximum number of data packets in the buffer */ | ||
35 | #define BUFFER_PACKET_NUM (16-1) | ||
36 | |||
37 | /* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ | ||
38 | #define CONNEXION_TIMEOUT 5 | ||
39 | |||
40 | /* initial amount of sync/hanshake packets to send per second. */ | ||
41 | #define SYNC_RATE 2 | ||
42 | |||
43 | /* initial send rate of data. */ | ||
44 | #define DATA_SYNC_RATE 30 | ||
45 | |||
46 | typedef struct { | ||
47 | uint8_t data[MAX_DATA_SIZE]; | ||
48 | uint16_t size; | ||
49 | } Data; | ||
50 | |||
51 | typedef struct { | ||
52 | IP_Port ip_port; | ||
53 | |||
54 | /* | ||
55 | * 0 if connection is dead, 1 if attempting handshake, | ||
56 | * 2 if handshake is done (we start sending SYNC packets) | ||
57 | * 3 if we are sending SYNC packets and can send data | ||
58 | * 4 if the connection has timed out. | ||
59 | */ | ||
60 | uint8_t status; | ||
61 | |||
62 | /* | ||
63 | * 1 or 2 if connection was initiated by someone else, 0 if not. | ||
64 | * 2 if incoming_connection() has not returned it yet, 1 if it has. | ||
65 | */ | ||
66 | uint8_t inbound; | ||
67 | |||
68 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | ||
69 | uint16_t data_rate; /* current data packet send rate packets per second. */ | ||
70 | |||
71 | uint64_t last_SYNC; /* time our last SYNC packet was sent. */ | ||
72 | uint64_t last_sent; /* time our last data or handshake packet was sent. */ | ||
73 | uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */ | ||
74 | uint64_t last_recvdata; /* time we last received a DATA packet from the other */ | ||
75 | uint64_t killat; /* time to kill the connection */ | ||
76 | |||
77 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | ||
78 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | ||
79 | |||
80 | uint32_t handshake_id1; | ||
81 | uint32_t handshake_id2; | ||
82 | |||
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. */ | ||
113 | } Connection; | ||
114 | |||
115 | |||
116 | static Connection *connections; | ||
117 | |||
118 | static uint32_t connections_length; /* Length of connections array */ | ||
119 | static uint32_t connections_number; /* Number of connections in connections array */ | ||
120 | |||
121 | #define MAX_CONNECTIONS connections_length | ||
122 | 31 | ||
123 | /* Functions */ | 32 | /* Functions */ |
124 | 33 | ||
@@ -127,22 +36,20 @@ static uint32_t connections_number; /* Number of connections in connections arra | |||
127 | * Return -1 if there are no connections like we are looking for | 36 | * Return -1 if there are no connections like we are looking for |
128 | * Return id if it found it | 37 | * Return id if it found it |
129 | */ | 38 | */ |
130 | int getconnection_id(IP_Port ip_port) | 39 | int getconnection_id(Lossless_UDP * ludp, IP_Port ip_port) |
131 | { | 40 | { |
132 | uint32_t i; | 41 | uint32_t i; |
133 | 42 | ||
134 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 43 | for (i = 0; i < ludp->connections_length; ++i) { |
135 | if (connections[i].ip_port.ip.i == ip_port.ip.i && | 44 | if (ludp->connections[i].ip_port.ip.i == ip_port.ip.i && |
136 | connections[i].ip_port.port == ip_port.port && | 45 | ludp->connections[i].ip_port.port == ip_port.port && |
137 | connections[i].status > 0) | 46 | ludp->connections[i].status > 0) |
138 | return i; | 47 | return i; |
139 | } | 48 | } |
140 | 49 | ||
141 | return -1; | 50 | return -1; |
142 | } | 51 | } |
143 | 52 | ||
144 | /* table of random numbers used below. */ | ||
145 | static uint32_t randtable[6][256]; | ||
146 | 53 | ||
147 | /* | 54 | /* |
148 | * Generate a handshake_id which depends on the ip_port. | 55 | * Generate a handshake_id which depends on the ip_port. |
@@ -150,15 +57,15 @@ static uint32_t randtable[6][256]; | |||
150 | * | 57 | * |
151 | * TODO: make this better | 58 | * TODO: make this better |
152 | */ | 59 | */ |
153 | static uint32_t handshake_id(IP_Port source) | 60 | static uint32_t handshake_id(Lossless_UDP * ludp, IP_Port source) |
154 | { | 61 | { |
155 | uint32_t id = 0, i; | 62 | uint32_t id = 0, i; |
156 | 63 | ||
157 | for (i = 0; i < 6; ++i) { | 64 | for (i = 0; i < 6; ++i) { |
158 | if (randtable[i][((uint8_t *)&source)[i]] == 0) | 65 | if (ludp->randtable[i][((uint8_t *)&source)[i]] == 0) |
159 | randtable[i][((uint8_t *)&source)[i]] = random_int(); | 66 | ludp->randtable[i][((uint8_t *)&source)[i]] = random_int(); |
160 | 67 | ||
161 | id ^= randtable[i][((uint8_t *)&source)[i]]; | 68 | id ^= ludp->randtable[i][((uint8_t *)&source)[i]]; |
162 | } | 69 | } |
163 | 70 | ||
164 | if (id == 0) /* id can't be zero */ | 71 | if (id == 0) /* id can't be zero */ |
@@ -172,10 +79,10 @@ static uint32_t handshake_id(IP_Port source) | |||
172 | * | 79 | * |
173 | * TODO: make this better | 80 | * TODO: make this better |
174 | */ | 81 | */ |
175 | static void change_handshake(IP_Port source) | 82 | static void change_handshake(Lossless_UDP * ludp, IP_Port source) |
176 | { | 83 | { |
177 | uint8_t rand = random_int() % 4; | 84 | uint8_t rand = random_int() % 4; |
178 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); | 85 | ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int(); |
179 | } | 86 | } |
180 | 87 | ||
181 | /* | 88 | /* |
@@ -184,33 +91,33 @@ static void change_handshake(IP_Port source) | |||
184 | * Return -1 if it could not initialize the connectiont | 91 | * Return -1 if it could not initialize the connectiont |
185 | * If there already was an existing connection to that ip_port return its number. | 92 | * If there already was an existing connection to that ip_port return its number. |
186 | */ | 93 | */ |
187 | int new_connection(IP_Port ip_port) | 94 | int new_connection(Lossless_UDP * ludp, IP_Port ip_port) |
188 | { | 95 | { |
189 | int connect = getconnection_id(ip_port); | 96 | int connect = getconnection_id(ludp, ip_port); |
190 | 97 | ||
191 | if (connect != -1) | 98 | if (connect != -1) |
192 | return connect; | 99 | return connect; |
193 | 100 | ||
194 | if (connections_number == connections_length) { | 101 | if (ludp->connections_number == ludp->connections_length) { |
195 | Connection *temp; | 102 | Connection *temp; |
196 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 103 | temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1)); |
197 | 104 | ||
198 | if (temp == NULL) | 105 | if (temp == NULL) |
199 | return -1; | 106 | return -1; |
200 | 107 | ||
201 | memset(&temp[connections_length], 0, sizeof(Connection)); | 108 | memset(&temp[ludp->connections_length], 0, sizeof(Connection)); |
202 | ++connections_length; | 109 | ++ludp->connections_length; |
203 | connections = temp; | 110 | ludp->connections = temp; |
204 | } | 111 | } |
205 | 112 | ||
206 | uint32_t i; | 113 | uint32_t i; |
207 | 114 | ||
208 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 115 | for (i = 0; i < ludp->connections_length; ++i) { |
209 | if (connections[i].status == 0) { | 116 | if (ludp->connections[i].status == 0) { |
210 | memset(&connections[i], 0, sizeof(Connection)); | 117 | memset(&ludp->connections[i], 0, sizeof(Connection)); |
211 | uint32_t handshake_id1 = handshake_id(ip_port); | 118 | uint32_t handshake_id1 = handshake_id(ludp, ip_port); |
212 | 119 | ||
213 | connections[i] = (Connection) { | 120 | ludp->connections[i] = (Connection) { |
214 | .ip_port = ip_port, | 121 | .ip_port = ip_port, |
215 | .status = 1, | 122 | .status = 1, |
216 | .inbound = 0, | 123 | .inbound = 0, |
@@ -227,7 +134,7 @@ int new_connection(IP_Port ip_port) | |||
227 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 134 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ |
228 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT | 135 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT |
229 | }; | 136 | }; |
230 | ++connections_number; | 137 | ++ludp->connections_number; |
231 | 138 | ||
232 | return i; | 139 | return i; |
233 | } | 140 | } |
@@ -241,31 +148,31 @@ int new_connection(IP_Port ip_port) | |||
241 | * Returns an integer corresponding to the connection id. | 148 | * Returns an integer corresponding to the connection id. |
242 | * Return -1 if it could not initialize the connection. | 149 | * Return -1 if it could not initialize the connection. |
243 | */ | 150 | */ |
244 | static int new_inconnection(IP_Port ip_port) | 151 | static int new_inconnection(Lossless_UDP * ludp, IP_Port ip_port) |
245 | { | 152 | { |
246 | if (getconnection_id(ip_port) != -1) | 153 | if (getconnection_id(ludp, ip_port) != -1) |
247 | return -1; | 154 | return -1; |
248 | 155 | ||
249 | if (connections_number == connections_length) { | 156 | if (ludp->connections_number == ludp->connections_length) { |
250 | Connection *temp; | 157 | Connection *temp; |
251 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 158 | temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1)); |
252 | 159 | ||
253 | if (temp == NULL) | 160 | if (temp == NULL) |
254 | return -1; | 161 | return -1; |
255 | 162 | ||
256 | memset(&temp[connections_length], 0, sizeof(Connection)); | 163 | memset(&temp[ludp->connections_length], 0, sizeof(Connection)); |
257 | ++connections_length; | 164 | ++ludp->connections_length; |
258 | connections = temp; | 165 | ludp->connections = temp; |
259 | } | 166 | } |
260 | 167 | ||
261 | uint32_t i; | 168 | uint32_t i; |
262 | 169 | ||
263 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 170 | for (i = 0; i < ludp->connections_length; ++i) { |
264 | if (connections[i].status == 0) { | 171 | if (ludp->connections[i].status == 0) { |
265 | memset(&connections[i], 0, sizeof(Connection)); | 172 | memset(&ludp->connections[i], 0, sizeof(Connection)); |
266 | uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 173 | uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; |
267 | 174 | ||
268 | connections[i] = (Connection) { | 175 | ludp->connections[i] = (Connection) { |
269 | .ip_port = ip_port, | 176 | .ip_port = ip_port, |
270 | .status = 2, | 177 | .status = 2, |
271 | .inbound = 2, | 178 | .inbound = 2, |
@@ -281,7 +188,7 @@ static int new_inconnection(IP_Port ip_port) | |||
281 | /* if this connection isn't handled within the timeout kill it. */ | 188 | /* if this connection isn't handled within the timeout kill it. */ |
282 | .killat = current_time() + 1000000UL * timeout | 189 | .killat = current_time() + 1000000UL * timeout |
283 | }; | 190 | }; |
284 | ++connections_number; | 191 | ++ludp->connections_number; |
285 | return i; | 192 | return i; |
286 | } | 193 | } |
287 | } | 194 | } |
@@ -293,13 +200,13 @@ static int new_inconnection(IP_Port ip_port) | |||
293 | * Returns an integer corresponding to the next connection in our incoming connection list. | 200 | * Returns an integer corresponding to the next connection in our incoming connection list. |
294 | * Return -1 if there are no new incoming connections in the list. | 201 | * Return -1 if there are no new incoming connections in the list. |
295 | */ | 202 | */ |
296 | int incoming_connection(void) | 203 | int incoming_connection(Lossless_UDP * ludp) |
297 | { | 204 | { |
298 | uint32_t i; | 205 | uint32_t i; |
299 | 206 | ||
300 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 207 | for (i = 0; i < ludp->connections_length; ++i) { |
301 | if (connections[i].inbound == 2) { | 208 | if (ludp->connections[i].inbound == 2) { |
302 | connections[i].inbound = 1; | 209 | ludp->connections[i].inbound = 1; |
303 | return i; | 210 | return i; |
304 | } | 211 | } |
305 | } | 212 | } |
@@ -308,46 +215,46 @@ int incoming_connection(void) | |||
308 | } | 215 | } |
309 | 216 | ||
310 | /* Try to free some memory from the connections array. */ | 217 | /* Try to free some memory from the connections array. */ |
311 | static void free_connections(void) | 218 | static void free_connections(Lossless_UDP * ludp) |
312 | { | 219 | { |
313 | uint32_t i; | 220 | uint32_t i; |
314 | 221 | ||
315 | for (i = connections_length; i != 0; --i) | 222 | for (i = ludp->connections_length; i != 0; --i) |
316 | if (connections[i - 1].status != 0) | 223 | if (ludp->connections[i - 1].status != 0) |
317 | break; | 224 | break; |
318 | 225 | ||
319 | if (connections_length == i) | 226 | if (ludp->connections_length == i) |
320 | return; | 227 | return; |
321 | 228 | ||
322 | if (i == 0) { | 229 | if (i == 0) { |
323 | free(connections); | 230 | free(ludp->connections); |
324 | connections = NULL; | 231 | ludp->connections = NULL; |
325 | connections_length = i; | 232 | ludp->connections_length = i; |
326 | return; | 233 | return; |
327 | } | 234 | } |
328 | 235 | ||
329 | Connection *temp; | 236 | Connection *temp; |
330 | temp = realloc(connections, sizeof(Connection) * i); | 237 | temp = realloc(ludp->connections, sizeof(Connection) * i); |
331 | 238 | ||
332 | if (temp == NULL && i != 0) | 239 | if (temp == NULL && i != 0) |
333 | return; | 240 | return; |
334 | 241 | ||
335 | connections = temp; | 242 | ludp->connections = temp; |
336 | connections_length = i; | 243 | ludp->connections_length = i; |
337 | } | 244 | } |
338 | 245 | ||
339 | /* | 246 | /* |
340 | * Return -1 if it could not kill the connection. | 247 | * Return -1 if it could not kill the connection. |
341 | * Return 0 if killed successfully | 248 | * Return 0 if killed successfully |
342 | */ | 249 | */ |
343 | int kill_connection(int connection_id) | 250 | int kill_connection(Lossless_UDP * ludp, int connection_id) |
344 | { | 251 | { |
345 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 252 | if (connection_id >= 0 && connection_id < ludp->connections_length) { |
346 | if (connections[connection_id].status > 0) { | 253 | if (ludp->connections[connection_id].status > 0) { |
347 | connections[connection_id].status = 0; | 254 | ludp->connections[connection_id].status = 0; |
348 | change_handshake(connections[connection_id].ip_port); | 255 | change_handshake(ludp, ludp->connections[connection_id].ip_port); |
349 | --connections_number; | 256 | --ludp->connections_number; |
350 | free_connections(); | 257 | free_connections(ludp); |
351 | return 0; | 258 | return 0; |
352 | } | 259 | } |
353 | } | 260 | } |
@@ -360,11 +267,11 @@ int kill_connection(int connection_id) | |||
360 | * Return -1 if it can not kill the connection. | 267 | * Return -1 if it can not kill the connection. |
361 | * Return 0 if it will kill it. | 268 | * Return 0 if it will kill it. |
362 | */ | 269 | */ |
363 | int kill_connection_in(int connection_id, uint32_t seconds) | 270 | int kill_connection_in(Lossless_UDP * ludp, int connection_id, uint32_t seconds) |
364 | { | 271 | { |
365 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 272 | if (connection_id >= 0 && connection_id < ludp->connections_length) { |
366 | if (connections[connection_id].status > 0) { | 273 | if (ludp->connections[connection_id].status > 0) { |
367 | connections[connection_id].killat = current_time() + 1000000UL * seconds; | 274 | ludp->connections[connection_id].killat = current_time() + 1000000UL * seconds; |
368 | return 0; | 275 | return 0; |
369 | } | 276 | } |
370 | } | 277 | } |
@@ -380,65 +287,65 @@ int kill_connection_in(int connection_id, uint32_t seconds) | |||
380 | * Return 3 if fully connected. | 287 | * Return 3 if fully connected. |
381 | * Return 4 if timed out and waiting to be killed. | 288 | * Return 4 if timed out and waiting to be killed. |
382 | */ | 289 | */ |
383 | int is_connected(int connection_id) | 290 | int is_connected(Lossless_UDP * ludp, int connection_id) |
384 | { | 291 | { |
385 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 292 | if (connection_id >= 0 && connection_id < ludp->connections_length) |
386 | return connections[connection_id].status; | 293 | return ludp->connections[connection_id].status; |
387 | 294 | ||
388 | return 0; | 295 | return 0; |
389 | } | 296 | } |
390 | 297 | ||
391 | /* returns the ip_port of the corresponding connection. */ | 298 | /* returns the ip_port of the corresponding connection. */ |
392 | IP_Port connection_ip(int connection_id) | 299 | IP_Port connection_ip(Lossless_UDP * ludp, int connection_id) |
393 | { | 300 | { |
394 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 301 | if (connection_id >= 0 && connection_id < ludp->connections_length) |
395 | return connections[connection_id].ip_port; | 302 | return ludp->connections[connection_id].ip_port; |
396 | 303 | ||
397 | IP_Port zero = {{{0}}, 0}; | 304 | IP_Port zero = {{{0}}, 0}; |
398 | return zero; | 305 | return zero; |
399 | } | 306 | } |
400 | 307 | ||
401 | /* returns the number of packets in the queue waiting to be successfully sent. */ | 308 | /* returns the number of packets in the queue waiting to be successfully sent. */ |
402 | uint32_t sendqueue(int connection_id) | 309 | uint32_t sendqueue(Lossless_UDP * ludp, int connection_id) |
403 | { | 310 | { |
404 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 311 | if (connection_id < 0 || connection_id >= ludp->connections_length) |
405 | return 0; | 312 | return 0; |
406 | 313 | ||
407 | return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; | 314 | return ludp->connections[connection_id].sendbuff_packetnum - ludp->connections[connection_id].successful_sent; |
408 | } | 315 | } |
409 | 316 | ||
410 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ | 317 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ |
411 | uint32_t recvqueue(int connection_id) | 318 | uint32_t recvqueue(Lossless_UDP * ludp, int connection_id) |
412 | { | 319 | { |
413 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 320 | if (connection_id < 0 || connection_id >= ludp->connections_length) |
414 | return 0; | 321 | return 0; |
415 | 322 | ||
416 | return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; | 323 | return ludp->connections[connection_id].recv_packetnum - ludp->connections[connection_id].successful_read; |
417 | } | 324 | } |
418 | 325 | ||
419 | /* returns the id of the next packet in the queue | 326 | /* returns the id of the next packet in the queue |
420 | return -1 if no packet in queue */ | 327 | return -1 if no packet in queue */ |
421 | char id_packet(int connection_id) | 328 | char id_packet(Lossless_UDP * ludp, int connection_id) |
422 | { | 329 | { |
423 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 330 | if (connection_id < 0 || connection_id >= ludp->connections_length) |
424 | return -1; | 331 | return -1; |
425 | 332 | ||
426 | if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) | 333 | if (recvqueue(ludp, connection_id) != 0 && ludp->connections[connection_id].status != 0) |
427 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; | 334 | return ludp->connections[connection_id].recvbuffer[ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; |
428 | 335 | ||
429 | return -1; | 336 | return -1; |
430 | } | 337 | } |
431 | 338 | ||
432 | /* return 0 if there is no received data in the buffer. | 339 | /* return 0 if there is no received data in the buffer. |
433 | return length of received packet if successful */ | 340 | return length of received packet if successful */ |
434 | int read_packet(int connection_id, uint8_t *data) | 341 | int read_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data) |
435 | { | 342 | { |
436 | if (recvqueue(connection_id) != 0) { | 343 | if (recvqueue(ludp, connection_id) != 0) { |
437 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; | 344 | uint16_t index = ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM; |
438 | uint16_t size = connections[connection_id].recvbuffer[index].size; | 345 | uint16_t size = ludp->connections[connection_id].recvbuffer[index].size; |
439 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); | 346 | memcpy(data, ludp->connections[connection_id].recvbuffer[index].data, size); |
440 | ++connections[connection_id].successful_read; | 347 | ++ludp->connections[connection_id].successful_read; |
441 | connections[connection_id].recvbuffer[index].size = 0; | 348 | ludp->connections[connection_id].recvbuffer[index].size = 0; |
442 | return size; | 349 | return size; |
443 | } | 350 | } |
444 | 351 | ||
@@ -449,16 +356,16 @@ int read_packet(int connection_id, uint8_t *data) | |||
449 | * Return 0 if data could not be put in packet queue | 356 | * Return 0 if data could not be put in packet queue |
450 | * Return 1 if data was put into the queue | 357 | * Return 1 if data was put into the queue |
451 | */ | 358 | */ |
452 | int write_packet(int connection_id, uint8_t *data, uint32_t length) | 359 | int write_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data, uint32_t length) |
453 | { | 360 | { |
454 | if (length > MAX_DATA_SIZE || length == 0) | 361 | if (length > MAX_DATA_SIZE || length == 0) |
455 | return 0; | 362 | return 0; |
456 | 363 | ||
457 | if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { | 364 | if (sendqueue(ludp, connection_id) < BUFFER_PACKET_NUM) { |
458 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | 365 | uint32_t index = ludp->connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; |
459 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | 366 | memcpy(ludp->connections[connection_id].sendbuffer[index].data, data, length); |
460 | connections[connection_id].sendbuffer[index].size = length; | 367 | ludp->connections[connection_id].sendbuffer[index].size = length; |
461 | connections[connection_id].sendbuff_packetnum++; | 368 | ludp->connections[connection_id].sendbuff_packetnum++; |
462 | return 1; | 369 | return 1; |
463 | } | 370 | } |
464 | 371 | ||
@@ -466,18 +373,18 @@ int write_packet(int connection_id, uint8_t *data, uint32_t length) | |||
466 | } | 373 | } |
467 | 374 | ||
468 | /* put the packet numbers the we are missing in requested and return the number */ | 375 | /* put the packet numbers the we are missing in requested and return the number */ |
469 | uint32_t missing_packets(int connection_id, uint32_t *requested) | 376 | uint32_t missing_packets(Lossless_UDP * ludp, int connection_id, uint32_t *requested) |
470 | { | 377 | { |
471 | uint32_t number = 0; | 378 | uint32_t number = 0; |
472 | uint32_t i; | 379 | uint32_t i; |
473 | uint32_t temp; | 380 | uint32_t temp; |
474 | 381 | ||
475 | /* don't request packets if the buffer is full. */ | 382 | /* don't request packets if the buffer is full. */ |
476 | if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) | 383 | if (recvqueue(ludp, connection_id) >= (BUFFER_PACKET_NUM - 1)) |
477 | return 0; | 384 | return 0; |
478 | 385 | ||
479 | for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { | 386 | for (i = ludp->connections[connection_id].recv_packetnum; i != ludp->connections[connection_id].osent_packetnum; i++) { |
480 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { | 387 | if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { |
481 | temp = htonl(i); | 388 | temp = htonl(i); |
482 | memcpy(requested + number, &temp, 4); | 389 | memcpy(requested + number, &temp, 4); |
483 | ++number; | 390 | ++number; |
@@ -485,7 +392,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested) | |||
485 | } | 392 | } |
486 | 393 | ||
487 | if (number == 0) | 394 | if (number == 0) |
488 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; | 395 | ludp->connections[connection_id].recv_packetnum = ludp->connections[connection_id].osent_packetnum; |
489 | 396 | ||
490 | return number; | 397 | return number; |
491 | } | 398 | } |
@@ -496,7 +403,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested) | |||
496 | * see http://wiki.tox.im/index.php/Lossless_UDP for more information. | 403 | * see http://wiki.tox.im/index.php/Lossless_UDP for more information. |
497 | */ | 404 | */ |
498 | 405 | ||
499 | static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 406 | static int send_handshake(Lossless_UDP * ludp, IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) |
500 | { | 407 | { |
501 | uint8_t packet[1 + 4 + 4]; | 408 | uint8_t packet[1 + 4 + 4]; |
502 | uint32_t temp; | 409 | uint32_t temp; |
@@ -507,21 +414,21 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand | |||
507 | temp = htonl(handshake_id2); | 414 | temp = htonl(handshake_id2); |
508 | memcpy(packet + 5, &temp, 4); | 415 | memcpy(packet + 5, &temp, 4); |
509 | 416 | ||
510 | return sendpacket(ip_port, packet, sizeof(packet)); | 417 | return sendpacket(ludp->net->sock, ip_port, packet, sizeof(packet)); |
511 | } | 418 | } |
512 | 419 | ||
513 | static int send_SYNC(uint32_t connection_id) | 420 | static int send_SYNC(Lossless_UDP * ludp, uint32_t connection_id) |
514 | { | 421 | { |
515 | uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; | 422 | uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; |
516 | uint16_t index = 0; | 423 | uint16_t index = 0; |
517 | 424 | ||
518 | IP_Port ip_port = connections[connection_id].ip_port; | 425 | IP_Port ip_port = ludp->connections[connection_id].ip_port; |
519 | uint8_t counter = connections[connection_id].send_counter; | 426 | uint8_t counter = ludp->connections[connection_id].send_counter; |
520 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); | 427 | uint32_t recv_packetnum = htonl(ludp->connections[connection_id].recv_packetnum); |
521 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); | 428 | uint32_t sent_packetnum = htonl(ludp->connections[connection_id].sent_packetnum); |
522 | 429 | ||
523 | uint32_t requested[BUFFER_PACKET_NUM]; | 430 | uint32_t requested[BUFFER_PACKET_NUM]; |
524 | uint32_t number = missing_packets(connection_id, requested); | 431 | uint32_t number = missing_packets(ludp, connection_id, requested); |
525 | 432 | ||
526 | packet[0] = 17; | 433 | packet[0] = 17; |
527 | index += 1; | 434 | index += 1; |
@@ -533,11 +440,11 @@ static int send_SYNC(uint32_t connection_id) | |||
533 | index += 4; | 440 | index += 4; |
534 | memcpy(packet + index, requested, 4 * number); | 441 | memcpy(packet + index, requested, 4 * number); |
535 | 442 | ||
536 | return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2)); | 443 | return sendpacket(ludp->net->sock, ip_port, packet, (number * 4 + 4 + 4 + 2)); |
537 | 444 | ||
538 | } | 445 | } |
539 | 446 | ||
540 | static int send_data_packet(uint32_t connection_id, uint32_t packet_num) | 447 | static int send_data_packet(Lossless_UDP * ludp, uint32_t connection_id, uint32_t packet_num) |
541 | { | 448 | { |
542 | uint32_t index = packet_num % MAX_QUEUE_NUM; | 449 | uint32_t index = packet_num % MAX_QUEUE_NUM; |
543 | uint32_t temp; | 450 | uint32_t temp; |
@@ -545,29 +452,29 @@ static int send_data_packet(uint32_t connection_id, uint32_t packet_num) | |||
545 | packet[0] = 18; | 452 | packet[0] = 18; |
546 | temp = htonl(packet_num); | 453 | temp = htonl(packet_num); |
547 | memcpy(packet + 1, &temp, 4); | 454 | memcpy(packet + 1, &temp, 4); |
548 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, | 455 | memcpy(packet + 5, ludp->connections[connection_id].sendbuffer[index].data, |
549 | connections[connection_id].sendbuffer[index].size); | 456 | ludp->connections[connection_id].sendbuffer[index].size); |
550 | return sendpacket(connections[connection_id].ip_port, packet, | 457 | return sendpacket(ludp->net->sock, ludp->connections[connection_id].ip_port, packet, |
551 | 1 + 4 + connections[connection_id].sendbuffer[index].size); | 458 | 1 + 4 + ludp->connections[connection_id].sendbuffer[index].size); |
552 | } | 459 | } |
553 | 460 | ||
554 | /* sends 1 data packet */ | 461 | /* sends 1 data packet */ |
555 | static int send_DATA(uint32_t connection_id) | 462 | static int send_DATA(Lossless_UDP * ludp, uint32_t connection_id) |
556 | { | 463 | { |
557 | int ret; | 464 | int ret; |
558 | uint32_t buffer[BUFFER_PACKET_NUM]; | 465 | uint32_t buffer[BUFFER_PACKET_NUM]; |
559 | 466 | ||
560 | if (connections[connection_id].num_req_paquets > 0) { | 467 | if (ludp->connections[connection_id].num_req_paquets > 0) { |
561 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); | 468 | ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].req_packets[0]); |
562 | connections[connection_id].num_req_paquets--; | 469 | ludp->connections[connection_id].num_req_paquets--; |
563 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); | 470 | memcpy(buffer, ludp->connections[connection_id].req_packets + 1, ludp->connections[connection_id].num_req_paquets * 4); |
564 | memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); | 471 | memcpy(ludp->connections[connection_id].req_packets, buffer, ludp->connections[connection_id].num_req_paquets * 4); |
565 | return ret; | 472 | return ret; |
566 | } | 473 | } |
567 | 474 | ||
568 | if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { | 475 | if (ludp->connections[connection_id].sendbuff_packetnum != ludp->connections[connection_id].sent_packetnum) { |
569 | ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); | 476 | ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].sent_packetnum); |
570 | connections[connection_id].sent_packetnum++; | 477 | ludp->connections[connection_id].sent_packetnum++; |
571 | return ret; | 478 | return ret; |
572 | } | 479 | } |
573 | 480 | ||
@@ -584,37 +491,38 @@ static int send_DATA(uint32_t connection_id) | |||
584 | 491 | ||
585 | 492 | ||
586 | /* Return 0 if handled correctly, 1 if packet is bad. */ | 493 | /* Return 0 if handled correctly, 1 if packet is bad. */ |
587 | static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length) | 494 | static int handle_handshake(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
588 | { | 495 | { |
496 | Lossless_UDP * ludp = object; | ||
589 | if (length != (1 + 4 + 4)) | 497 | if (length != (1 + 4 + 4)) |
590 | return 1; | 498 | return 1; |
591 | 499 | ||
592 | uint32_t temp; | 500 | uint32_t temp; |
593 | uint32_t handshake_id1, handshake_id2; | 501 | uint32_t handshake_id1, handshake_id2; |
594 | 502 | ||
595 | int connection = getconnection_id(source); | 503 | int connection = getconnection_id(ludp, source); |
596 | memcpy(&temp, packet + 1, 4); | 504 | memcpy(&temp, packet + 1, 4); |
597 | handshake_id1 = ntohl(temp); | 505 | handshake_id1 = ntohl(temp); |
598 | memcpy(&temp, packet + 5, 4); | 506 | memcpy(&temp, packet + 5, 4); |
599 | handshake_id2 = ntohl(temp); | 507 | handshake_id2 = ntohl(temp); |
600 | 508 | ||
601 | if (handshake_id2 == 0 && is_connected(connection) < 3) { | 509 | if (handshake_id2 == 0 && is_connected(ludp, connection) < 3) { |
602 | send_handshake(source, handshake_id(source), handshake_id1); | 510 | send_handshake(ludp, source, handshake_id(ludp, source), handshake_id1); |
603 | return 0; | 511 | return 0; |
604 | } | 512 | } |
605 | 513 | ||
606 | if (is_connected(connection) != 1) | 514 | if (is_connected(ludp, connection) != 1) |
607 | return 1; | 515 | return 1; |
608 | 516 | ||
609 | /* if handshake_id2 is what we sent previously as handshake_id1 */ | 517 | /* if handshake_id2 is what we sent previously as handshake_id1 */ |
610 | if (handshake_id2 == connections[connection].handshake_id1) { | 518 | if (handshake_id2 == ludp->connections[connection].handshake_id1) { |
611 | connections[connection].status = 2; | 519 | ludp->connections[connection].status = 2; |
612 | /* NOTE: is this necessary? | 520 | /* NOTE: is this necessary? |
613 | connections[connection].handshake_id2 = handshake_id1; */ | 521 | ludp->connections[connection].handshake_id2 = handshake_id1; */ |
614 | connections[connection].orecv_packetnum = handshake_id2; | 522 | ludp->connections[connection].orecv_packetnum = handshake_id2; |
615 | connections[connection].osent_packetnum = handshake_id1; | 523 | ludp->connections[connection].osent_packetnum = handshake_id1; |
616 | connections[connection].recv_packetnum = handshake_id1; | 524 | ludp->connections[connection].recv_packetnum = handshake_id1; |
617 | connections[connection].successful_read = handshake_id1; | 525 | ludp->connections[connection].successful_read = handshake_id1; |
618 | } | 526 | } |
619 | 527 | ||
620 | return 0; | 528 | return 0; |
@@ -634,19 +542,19 @@ static int SYNC_valid(uint32_t length) | |||
634 | } | 542 | } |
635 | 543 | ||
636 | /* case 1 in handle_SYNC: */ | 544 | /* case 1 in handle_SYNC: */ |
637 | static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 545 | static int handle_SYNC1(Lossless_UDP * ludp, IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) |
638 | { | 546 | { |
639 | if (handshake_id(source) == recv_packetnum) { | 547 | if (handshake_id(ludp, source) == recv_packetnum) { |
640 | int x = new_inconnection(source); | 548 | int x = new_inconnection(ludp, source); |
641 | 549 | ||
642 | if (x != -1) { | 550 | if (x != -1) { |
643 | connections[x].orecv_packetnum = recv_packetnum; | 551 | ludp->connections[x].orecv_packetnum = recv_packetnum; |
644 | connections[x].sent_packetnum = recv_packetnum; | 552 | ludp->connections[x].sent_packetnum = recv_packetnum; |
645 | connections[x].sendbuff_packetnum = recv_packetnum; | 553 | ludp->connections[x].sendbuff_packetnum = recv_packetnum; |
646 | connections[x].successful_sent = recv_packetnum; | 554 | ludp->connections[x].successful_sent = recv_packetnum; |
647 | connections[x].osent_packetnum = sent_packetnum; | 555 | ludp->connections[x].osent_packetnum = sent_packetnum; |
648 | connections[x].recv_packetnum = sent_packetnum; | 556 | ludp->connections[x].recv_packetnum = sent_packetnum; |
649 | connections[x].successful_read = sent_packetnum; | 557 | ludp->connections[x].successful_read = sent_packetnum; |
650 | 558 | ||
651 | return x; | 559 | return x; |
652 | } | 560 | } |
@@ -656,63 +564,63 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p | |||
656 | } | 564 | } |
657 | 565 | ||
658 | /* case 2 in handle_SYNC: */ | 566 | /* case 2 in handle_SYNC: */ |
659 | static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 567 | static int handle_SYNC2(Lossless_UDP * ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
660 | { | 568 | { |
661 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { | 569 | if (recv_packetnum == ludp->connections[connection_id].orecv_packetnum) { |
662 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ | 570 | /* && sent_packetnum == ludp->connections[connection_id].osent_packetnum) */ |
663 | connections[connection_id].status = 3; | 571 | ludp->connections[connection_id].status = 3; |
664 | connections[connection_id].recv_counter = counter; | 572 | ludp->connections[connection_id].recv_counter = counter; |
665 | ++connections[connection_id].send_counter; | 573 | ++ludp->connections[connection_id].send_counter; |
666 | send_SYNC(connection_id); | 574 | send_SYNC(ludp, connection_id); |
667 | return 0; | 575 | return 0; |
668 | } | 576 | } |
669 | 577 | ||
670 | return 1; | 578 | return 1; |
671 | } | 579 | } |
672 | /* case 3 in handle_SYNC: */ | 580 | /* case 3 in handle_SYNC: */ |
673 | static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, | 581 | static int handle_SYNC3(Lossless_UDP * ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, |
674 | uint32_t *req_packets, | 582 | uint32_t *req_packets, |
675 | uint16_t number) | 583 | uint16_t number) |
676 | { | 584 | { |
677 | uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); | 585 | uint8_t comp_counter = (counter - ludp->connections[connection_id].recv_counter ); |
678 | uint32_t i, temp; | 586 | uint32_t i, temp; |
679 | /* uint32_t comp_1 = (recv_packetnum - connections[connection_id].successful_sent); | 587 | /* uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].successful_sent); |
680 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ | 588 | uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].successful_read); */ |
681 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); | 589 | uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].orecv_packetnum); |
682 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); | 590 | uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].osent_packetnum); |
683 | 591 | ||
684 | /* packet valid */ | 592 | /* packet valid */ |
685 | if (comp_1 <= BUFFER_PACKET_NUM && | 593 | if (comp_1 <= BUFFER_PACKET_NUM && |
686 | comp_2 <= BUFFER_PACKET_NUM && | 594 | comp_2 <= BUFFER_PACKET_NUM && |
687 | comp_counter < 10 && comp_counter != 0) { | 595 | comp_counter < 10 && comp_counter != 0) { |
688 | 596 | ||
689 | connections[connection_id].orecv_packetnum = recv_packetnum; | 597 | ludp->connections[connection_id].orecv_packetnum = recv_packetnum; |
690 | connections[connection_id].osent_packetnum = sent_packetnum; | 598 | ludp->connections[connection_id].osent_packetnum = sent_packetnum; |
691 | connections[connection_id].successful_sent = recv_packetnum; | 599 | ludp->connections[connection_id].successful_sent = recv_packetnum; |
692 | connections[connection_id].last_recvSYNC = current_time(); | 600 | ludp->connections[connection_id].last_recvSYNC = current_time(); |
693 | connections[connection_id].recv_counter = counter; | 601 | ludp->connections[connection_id].recv_counter = counter; |
694 | 602 | ||
695 | ++connections[connection_id].send_counter; | 603 | ++ludp->connections[connection_id].send_counter; |
696 | 604 | ||
697 | for (i = 0; i < number; ++i) { | 605 | for (i = 0; i < number; ++i) { |
698 | temp = ntohl(req_packets[i]); | 606 | temp = ntohl(req_packets[i]); |
699 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); | 607 | memcpy(ludp->connections[connection_id].req_packets + i, &temp, 4 * number); |
700 | } | 608 | } |
701 | 609 | ||
702 | connections[connection_id].num_req_paquets = number; | 610 | ludp->connections[connection_id].num_req_paquets = number; |
703 | return 0; | 611 | return 0; |
704 | } | 612 | } |
705 | 613 | ||
706 | return 1; | 614 | return 1; |
707 | } | 615 | } |
708 | 616 | ||
709 | static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | 617 | static int handle_SYNC(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
710 | { | 618 | { |
711 | 619 | Lossless_UDP * ludp = object; | |
712 | if (!SYNC_valid(length)) | 620 | if (!SYNC_valid(length)) |
713 | return 1; | 621 | return 1; |
714 | 622 | ||
715 | int connection = getconnection_id(source); | 623 | int connection = getconnection_id(ludp, source); |
716 | uint8_t counter; | 624 | uint8_t counter; |
717 | uint32_t temp; | 625 | uint32_t temp; |
718 | uint32_t recv_packetnum, sent_packetnum; | 626 | uint32_t recv_packetnum, sent_packetnum; |
@@ -729,14 +637,14 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | |||
729 | memcpy(req_packets, packet + 10, 4 * number); | 637 | memcpy(req_packets, packet + 10, 4 * number); |
730 | 638 | ||
731 | if (connection == -1) | 639 | if (connection == -1) |
732 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); | 640 | return handle_SYNC1(ludp, source, recv_packetnum, sent_packetnum); |
733 | 641 | ||
734 | if (connections[connection].status == 2) | 642 | if (ludp->connections[connection].status == 2) |
735 | return handle_SYNC2(connection, counter, | 643 | return handle_SYNC2(ludp, connection, counter, |
736 | recv_packetnum, sent_packetnum); | 644 | recv_packetnum, sent_packetnum); |
737 | 645 | ||
738 | if (connections[connection].status == 3) | 646 | if (ludp->connections[connection].status == 3) |
739 | return handle_SYNC3(connection, counter, recv_packetnum, | 647 | return handle_SYNC3(ludp, connection, counter, recv_packetnum, |
740 | sent_packetnum, req_packets, number); | 648 | sent_packetnum, req_packets, number); |
741 | 649 | ||
742 | return 0; | 650 | return 0; |
@@ -746,33 +654,33 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | |||
746 | * Add a packet to the received buffer and set the recv_packetnum of the | 654 | * Add a packet to the received buffer and set the recv_packetnum of the |
747 | * connection to its proper value. Return 1 if data was too big, 0 if not. | 655 | * connection to its proper value. Return 1 if data was too big, 0 if not. |
748 | */ | 656 | */ |
749 | static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | 657 | static int add_recv(Lossless_UDP * ludp, int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) |
750 | { | 658 | { |
751 | if (size > MAX_DATA_SIZE) | 659 | if (size > MAX_DATA_SIZE) |
752 | return 1; | 660 | return 1; |
753 | 661 | ||
754 | uint32_t i; | 662 | uint32_t i; |
755 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 663 | uint32_t maxnum = ludp->connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
756 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 664 | uint32_t sent_packet = data_num - ludp->connections[connection_id].osent_packetnum; |
757 | 665 | ||
758 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 666 | for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
759 | if (i == data_num) { | 667 | if (i == data_num) { |
760 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 668 | memcpy(ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
761 | 669 | ||
762 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 670 | ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
763 | connections[connection_id].last_recvdata = current_time(); | 671 | ludp->connections[connection_id].last_recvdata = current_time(); |
764 | 672 | ||
765 | if (sent_packet < BUFFER_PACKET_NUM) { | 673 | if (sent_packet < BUFFER_PACKET_NUM) { |
766 | connections[connection_id].osent_packetnum = data_num; | 674 | ludp->connections[connection_id].osent_packetnum = data_num; |
767 | } | 675 | } |
768 | 676 | ||
769 | break; | 677 | break; |
770 | } | 678 | } |
771 | } | 679 | } |
772 | 680 | ||
773 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 681 | for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
774 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 682 | if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
775 | connections[connection_id].recv_packetnum = i; | 683 | ludp->connections[connection_id].recv_packetnum = i; |
776 | else | 684 | else |
777 | break; | 685 | break; |
778 | } | 686 | } |
@@ -780,15 +688,16 @@ static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_ | |||
780 | return 0; | 688 | return 0; |
781 | } | 689 | } |
782 | 690 | ||
783 | static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) | 691 | static int handle_data(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
784 | { | 692 | { |
785 | int connection = getconnection_id(source); | 693 | Lossless_UDP * ludp = object; |
694 | int connection = getconnection_id(ludp, source); | ||
786 | 695 | ||
787 | if (connection == -1) | 696 | if (connection == -1) |
788 | return 1; | 697 | return 1; |
789 | 698 | ||
790 | /* Drop the data packet if connection is not connected. */ | 699 | /* Drop the data packet if connection is not connected. */ |
791 | if (connections[connection].status != 3) | 700 | if (ludp->connections[connection].status != 3) |
792 | return 1; | 701 | return 1; |
793 | 702 | ||
794 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) | 703 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) |
@@ -801,76 +710,81 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) | |||
801 | memcpy(&temp, packet + 1, 4); | 710 | memcpy(&temp, packet + 1, 4); |
802 | number = ntohl(temp); | 711 | number = ntohl(temp); |
803 | 712 | ||
804 | return add_recv(connection, number, packet + 5, size); | 713 | return add_recv(ludp, connection, number, packet + 5, size); |
805 | } | 714 | } |
806 | 715 | ||
807 | /* | 716 | /* |
808 | * END of packet handling functions | 717 | * END of packet handling functions |
809 | */ | 718 | */ |
810 | 719 | ||
811 | void LosslessUDP_init(void) | 720 | Lossless_UDP * new_lossless_udp(Networking_Core * net) |
812 | { | 721 | { |
813 | networking_registerhandler(16, &handle_handshake); | 722 | Lossless_UDP * temp = calloc(1, sizeof(Lossless_UDP)); |
814 | networking_registerhandler(17, &handle_SYNC); | 723 | if (temp == NULL) |
815 | networking_registerhandler(18, &handle_data); | 724 | return NULL; |
725 | temp->net = net; | ||
726 | networking_registerhandler(net, 16, &handle_handshake, temp); | ||
727 | networking_registerhandler(net, 17, &handle_SYNC, temp); | ||
728 | networking_registerhandler(net, 18, &handle_data, temp); | ||
729 | return temp; | ||
816 | } | 730 | } |
817 | 731 | ||
818 | /* | 732 | /* |
819 | * Send handshake requests | 733 | * Send handshake requests |
820 | * handshake packets are sent at the same rate as SYNC packets | 734 | * handshake packets are sent at the same rate as SYNC packets |
821 | */ | 735 | */ |
822 | static void doNew(void) | 736 | static void do_new(Lossless_UDP * ludp) |
823 | { | 737 | { |
824 | uint32_t i; | 738 | uint32_t i; |
825 | uint64_t temp_time = current_time(); | 739 | uint64_t temp_time = current_time(); |
826 | 740 | ||
827 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 741 | for (i = 0; i < ludp->connections_length; ++i) { |
828 | if (connections[i].status == 1) | 742 | if (ludp->connections[i].status == 1) |
829 | if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { | 743 | if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) { |
830 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); | 744 | send_handshake(ludp, ludp->connections[i].ip_port, ludp->connections[i].handshake_id1, 0); |
831 | connections[i].last_sent = temp_time; | 745 | ludp->connections[i].last_sent = temp_time; |
832 | } | 746 | } |
833 | 747 | ||
834 | /* kill all timed out connections */ | 748 | /* kill all timed out connections */ |
835 | if (connections[i].status > 0 && | 749 | if (ludp->connections[i].status > 0 && |
836 | (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 750 | (ludp->connections[i].last_recvSYNC + ludp->connections[i].timeout * 1000000UL) < temp_time && |
837 | connections[i].status != 4) { | 751 | ludp->connections[i].status != 4) { |
838 | connections[i].status = 4; | 752 | ludp->connections[i].status = 4; |
839 | /* kill_connection(i); */ | 753 | /* kill_connection(i); */ |
840 | } | 754 | } |
841 | 755 | ||
842 | if (connections[i].status > 0 && connections[i].killat < temp_time) | 756 | if (ludp->connections[i].status > 0 && ludp->connections[i].killat < temp_time) |
843 | kill_connection(i); | 757 | kill_connection(ludp, i); |
844 | } | 758 | } |
845 | } | 759 | } |
846 | 760 | ||
847 | static void doSYNC(void) | 761 | static void do_SYNC(Lossless_UDP * ludp) |
848 | { | 762 | { |
849 | uint32_t i; | 763 | uint32_t i; |
850 | uint64_t temp_time = current_time(); | 764 | uint64_t temp_time = current_time(); |
851 | 765 | ||
852 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 766 | for (i = 0; i < ludp->connections_length; ++i) { |
853 | if (connections[i].status == 2 || connections[i].status == 3) | 767 | if (ludp->connections[i].status == 2 || ludp->connections[i].status == 3) |
854 | if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { | 768 | if ((ludp->connections[i].last_SYNC + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) { |
855 | send_SYNC(i); | 769 | send_SYNC(ludp, i); |
856 | connections[i].last_SYNC = temp_time; | 770 | ludp->connections[i].last_SYNC = temp_time; |
857 | } | 771 | } |
858 | } | 772 | } |
859 | } | 773 | } |
860 | 774 | ||
861 | static void doData(void) | 775 | static void do_data(Lossless_UDP * ludp) |
862 | { | 776 | { |
863 | uint32_t i; | 777 | uint32_t i; |
864 | uint64_t j; | 778 | uint64_t j; |
865 | uint64_t temp_time = current_time(); | 779 | uint64_t temp_time = current_time(); |
866 | 780 | ||
867 | for (i = 0; i < MAX_CONNECTIONS; ++i) | 781 | for (i = 0; i < ludp->connections_length; ++i) |
868 | if (connections[i].status == 3 && sendqueue(i) != 0) | 782 | if (ludp->connections[i].status == 3 && sendqueue(ludp, i) != 0) |
869 | if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) { | 783 | if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].data_rate)) <= temp_time) { |
870 | for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate)) | 784 | for (j = ludp->connections[i].last_sent; j < temp_time; j += (1000000UL / ludp->connections[i].data_rate)) |
871 | send_DATA(i); | 785 | send_DATA(ludp, i); |
872 | 786 | ||
873 | connections[i].last_sent = temp_time; | 787 | ludp->connections[i].last_sent = temp_time; |
874 | } | 788 | } |
875 | } | 789 | } |
876 | 790 | ||
@@ -881,32 +795,38 @@ static void doData(void) | |||
881 | * | 795 | * |
882 | * TODO: flow control. | 796 | * TODO: flow control. |
883 | */ | 797 | */ |
884 | static void adjustRates(void) | 798 | static void adjust_rates(Lossless_UDP * ludp) |
885 | { | 799 | { |
886 | uint32_t i; | 800 | uint32_t i; |
887 | uint64_t temp_time = current_time(); | 801 | uint64_t temp_time = current_time(); |
888 | 802 | ||
889 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 803 | for (i = 0; i < ludp->connections_length; ++i) { |
890 | if (connections[i].status == 1 || connections[i].status == 2) | 804 | if (ludp->connections[i].status == 1 || ludp->connections[i].status == 2) |
891 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 805 | ludp->connections[i].SYNC_rate = MAX_SYNC_RATE; |
892 | 806 | ||
893 | if (connections[i].status == 3) { | 807 | if (ludp->connections[i].status == 3) { |
894 | if (sendqueue(i) != 0) { | 808 | if (sendqueue(ludp, i) != 0) { |
895 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; | 809 | ludp->connections[i].data_rate = (BUFFER_PACKET_NUM - ludp->connections[i].num_req_paquets) * MAX_SYNC_RATE; |
896 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 810 | ludp->connections[i].SYNC_rate = MAX_SYNC_RATE; |
897 | } else if (connections[i].last_recvdata + 1000000UL > temp_time) | 811 | } else if (ludp->connections[i].last_recvdata + 1000000UL > temp_time) |
898 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 812 | ludp->connections[i].SYNC_rate = MAX_SYNC_RATE; |
899 | else | 813 | else |
900 | connections[i].SYNC_rate = SYNC_RATE; | 814 | ludp->connections[i].SYNC_rate = SYNC_RATE; |
901 | } | 815 | } |
902 | } | 816 | } |
903 | } | 817 | } |
904 | 818 | ||
905 | /* Call this function a couple times per second It's the main loop. */ | 819 | /* Call this function a couple times per second It's the main loop. */ |
906 | void doLossless_UDP(void) | 820 | void do_lossless_udp(Lossless_UDP * ludp) |
907 | { | 821 | { |
908 | doNew(); | 822 | do_new(ludp); |
909 | doSYNC(); | 823 | do_SYNC(ludp); |
910 | doData(); | 824 | do_data(ludp); |
911 | adjustRates(); | 825 | adjust_rates(ludp); |
912 | } | 826 | } |
827 | |||
828 | void kill_lossless_udp(Lossless_UDP * ludp) | ||
829 | { | ||
830 | free(ludp->connections); | ||
831 | free(ludp); | ||
832 | } \ No newline at end of file | ||
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h index bd426ee0..6d0ee6a2 100644 --- a/core/Lossless_UDP.h +++ b/core/Lossless_UDP.h | |||
@@ -33,72 +33,168 @@ 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 | /* maximum data packets in sent and receive queues. */ | ||
37 | #define MAX_QUEUE_NUM 16 | ||
38 | |||
39 | /* maximum number of data packets in the buffer */ | ||
40 | #define BUFFER_PACKET_NUM (16-1) | ||
41 | |||
42 | /* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ | ||
43 | #define CONNEXION_TIMEOUT 5 | ||
44 | |||
45 | /* initial amount of sync/hanshake packets to send per second. */ | ||
46 | #define SYNC_RATE 2 | ||
47 | |||
48 | /* initial send rate of data. */ | ||
49 | #define DATA_SYNC_RATE 30 | ||
50 | |||
51 | typedef struct { | ||
52 | uint8_t data[MAX_DATA_SIZE]; | ||
53 | uint16_t size; | ||
54 | } Data; | ||
55 | |||
56 | typedef struct { | ||
57 | IP_Port ip_port; | ||
58 | |||
59 | /* | ||
60 | * 0 if connection is dead, 1 if attempting handshake, | ||
61 | * 2 if handshake is done (we start sending SYNC packets) | ||
62 | * 3 if we are sending SYNC packets and can send data | ||
63 | * 4 if the connection has timed out. | ||
64 | */ | ||
65 | uint8_t status; | ||
66 | |||
67 | /* | ||
68 | * 1 or 2 if connection was initiated by someone else, 0 if not. | ||
69 | * 2 if incoming_connection() has not returned it yet, 1 if it has. | ||
70 | */ | ||
71 | uint8_t inbound; | ||
72 | |||
73 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | ||
74 | uint16_t data_rate; /* current data packet send rate packets per second. */ | ||
75 | |||
76 | uint64_t last_SYNC; /* time our last SYNC packet was sent. */ | ||
77 | uint64_t last_sent; /* time our last data or handshake packet was sent. */ | ||
78 | uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */ | ||
79 | uint64_t last_recvdata; /* time we last received a DATA packet from the other */ | ||
80 | uint64_t killat; /* time to kill the connection */ | ||
81 | |||
82 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | ||
83 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | ||
84 | |||
85 | uint32_t handshake_id1; | ||
86 | uint32_t handshake_id2; | ||
87 | |||
88 | /* number of data packets received (also used as handshake_id1) */ | ||
89 | uint32_t recv_packetnum; | ||
90 | |||
91 | /* number of packets received by the other peer */ | ||
92 | uint32_t orecv_packetnum; | ||
93 | |||
94 | /* number of data packets sent */ | ||
95 | uint32_t sent_packetnum; | ||
96 | |||
97 | /* number of packets sent by the other peer. */ | ||
98 | uint32_t osent_packetnum; | ||
99 | |||
100 | /* number of latest packet written onto the sendbuffer */ | ||
101 | uint32_t sendbuff_packetnum; | ||
102 | |||
103 | /* we know all packets before that number were successfully sent */ | ||
104 | uint32_t successful_sent; | ||
105 | |||
106 | /* packet number of last packet read with the read_packet function */ | ||
107 | uint32_t successful_read; | ||
108 | |||
109 | /* list of currently requested packet numbers(by the other person) */ | ||
110 | uint32_t req_packets[BUFFER_PACKET_NUM]; | ||
111 | |||
112 | /* total number of currently requested packets(by the other person) */ | ||
113 | uint16_t num_req_paquets; | ||
114 | |||
115 | uint8_t recv_counter; | ||
116 | uint8_t send_counter; | ||
117 | uint8_t timeout; /* connection timeout in seconds. */ | ||
118 | } Connection; | ||
119 | |||
120 | typedef struct { | ||
121 | Networking_Core *net; | ||
122 | Connection *connections; | ||
123 | |||
124 | uint32_t connections_length; /* Length of connections array */ | ||
125 | uint32_t connections_number; /* Number of connections in connections array */ | ||
126 | |||
127 | /* table of random numbers used in handshake_id. */ | ||
128 | uint32_t randtable[6][256]; | ||
129 | |||
130 | } Lossless_UDP; | ||
131 | |||
36 | /* | 132 | /* |
37 | * Initialize a new connection to ip_port | 133 | * Initialize a new connection to ip_port |
38 | * Returns an integer corresponding to the connection id. | 134 | * Returns an integer corresponding to the connection id. |
39 | * Return -1 if it could not initialize the connection. | 135 | * Return -1 if it could not initialize the connection. |
40 | * Return number if there already was an existing connection to that ip_port. | 136 | * Return number if there already was an existing connection to that ip_port. |
41 | */ | 137 | */ |
42 | int new_connection(IP_Port ip_port); | 138 | int new_connection(Lossless_UDP * ludp, IP_Port ip_port); |
43 | 139 | ||
44 | /* | 140 | /* |
45 | * Get connection id from IP_Port. | 141 | * Get connection id from IP_Port. |
46 | * Return -1 if there are no connections like we are looking for. | 142 | * Return -1 if there are no connections like we are looking for. |
47 | * Return id if it found it . | 143 | * Return id if it found it . |
48 | */ | 144 | */ |
49 | int getconnection_id(IP_Port ip_port); | 145 | int getconnection_id(Lossless_UDP * ludp, IP_Port ip_port); |
50 | 146 | ||
51 | /* | 147 | /* |
52 | * Returns an int corresponding to the next connection in our imcoming connection list | 148 | * 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. | 149 | * Return -1 if there are no new incoming connections in the list. |
54 | */ | 150 | */ |
55 | int incoming_connection(void); | 151 | int incoming_connection(Lossless_UDP * ludp); |
56 | 152 | ||
57 | /* | 153 | /* |
58 | * Return -1 if it could not kill the connection. | 154 | * Return -1 if it could not kill the connection. |
59 | * Return 0 if killed successfully | 155 | * Return 0 if killed successfully |
60 | */ | 156 | */ |
61 | int kill_connection(int connection_id); | 157 | int kill_connection(Lossless_UDP * ludp, int connection_id); |
62 | 158 | ||
63 | /* | 159 | /* |
64 | * Kill connection in seconds seconds. | 160 | * Kill connection in seconds seconds. |
65 | * Return -1 if it can not kill the connection. | 161 | * Return -1 if it can not kill the connection. |
66 | * Return 0 if it will kill it | 162 | * Return 0 if it will kill it |
67 | */ | 163 | */ |
68 | int kill_connection_in(int connection_id, uint32_t seconds); | 164 | int kill_connection_in(Lossless_UDP * ludp, int connection_id, uint32_t seconds); |
69 | 165 | ||
70 | /* | 166 | /* |
71 | * Returns the ip_port of the corresponding connection. | 167 | * Returns the ip_port of the corresponding connection. |
72 | * Return 0 if there is no such connection. | 168 | * Return 0 if there is no such connection. |
73 | */ | 169 | */ |
74 | IP_Port connection_ip(int connection_id); | 170 | IP_Port connection_ip(Lossless_UDP * ludp, int connection_id); |
75 | 171 | ||
76 | /* | 172 | /* |
77 | * Returns the id of the next packet in the queue | 173 | * Returns the id of the next packet in the queue |
78 | * Return -1 if no packet in queue | 174 | * Return -1 if no packet in queue |
79 | */ | 175 | */ |
80 | char id_packet(int connection_id); | 176 | char id_packet(Lossless_UDP * ludp, int connection_id); |
81 | 177 | ||
82 | /* | 178 | /* |
83 | * Return 0 if there is no received data in the buffer. | 179 | * Return 0 if there is no received data in the buffer. |
84 | * Return length of received packet if successful | 180 | * Return length of received packet if successful |
85 | */ | 181 | */ |
86 | int read_packet(int connection_id, uint8_t *data); | 182 | int read_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data); |
87 | 183 | ||
88 | /* | 184 | /* |
89 | * Return 0 if data could not be put in packet queue | 185 | * Return 0 if data could not be put in packet queue |
90 | * Return 1 if data was put into the queue | 186 | * Return 1 if data was put into the queue |
91 | */ | 187 | */ |
92 | int write_packet(int connection_id, uint8_t *data, uint32_t length); | 188 | int write_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data, uint32_t length); |
93 | 189 | ||
94 | /* Returns the number of packets in the queue waiting to be successfully sent. */ | 190 | /* Returns the number of packets in the queue waiting to be successfully sent. */ |
95 | uint32_t sendqueue(int connection_id); | 191 | uint32_t sendqueue(Lossless_UDP * ludp, int connection_id); |
96 | 192 | ||
97 | /* | 193 | /* |
98 | * returns the number of packets in the queue waiting to be successfully | 194 | * returns the number of packets in the queue waiting to be successfully |
99 | * read with read_packet(...) | 195 | * read with read_packet(...) |
100 | */ | 196 | */ |
101 | uint32_t recvqueue(int connection_id); | 197 | uint32_t recvqueue(Lossless_UDP * ludp, int connection_id); |
102 | 198 | ||
103 | /* Check if connection is connected: | 199 | /* Check if connection is connected: |
104 | * Return 0 no. | 200 | * Return 0 no. |
@@ -107,15 +203,17 @@ uint32_t recvqueue(int connection_id); | |||
107 | * Return 3 if fully connected. | 203 | * Return 3 if fully connected. |
108 | * Return 4 if timed out and wating to be killed. | 204 | * Return 4 if timed out and wating to be killed. |
109 | */ | 205 | */ |
110 | int is_connected(int connection_id); | 206 | int is_connected(Lossless_UDP * ludp, int connection_id); |
111 | 207 | ||
112 | /* Call this function a couple times per second It's the main loop. */ | 208 | /* Call this function a couple times per second It's the main loop. */ |
113 | void doLossless_UDP(void); | 209 | void do_lossless_udp(Lossless_UDP * ludp); |
114 | 210 | ||
115 | /* | 211 | /* |
116 | * This function sets up LosslessUDP packet handling. | 212 | * This function sets up LosslessUDP packet handling. |
117 | */ | 213 | */ |
118 | void LosslessUDP_init(void); | 214 | Lossless_UDP * new_lossless_udp(Networking_Core * net); |
215 | |||
216 | void kill_lossless_udp(Lossless_UDP * ludp); | ||
119 | 217 | ||
120 | #ifdef __cplusplus | 218 | #ifdef __cplusplus |
121 | } | 219 | } |
diff --git a/core/Messenger.c b/core/Messenger.c index 7fd6a569..cb3d2551 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -246,7 +246,7 @@ int m_delfriend(Messenger *m, int friendnumber) | |||
246 | return -1; | 246 | return -1; |
247 | 247 | ||
248 | DHT_delfriend(m->friendlist[friendnumber].client_id); | 248 | DHT_delfriend(m->friendlist[friendnumber].client_id); |
249 | crypto_kill(m->friendlist[friendnumber].crypt_connection_id); | 249 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); |
250 | free(m->friendlist[friendnumber].statusmessage); | 250 | free(m->friendlist[friendnumber].statusmessage); |
251 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); | 251 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); |
252 | uint32_t i; | 252 | uint32_t i; |
@@ -606,7 +606,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint | |||
606 | if (length != 0) | 606 | if (length != 0) |
607 | memcpy(packet + 1, data, length); | 607 | memcpy(packet + 1, data, length); |
608 | 608 | ||
609 | return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); | 609 | return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); |
610 | } | 610 | } |
611 | 611 | ||
612 | 612 | ||
@@ -626,21 +626,25 @@ int LANdiscovery(timer *t, void *arg) | |||
626 | Messenger *initMessenger(void) | 626 | Messenger *initMessenger(void) |
627 | { | 627 | { |
628 | Messenger *m = calloc(1, sizeof(Messenger)); | 628 | Messenger *m = calloc(1, sizeof(Messenger)); |
629 | |||
630 | if ( ! m ) | 629 | if ( ! m ) |
631 | return 0; | 630 | return 0; |
632 | |||
633 | new_keys(); | ||
634 | m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); | ||
635 | initNetCrypto(); | ||
636 | IP ip; | 631 | IP ip; |
637 | ip.i = 0; | 632 | ip.i = 0; |
638 | 633 | m->net = new_networking(ip, PORT); | |
639 | if (init_networking(ip, PORT) == -1) | 634 | if (m->net == NULL) { |
640 | return 0; | 635 | free(m); |
636 | return NULL; | ||
637 | } | ||
638 | m->net_crypto = new_net_crypto(m->net); | ||
639 | if (m->net_crypto == NULL) { | ||
640 | free(m); | ||
641 | free(m->net); | ||
642 | return NULL; | ||
643 | } | ||
644 | new_keys(m->net_crypto); | ||
645 | m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); | ||
641 | 646 | ||
642 | DHT_init(); | 647 | DHT_init(); |
643 | LosslessUDP_init(); | ||
644 | friendreq_init(); | 648 | friendreq_init(); |
645 | LANdiscovery_init(); | 649 | LANdiscovery_init(); |
646 | set_nospam(random_int()); | 650 | set_nospam(random_int()); |
@@ -657,6 +661,7 @@ void cleanupMessenger(Messenger *m) | |||
657 | /* FIXME TODO ideally cleanupMessenger will mirror initMessenger | 661 | /* FIXME TODO ideally cleanupMessenger will mirror initMessenger |
658 | * this requires the other modules to expose cleanup functions | 662 | * this requires the other modules to expose cleanup functions |
659 | */ | 663 | */ |
664 | kill_net_crypto(m->net_crypto); | ||
660 | free(m->friendlist); | 665 | free(m->friendlist); |
661 | free(m); | 666 | free(m); |
662 | } | 667 | } |
@@ -696,10 +701,10 @@ void doFriends(Messenger *m) | |||
696 | 701 | ||
697 | IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); | 702 | IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); |
698 | 703 | ||
699 | switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { | 704 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { |
700 | case 0: | 705 | case 0: |
701 | if (friendip.ip.i > 1) | 706 | if (friendip.ip.i > 1) |
702 | m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); | 707 | m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); |
703 | 708 | ||
704 | break; | 709 | break; |
705 | 710 | ||
@@ -712,7 +717,7 @@ void doFriends(Messenger *m) | |||
712 | break; | 717 | break; |
713 | 718 | ||
714 | case 4: | 719 | case 4: |
715 | crypto_kill(m->friendlist[i].crypt_connection_id); | 720 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); |
716 | m->friendlist[i].crypt_connection_id = -1; | 721 | m->friendlist[i].crypt_connection_id = -1; |
717 | break; | 722 | break; |
718 | 723 | ||
@@ -741,7 +746,7 @@ void doFriends(Messenger *m) | |||
741 | send_ping(m, i); | 746 | send_ping(m, i); |
742 | } | 747 | } |
743 | 748 | ||
744 | len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); | 749 | len = read_cryptpacket(m->net_crypto, m->friendlist[i].crypt_connection_id, temp); |
745 | uint8_t packet_id = temp[0]; | 750 | uint8_t packet_id = temp[0]; |
746 | uint8_t *data = temp + 1; | 751 | uint8_t *data = temp + 1; |
747 | int data_length = len - 1; | 752 | int data_length = len - 1; |
@@ -833,8 +838,8 @@ void doFriends(Messenger *m) | |||
833 | } | 838 | } |
834 | } | 839 | } |
835 | } else { | 840 | } else { |
836 | if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ | 841 | if (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ |
837 | crypto_kill(m->friendlist[i].crypt_connection_id); | 842 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); |
838 | m->friendlist[i].crypt_connection_id = -1; | 843 | m->friendlist[i].crypt_connection_id = -1; |
839 | set_friend_status(m, i, FRIEND_CONFIRMED); | 844 | set_friend_status(m, i, FRIEND_CONFIRMED); |
840 | } | 845 | } |
@@ -844,7 +849,7 @@ void doFriends(Messenger *m) | |||
844 | 849 | ||
845 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { | 850 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { |
846 | /* if we stopped recieving ping packets kill it */ | 851 | /* if we stopped recieving ping packets kill it */ |
847 | crypto_kill(m->friendlist[i].crypt_connection_id); | 852 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); |
848 | m->friendlist[i].crypt_connection_id = -1; | 853 | m->friendlist[i].crypt_connection_id = -1; |
849 | set_friend_status(m, i, FRIEND_CONFIRMED); | 854 | set_friend_status(m, i, FRIEND_CONFIRMED); |
850 | } | 855 | } |
@@ -857,15 +862,15 @@ void doInbound(Messenger *m) | |||
857 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 862 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
858 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 863 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
859 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 864 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; |
860 | int inconnection = crypto_inbound(public_key, secret_nonce, session_key); | 865 | int inconnection = crypto_inbound(m->net_crypto, public_key, secret_nonce, session_key); |
861 | 866 | ||
862 | if (inconnection != -1) { | 867 | if (inconnection != -1) { |
863 | int friend_id = getfriend_id(m, public_key); | 868 | int friend_id = getfriend_id(m, public_key); |
864 | 869 | ||
865 | if (friend_id != -1) { | 870 | if (friend_id != -1) { |
866 | crypto_kill(m->friendlist[friend_id].crypt_connection_id); | 871 | crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id); |
867 | m->friendlist[friend_id].crypt_connection_id = | 872 | m->friendlist[friend_id].crypt_connection_id = |
868 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); | 873 | accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key); |
869 | 874 | ||
870 | set_friend_status(m, friend_id, FRIEND_CONFIRMED); | 875 | set_friend_status(m, friend_id, FRIEND_CONFIRMED); |
871 | } | 876 | } |
@@ -873,14 +878,13 @@ void doInbound(Messenger *m) | |||
873 | } | 878 | } |
874 | 879 | ||
875 | 880 | ||
876 | /* the main loop that needs to be run at least 200 times per second. */ | 881 | /* the main loop that needs to be run at least 20 times per second. */ |
877 | void doMessenger(Messenger *m) | 882 | void doMessenger(Messenger *m) |
878 | { | 883 | { |
879 | networking_poll(); | 884 | networking_poll(m->net); |
880 | 885 | ||
881 | doDHT(); | 886 | doDHT(); |
882 | doLossless_UDP(); | 887 | do_net_crypto(m->net_crypto); |
883 | doNetCrypto(); | ||
884 | doInbound(m); | 888 | doInbound(m); |
885 | doFriends(m); | 889 | doFriends(m); |
886 | 890 | ||
@@ -904,7 +908,7 @@ uint32_t Messenger_size(Messenger *m) | |||
904 | /* save the messenger in data of size Messenger_size() */ | 908 | /* save the messenger in data of size Messenger_size() */ |
905 | void Messenger_save(Messenger *m, uint8_t *data) | 909 | void Messenger_save(Messenger *m, uint8_t *data) |
906 | { | 910 | { |
907 | save_keys(data); | 911 | save_keys(m->net_crypto, data); |
908 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 912 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
909 | uint32_t nospam = get_nospam(); | 913 | uint32_t nospam = get_nospam(); |
910 | memcpy(data, &nospam, sizeof(nospam)); | 914 | memcpy(data, &nospam, sizeof(nospam)); |
@@ -935,7 +939,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
935 | return -1; | 939 | return -1; |
936 | 940 | ||
937 | length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; | 941 | length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; |
938 | load_keys(data); | 942 | load_keys(m->net_crypto, data); |
939 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 943 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
940 | uint32_t nospam; | 944 | uint32_t nospam; |
941 | memcpy(&nospam, data, sizeof(nospam)); | 945 | memcpy(&nospam, data, sizeof(nospam)); |
diff --git a/core/Messenger.h b/core/Messenger.h index 9016be93..a2e8f16e 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -112,8 +112,9 @@ typedef struct { | |||
112 | } Friend; | 112 | } Friend; |
113 | 113 | ||
114 | typedef struct Messenger { | 114 | typedef struct Messenger { |
115 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 115 | |
116 | 116 | Networking_Core *net; | |
117 | Net_Crypto * net_crypto; | ||
117 | uint8_t name[MAX_NAME_LENGTH]; | 118 | uint8_t name[MAX_NAME_LENGTH]; |
118 | uint16_t name_length; | 119 | uint16_t name_length; |
119 | 120 | ||
diff --git a/core/friend_requests.c b/core/friend_requests.c index 3708f154..7be7a4bd 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "friend_requests.h" | 24 | #include "friend_requests.h" |
25 | 25 | ||
26 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 26 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; |
27 | 27 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | |
28 | 28 | ||
29 | /* Try to send a friendrequest to peer with public_key | 29 | /* Try to send a friendrequest to peer with public_key |
30 | data is the data in the request and length is the length. | 30 | data is the data in the request and length is the length. |
@@ -40,7 +40,7 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, | |||
40 | memcpy(temp, &nospam_num, sizeof(nospam_num)); | 40 | memcpy(temp, &nospam_num, sizeof(nospam_num)); |
41 | memcpy(temp + sizeof(nospam_num), data, length); | 41 | memcpy(temp + sizeof(nospam_num), data, length); |
42 | uint8_t packet[MAX_DATA_SIZE]; | 42 | uint8_t packet[MAX_DATA_SIZE]; |
43 | int len = create_request(packet, public_key, temp, length + sizeof(nospam_num), | 43 | int len = create_request(self_public_key, self_secret_key, packet, public_key, temp, length + sizeof(nospam_num), |
44 | 32); /* 32 is friend request packet id */ | 44 | 32); /* 32 is friend request packet id */ |
45 | 45 | ||
46 | if (len == -1) | 46 | if (len == -1) |
@@ -52,7 +52,7 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, | |||
52 | return -1; | 52 | return -1; |
53 | 53 | ||
54 | if (ip_port.ip.i != 0) { | 54 | if (ip_port.ip.i != 0) { |
55 | if (sendpacket(ip_port, packet, len) != -1) | 55 | if (sendpacket(temp_net->sock, ip_port, packet, len) != -1) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | return -1; | 58 | return -1; |
@@ -146,5 +146,5 @@ static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_ | |||
146 | 146 | ||
147 | void friendreq_init(void) | 147 | void friendreq_init(void) |
148 | { | 148 | { |
149 | cryptopacket_registerhandler(32, &friendreq_handlepacket); | 149 | cryptopacket_registerhandler(temp_net_crypto, 32, &friendreq_handlepacket); |
150 | } | 150 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index 8fcb62e1..dcf36a12 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -26,42 +26,12 @@ | |||
26 | 26 | ||
27 | #include "net_crypto.h" | 27 | #include "net_crypto.h" |
28 | 28 | ||
29 | /* Our public and secret keys. */ | ||
30 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
31 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
32 | |||
33 | typedef struct { | ||
34 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ | ||
35 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ | ||
36 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ | ||
37 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ | ||
38 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ | ||
39 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | ||
40 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */ | ||
41 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
42 | (we have received a handshake but no empty data packet), 3 if the connection is established. | ||
43 | 4 if the connection is timed out. */ | ||
44 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ | ||
45 | |||
46 | } Crypto_Connection; | ||
47 | |||
48 | static Crypto_Connection *crypto_connections; | ||
49 | |||
50 | static uint32_t crypto_connections_length; /* Length of connections array */ | ||
51 | |||
52 | #define MAX_CRYPTO_CONNECTIONS crypto_connections_length | ||
53 | |||
54 | #define CONN_NO_CONNECTION 0 | 29 | #define CONN_NO_CONNECTION 0 |
55 | #define CONN_HANDSHAKE_SENT 1 | 30 | #define CONN_HANDSHAKE_SENT 1 |
56 | #define CONN_NOT_CONFIRMED 2 | 31 | #define CONN_NOT_CONFIRMED 2 |
57 | #define CONN_ESTABLISHED 3 | 32 | #define CONN_ESTABLISHED 3 |
58 | #define CONN_TIMED_OUT 4 | 33 | #define CONN_TIMED_OUT 4 |
59 | 34 | ||
60 | #define MAX_INCOMING 64 | ||
61 | |||
62 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | ||
63 | static int incoming_connections[MAX_INCOMING]; | ||
64 | |||
65 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ | 35 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ |
66 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) | 36 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) |
67 | { | 37 | { |
@@ -175,16 +145,16 @@ void random_nonce(uint8_t *nonce) | |||
175 | /* return 0 if there is no received data in the buffer | 145 | /* return 0 if there is no received data in the buffer |
176 | return -1 if the packet was discarded. | 146 | return -1 if the packet was discarded. |
177 | return length of received data if successful */ | 147 | return length of received data if successful */ |
178 | int read_cryptpacket(int crypt_connection_id, uint8_t *data) | 148 | int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data) |
179 | { | 149 | { |
180 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 150 | if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length) |
181 | return 0; | 151 | return 0; |
182 | 152 | ||
183 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) | 153 | if (c->crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
184 | return 0; | 154 | return 0; |
185 | 155 | ||
186 | uint8_t temp_data[MAX_DATA_SIZE]; | 156 | uint8_t temp_data[MAX_DATA_SIZE]; |
187 | int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); | 157 | int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data); |
188 | 158 | ||
189 | if (length == 0) | 159 | if (length == 0) |
190 | return 0; | 160 | return 0; |
@@ -192,12 +162,12 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
192 | if (temp_data[0] != 3) | 162 | if (temp_data[0] != 3) |
193 | return -1; | 163 | return -1; |
194 | 164 | ||
195 | int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, | 165 | int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, |
196 | crypto_connections[crypt_connection_id].recv_nonce, | 166 | c->crypto_connections[crypt_connection_id].recv_nonce, |
197 | temp_data + 1, length - 1, data); | 167 | temp_data + 1, length - 1, data); |
198 | 168 | ||
199 | if (len != -1) { | 169 | if (len != -1) { |
200 | increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); | 170 | increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce); |
201 | return len; | 171 | return len; |
202 | } | 172 | } |
203 | 173 | ||
@@ -206,20 +176,20 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
206 | 176 | ||
207 | /* return 0 if data could not be put in packet queue | 177 | /* return 0 if data could not be put in packet queue |
208 | return 1 if data was put into the queue */ | 178 | return 1 if data was put into the queue */ |
209 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | 179 | int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) |
210 | { | 180 | { |
211 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 181 | if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length) |
212 | return 0; | 182 | return 0; |
213 | 183 | ||
214 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) | 184 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) |
215 | return 0; | 185 | return 0; |
216 | 186 | ||
217 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) | 187 | if (c->crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
218 | return 0; | 188 | return 0; |
219 | 189 | ||
220 | uint8_t temp_data[MAX_DATA_SIZE]; | 190 | uint8_t temp_data[MAX_DATA_SIZE]; |
221 | int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, | 191 | int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, |
222 | crypto_connections[crypt_connection_id].sent_nonce, | 192 | c->crypto_connections[crypt_connection_id].sent_nonce, |
223 | data, length, temp_data + 1); | 193 | data, length, temp_data + 1); |
224 | 194 | ||
225 | if (len == -1) | 195 | if (len == -1) |
@@ -227,20 +197,22 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | |||
227 | 197 | ||
228 | temp_data[0] = 3; | 198 | temp_data[0] = 3; |
229 | 199 | ||
230 | if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) | 200 | if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) |
231 | return 0; | 201 | return 0; |
232 | 202 | ||
233 | increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); | 203 | increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce); |
234 | return 1; | 204 | return 1; |
235 | } | 205 | } |
236 | 206 | ||
237 | /* create a request to peer with public_key. | 207 | /* create a request to peer. |
208 | send_public_key and send_secret_key are the pub/secret keys of the sender | ||
209 | recv_public_key is public key of reciever | ||
238 | packet must be an array of MAX_DATA_SIZE big. | 210 | packet must be an array of MAX_DATA_SIZE big. |
239 | Data represents the data we send with the request with length being the length of the data. | 211 | Data represents the data we send with the request with length being the length of the data. |
240 | request_id is the id of the request (32 = friend request, 254 = ping request) | 212 | request_id is the id of the request (32 = friend request, 254 = ping request) |
241 | returns -1 on failure | 213 | returns -1 on failure |
242 | returns the length of the created packet on success */ | 214 | returns the length of the created packet on success */ |
243 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) | 215 | int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, uint8_t *data, uint32_t length, uint8_t request_id) |
244 | { | 216 | { |
245 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) | 217 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) |
246 | return -1; | 218 | return -1; |
@@ -250,15 +222,15 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
250 | memcpy(temp + 1, data, length); | 222 | memcpy(temp + 1, data, length); |
251 | temp[0] = request_id; | 223 | temp[0] = request_id; |
252 | random_nonce(nonce); | 224 | random_nonce(nonce); |
253 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1, | 225 | int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, |
254 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); | 226 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); |
255 | 227 | ||
256 | if (len == -1) | 228 | if (len == -1) |
257 | return -1; | 229 | return -1; |
258 | 230 | ||
259 | packet[0] = 32; | 231 | packet[0] = 32; |
260 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 232 | memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); |
261 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); | 233 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); |
262 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); | 234 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); |
263 | 235 | ||
264 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; | 236 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; |
@@ -268,17 +240,17 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
268 | in data if a friend or ping request was sent to us and returns the length of the data. | 240 | in data if a friend or ping request was sent to us and returns the length of the data. |
269 | packet is the request packet and length is its length | 241 | packet is the request packet and length is its length |
270 | return -1 if not valid request. */ | 242 | return -1 if not valid request. */ |
271 | static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length) | 243 | static int handle_request(Net_Crypto *c, uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length) |
272 | { | 244 | { |
273 | 245 | ||
274 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 246 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
275 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && | 247 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && |
276 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 248 | memcmp(packet + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
277 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | 249 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); |
278 | uint8_t nonce[crypto_box_NONCEBYTES]; | 250 | uint8_t nonce[crypto_box_NONCEBYTES]; |
279 | uint8_t temp[MAX_DATA_SIZE]; | 251 | uint8_t temp[MAX_DATA_SIZE]; |
280 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); | 252 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); |
281 | int len1 = decrypt_data(public_key, self_secret_key, nonce, | 253 | int len1 = decrypt_data(public_key, c->self_secret_key, nonce, |
282 | packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, | 254 | packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, |
283 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); | 255 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); |
284 | 256 | ||
@@ -293,15 +265,14 @@ static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_i | |||
293 | return -1; | 265 | return -1; |
294 | } | 266 | } |
295 | 267 | ||
296 | static cryptopacket_handler_callback cryptopackethandlers[256] = {0}; | 268 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb) |
297 | |||
298 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb) | ||
299 | { | 269 | { |
300 | cryptopackethandlers[byte] = cb; | 270 | c->cryptopackethandlers[byte] = cb; |
301 | } | 271 | } |
302 | 272 | ||
303 | static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length) | 273 | static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
304 | { | 274 | { |
275 | Net_Crypto *c = object; | ||
305 | if (packet[0] == 32) { | 276 | if (packet[0] == 32) { |
306 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | 277 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || |
307 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 278 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
@@ -311,17 +282,17 @@ static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length) | |||
311 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 282 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
312 | uint8_t data[MAX_DATA_SIZE]; | 283 | uint8_t data[MAX_DATA_SIZE]; |
313 | uint8_t number; | 284 | uint8_t number; |
314 | int len = handle_request(public_key, data, &number, packet, length); | 285 | int len = handle_request(c, public_key, data, &number, packet, length); |
315 | 286 | ||
316 | if (len == -1 || len == 0) | 287 | if (len == -1 || len == 0) |
317 | return 1; | 288 | return 1; |
318 | 289 | ||
319 | if (!cryptopackethandlers[number]) return 1; | 290 | if (!c->cryptopackethandlers[number]) return 1; |
320 | 291 | ||
321 | cryptopackethandlers[number](source, public_key, data, len); | 292 | c->cryptopackethandlers[number](source, public_key, data, len); |
322 | 293 | ||
323 | } else { /* if request is not for us, try routing it. */ | 294 | } else { /* if request is not for us, try routing it. */ |
324 | if (route_packet(packet + 1, packet, length) == length) | 295 | if (route_packet(packet + 1, packet, length) == length) //NOTE |
325 | return 0; | 296 | return 0; |
326 | } | 297 | } |
327 | } | 298 | } |
@@ -332,7 +303,7 @@ static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length) | |||
332 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key | 303 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key |
333 | to peer with connection_id and public_key | 304 | to peer with connection_id and public_key |
334 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ | 305 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ |
335 | static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 306 | static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) |
336 | { | 307 | { |
337 | uint8_t temp_data[MAX_DATA_SIZE]; | 308 | uint8_t temp_data[MAX_DATA_SIZE]; |
338 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 309 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; |
@@ -342,22 +313,22 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t | |||
342 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); | 313 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); |
343 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); | 314 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); |
344 | 315 | ||
345 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 316 | int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
346 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | 317 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); |
347 | 318 | ||
348 | if (len == -1) | 319 | if (len == -1) |
349 | return 0; | 320 | return 0; |
350 | 321 | ||
351 | temp_data[0] = 2; | 322 | temp_data[0] = 2; |
352 | memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 323 | memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); |
353 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | 324 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); |
354 | return write_packet(connection_id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | 325 | return write_packet(c->lossless_udp, connection_id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); |
355 | } | 326 | } |
356 | 327 | ||
357 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length | 328 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length |
358 | return 1 if successful | 329 | return 1 if successful |
359 | return 0 if failure */ | 330 | return 0 if failure */ |
360 | static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | 331 | static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, |
361 | uint8_t *session_key, uint8_t *data, uint16_t length) | 332 | uint8_t *session_key, uint8_t *data, uint16_t length) |
362 | { | 333 | { |
363 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); | 334 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); |
@@ -374,7 +345,7 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | |||
374 | 345 | ||
375 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); | 346 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); |
376 | 347 | ||
377 | int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, | 348 | int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, |
378 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | 349 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, |
379 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); | 350 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); |
380 | 351 | ||
@@ -389,13 +360,13 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | |||
389 | /* get crypto connection id from public key of peer | 360 | /* get crypto connection id from public key of peer |
390 | return -1 if there are no connections like we are looking for | 361 | return -1 if there are no connections like we are looking for |
391 | return id if it found it */ | 362 | return id if it found it */ |
392 | static int getcryptconnection_id(uint8_t *public_key) | 363 | static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) |
393 | { | 364 | { |
394 | uint32_t i; | 365 | uint32_t i; |
395 | 366 | ||
396 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 367 | for (i = 0; i < c->crypto_connections_length; ++i) { |
397 | if (crypto_connections[i].status != CONN_NO_CONNECTION) | 368 | if (c->crypto_connections[i].status != CONN_NO_CONNECTION) |
398 | if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) | 369 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) |
399 | return i; | 370 | return i; |
400 | } | 371 | } |
401 | 372 | ||
@@ -404,63 +375,63 @@ static int getcryptconnection_id(uint8_t *public_key) | |||
404 | 375 | ||
405 | /* set the size of the friend list to numfriends | 376 | /* set the size of the friend list to numfriends |
406 | return -1 if realloc fails */ | 377 | return -1 if realloc fails */ |
407 | int realloc_cryptoconnection(uint32_t num) | 378 | int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) |
408 | { | 379 | { |
409 | if (num == 0) { | 380 | if (num == 0) { |
410 | free(crypto_connections); | 381 | free(c->crypto_connections); |
411 | crypto_connections = NULL; | 382 | c->crypto_connections = NULL; |
412 | return 0; | 383 | return 0; |
413 | } | 384 | } |
414 | 385 | ||
415 | Crypto_Connection *newcrypto_connections = realloc(crypto_connections, num * sizeof(Crypto_Connection)); | 386 | Crypto_Connection *newcrypto_connections = realloc(c->crypto_connections, num * sizeof(Crypto_Connection)); |
416 | 387 | ||
417 | if (newcrypto_connections == NULL) | 388 | if (newcrypto_connections == NULL) |
418 | return -1; | 389 | return -1; |
419 | 390 | ||
420 | crypto_connections = newcrypto_connections; | 391 | c->crypto_connections = newcrypto_connections; |
421 | return 0; | 392 | return 0; |
422 | } | 393 | } |
423 | 394 | ||
424 | /* Start a secure connection with other peer who has public_key and ip_port | 395 | /* Start a secure connection with other peer who has public_key and ip_port |
425 | returns -1 if failure | 396 | returns -1 if failure |
426 | returns crypt_connection_id of the initialized connection if everything went well. */ | 397 | returns crypt_connection_id of the initialized connection if everything went well. */ |
427 | int crypto_connect(uint8_t *public_key, IP_Port ip_port) | 398 | int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) |
428 | { | 399 | { |
429 | uint32_t i; | 400 | uint32_t i; |
430 | int id = getcryptconnection_id(public_key); | 401 | int id = getcryptconnection_id(c, public_key); |
431 | 402 | ||
432 | if (id != -1) { | 403 | if (id != -1) { |
433 | IP_Port c_ip = connection_ip(crypto_connections[id].number); | 404 | IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number); |
434 | 405 | ||
435 | if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) | 406 | if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) |
436 | return -1; | 407 | return -1; |
437 | } | 408 | } |
438 | 409 | ||
439 | if (realloc_cryptoconnection(crypto_connections_length + 1) == -1) | 410 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) |
440 | return -1; | 411 | return -1; |
441 | 412 | ||
442 | memset(&crypto_connections[crypto_connections_length], 0, sizeof(Crypto_Connection)); | 413 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); |
443 | crypto_connections[crypto_connections_length].number = ~0; | 414 | c->crypto_connections[c->crypto_connections_length].number = ~0; |
444 | 415 | ||
445 | for (i = 0; i <= MAX_CRYPTO_CONNECTIONS; ++i) { | 416 | for (i = 0; i <= c->crypto_connections_length; ++i) { |
446 | if (crypto_connections[i].status == CONN_NO_CONNECTION) { | 417 | if (c->crypto_connections[i].status == CONN_NO_CONNECTION) { |
447 | int id = new_connection(ip_port); | 418 | int id = new_connection(c->lossless_udp, ip_port); |
448 | 419 | ||
449 | if (id == -1) | 420 | if (id == -1) |
450 | return -1; | 421 | return -1; |
451 | 422 | ||
452 | crypto_connections[i].number = id; | 423 | c->crypto_connections[i].number = id; |
453 | crypto_connections[i].status = CONN_HANDSHAKE_SENT; | 424 | c->crypto_connections[i].status = CONN_HANDSHAKE_SENT; |
454 | random_nonce(crypto_connections[i].recv_nonce); | 425 | random_nonce(c->crypto_connections[i].recv_nonce); |
455 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 426 | memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
456 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 427 | crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); |
457 | 428 | ||
458 | if (crypto_connections_length == i) | 429 | if (c->crypto_connections_length == i) |
459 | ++crypto_connections_length; | 430 | ++c->crypto_connections_length; |
460 | 431 | ||
461 | if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, | 432 | if (send_cryptohandshake(c, id, public_key, c->crypto_connections[i].recv_nonce, |
462 | crypto_connections[i].sessionpublic_key) == 1) { | 433 | c->crypto_connections[i].sessionpublic_key) == 1) { |
463 | increment_nonce(crypto_connections[i].recv_nonce); | 434 | increment_nonce(c->crypto_connections[i].recv_nonce); |
464 | return i; | 435 | return i; |
465 | } | 436 | } |
466 | 437 | ||
@@ -478,25 +449,25 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port) | |||
478 | and the session public key for the connection in session_key | 449 | and the session public key for the connection in session_key |
479 | to accept it see: accept_crypto_inbound(...) | 450 | to accept it see: accept_crypto_inbound(...) |
480 | to refuse it just call kill_connection(...) on the connection id */ | 451 | to refuse it just call kill_connection(...) on the connection id */ |
481 | int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 452 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) |
482 | { | 453 | { |
483 | uint32_t i; | 454 | uint32_t i; |
484 | 455 | ||
485 | for (i = 0; i < MAX_INCOMING; ++i) { | 456 | for (i = 0; i < MAX_INCOMING; ++i) { |
486 | if (incoming_connections[i] != -1) { | 457 | if (c->incoming_connections[i] != -1) { |
487 | if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) { | 458 | if (is_connected(c->lossless_udp, c->incoming_connections[i]) == 4 || is_connected(c->lossless_udp, c->incoming_connections[i]) == 0) { |
488 | kill_connection(incoming_connections[i]); | 459 | kill_connection(c->lossless_udp, c->incoming_connections[i]); |
489 | incoming_connections[i] = -1; | 460 | c->incoming_connections[i] = -1; |
490 | continue; | 461 | continue; |
491 | } | 462 | } |
492 | 463 | ||
493 | if (id_packet(incoming_connections[i]) == 2) { | 464 | if (id_packet(c->lossless_udp, c->incoming_connections[i]) == 2) { |
494 | uint8_t temp_data[MAX_DATA_SIZE]; | 465 | uint8_t temp_data[MAX_DATA_SIZE]; |
495 | uint16_t len = read_packet(incoming_connections[i], temp_data); | 466 | uint16_t len = read_packet(c->lossless_udp, c->incoming_connections[i], temp_data); |
496 | 467 | ||
497 | if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { | 468 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { |
498 | int connection_id = incoming_connections[i]; | 469 | int connection_id = c->incoming_connections[i]; |
499 | incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ | 470 | c->incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ |
500 | return connection_id; | 471 | return connection_id; |
501 | } | 472 | } |
502 | } | 473 | } |
@@ -509,25 +480,25 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_ | |||
509 | /* kill a crypto connection | 480 | /* kill a crypto connection |
510 | return 0 if killed successfully | 481 | return 0 if killed successfully |
511 | return 1 if there was a problem. */ | 482 | return 1 if there was a problem. */ |
512 | int crypto_kill(int crypt_connection_id) | 483 | int crypto_kill(Net_Crypto *c, int crypt_connection_id) |
513 | { | 484 | { |
514 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 485 | if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length) |
515 | return 1; | 486 | return 1; |
516 | 487 | ||
517 | if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { | 488 | if (c->crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { |
518 | crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; | 489 | c->crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; |
519 | kill_connection(crypto_connections[crypt_connection_id].number); | 490 | kill_connection(c->lossless_udp, c->crypto_connections[crypt_connection_id].number); |
520 | memset(&crypto_connections[crypt_connection_id], 0 , sizeof(Crypto_Connection)); | 491 | memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); |
521 | crypto_connections[crypt_connection_id].number = ~0; | 492 | c->crypto_connections[crypt_connection_id].number = ~0; |
522 | uint32_t i; | 493 | uint32_t i; |
523 | 494 | ||
524 | for (i = crypto_connections_length; i != 0; --i) { | 495 | for (i = c->crypto_connections_length; i != 0; --i) { |
525 | if (crypto_connections[i - 1].status != CONN_NO_CONNECTION) | 496 | if (c->crypto_connections[i - 1].status != CONN_NO_CONNECTION) |
526 | break; | 497 | break; |
527 | } | 498 | } |
528 | 499 | ||
529 | crypto_connections_length = i; | 500 | c->crypto_connections_length = i; |
530 | realloc_cryptoconnection(crypto_connections_length); | 501 | realloc_cryptoconnection(c, c->crypto_connections_length); |
531 | return 0; | 502 | return 0; |
532 | } | 503 | } |
533 | 504 | ||
@@ -537,7 +508,7 @@ int crypto_kill(int crypt_connection_id) | |||
537 | /* accept an incoming connection using the parameters provided by crypto_inbound | 508 | /* accept an incoming connection using the parameters provided by crypto_inbound |
538 | return -1 if not successful | 509 | return -1 if not successful |
539 | returns the crypt_connection_id if successful */ | 510 | returns the crypt_connection_id if successful */ |
540 | int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 511 | int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) |
541 | { | 512 | { |
542 | uint32_t i; | 513 | uint32_t i; |
543 | 514 | ||
@@ -549,37 +520,37 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
549 | { | 520 | { |
550 | return -1; | 521 | return -1; |
551 | }*/ | 522 | }*/ |
552 | if (realloc_cryptoconnection(crypto_connections_length + 1) == -1) | 523 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) |
553 | return -1; | 524 | return -1; |
554 | 525 | ||
555 | memset(&crypto_connections[crypto_connections_length], 0, sizeof(Crypto_Connection)); | 526 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); |
556 | crypto_connections[crypto_connections_length].number = ~0; | 527 | c->crypto_connections[c->crypto_connections_length].number = ~0; |
557 | 528 | ||
558 | for (i = 0; i <= MAX_CRYPTO_CONNECTIONS; ++i) { | 529 | for (i = 0; i <= c->crypto_connections_length; ++i) { |
559 | if (crypto_connections[i].status == CONN_NO_CONNECTION) { | 530 | if (c->crypto_connections[i].status == CONN_NO_CONNECTION) { |
560 | crypto_connections[i].number = connection_id; | 531 | c->crypto_connections[i].number = connection_id; |
561 | crypto_connections[i].status = CONN_NOT_CONFIRMED; | 532 | c->crypto_connections[i].status = CONN_NOT_CONFIRMED; |
562 | random_nonce(crypto_connections[i].recv_nonce); | 533 | random_nonce(c->crypto_connections[i].recv_nonce); |
563 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 534 | memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); |
564 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 535 | memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
565 | increment_nonce(crypto_connections[i].sent_nonce); | 536 | increment_nonce(c->crypto_connections[i].sent_nonce); |
566 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 537 | memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
567 | 538 | ||
568 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 539 | crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); |
569 | 540 | ||
570 | if (crypto_connections_length == i) | 541 | if (c->crypto_connections_length == i) |
571 | ++crypto_connections_length; | 542 | ++c->crypto_connections_length; |
572 | 543 | ||
573 | if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, | 544 | if (send_cryptohandshake(c, connection_id, public_key, c->crypto_connections[i].recv_nonce, |
574 | crypto_connections[i].sessionpublic_key) == 1) { | 545 | c->crypto_connections[i].sessionpublic_key) == 1) { |
575 | increment_nonce(crypto_connections[i].recv_nonce); | 546 | increment_nonce(c->crypto_connections[i].recv_nonce); |
576 | uint32_t zero = 0; | 547 | uint32_t zero = 0; |
577 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | 548 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, |
578 | crypto_connections[i].sessionsecret_key, | 549 | c->crypto_connections[i].sessionsecret_key, |
579 | crypto_connections[i].shared_key); | 550 | c->crypto_connections[i].shared_key); |
580 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ | 551 | c->crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
581 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 552 | write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); |
582 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | 553 | c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ |
583 | return i; | 554 | return i; |
584 | } | 555 | } |
585 | 556 | ||
@@ -593,48 +564,54 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
593 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet | 564 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet |
594 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 565 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
595 | 4 if the connection is timed out and waiting to be killed */ | 566 | 4 if the connection is timed out and waiting to be killed */ |
596 | int is_cryptoconnected(int crypt_connection_id) | 567 | int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id) |
597 | { | 568 | { |
598 | if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) | 569 | if (crypt_connection_id >= 0 && crypt_connection_id < c->crypto_connections_length) |
599 | return crypto_connections[crypt_connection_id].status; | 570 | return c->crypto_connections[crypt_connection_id].status; |
600 | 571 | ||
601 | return CONN_NO_CONNECTION; | 572 | return CONN_NO_CONNECTION; |
602 | } | 573 | } |
603 | 574 | ||
604 | /* Generate our public and private keys | 575 | /* Generate our public and private keys |
605 | Only call this function the first time the program starts. */ | 576 | Only call this function the first time the program starts. */ |
606 | void new_keys(void) | 577 | |
578 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this | ||
579 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
580 | |||
581 | void new_keys(Net_Crypto *c) | ||
607 | { | 582 | { |
608 | crypto_box_keypair(self_public_key, self_secret_key); | 583 | crypto_box_keypair(c->self_public_key, c->self_secret_key); |
584 | memcpy(self_public_key, c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
585 | memcpy(self_secret_key, c->self_secret_key, crypto_box_PUBLICKEYBYTES); | ||
609 | } | 586 | } |
610 | 587 | ||
611 | /* save the public and private keys to the keys array | 588 | /* save the public and private keys to the keys array |
612 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 589 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
613 | void save_keys(uint8_t *keys) | 590 | void save_keys(Net_Crypto *c, uint8_t *keys) |
614 | { | 591 | { |
615 | memcpy(keys, self_public_key, crypto_box_PUBLICKEYBYTES); | 592 | memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES); |
616 | memcpy(keys + crypto_box_PUBLICKEYBYTES, self_secret_key, crypto_box_SECRETKEYBYTES); | 593 | memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); |
617 | } | 594 | } |
618 | 595 | ||
619 | /* load the public and private keys from the keys array | 596 | /* load the public and private keys from the keys array |
620 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 597 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
621 | void load_keys(uint8_t *keys) | 598 | void load_keys(Net_Crypto *c, uint8_t *keys) |
622 | { | 599 | { |
623 | memcpy(self_public_key, keys, crypto_box_PUBLICKEYBYTES); | 600 | memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES); |
624 | memcpy(self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); | 601 | memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); |
625 | } | 602 | } |
626 | 603 | ||
627 | /* TODO: optimize this | 604 | /* TODO: optimize this |
628 | adds an incoming connection to the incoming_connection list. | 605 | adds an incoming connection to the incoming_connection list. |
629 | returns 0 if successful | 606 | returns 0 if successful |
630 | returns 1 if failure */ | 607 | returns 1 if failure */ |
631 | static int new_incoming(int id) | 608 | static int new_incoming(Net_Crypto *c, int id) |
632 | { | 609 | { |
633 | uint32_t i; | 610 | uint32_t i; |
634 | 611 | ||
635 | for (i = 0; i < MAX_INCOMING; ++i) { | 612 | for (i = 0; i < MAX_INCOMING; ++i) { |
636 | if (incoming_connections[i] == -1) { | 613 | if (c->incoming_connections[i] == -1) { |
637 | incoming_connections[i] = id; | 614 | c->incoming_connections[i] = id; |
638 | return 0; | 615 | return 0; |
639 | } | 616 | } |
640 | } | 617 | } |
@@ -644,81 +621,81 @@ static int new_incoming(int id) | |||
644 | 621 | ||
645 | /* TODO: optimize this | 622 | /* TODO: optimize this |
646 | handle all new incoming connections. */ | 623 | handle all new incoming connections. */ |
647 | static void handle_incomings(void) | 624 | static void handle_incomings(Net_Crypto *c) |
648 | { | 625 | { |
649 | int income; | 626 | int income; |
650 | 627 | ||
651 | while (1) { | 628 | while (1) { |
652 | income = incoming_connection(); | 629 | income = incoming_connection(c->lossless_udp); |
653 | 630 | ||
654 | if (income == -1 || new_incoming(income) ) | 631 | if (income == -1 || new_incoming(c, income) ) |
655 | break; | 632 | break; |
656 | } | 633 | } |
657 | } | 634 | } |
658 | 635 | ||
659 | /* handle received packets for not yet established crypto connections. */ | 636 | /* handle received packets for not yet established crypto connections. */ |
660 | static void receive_crypto(void) | 637 | static void receive_crypto(Net_Crypto *c) |
661 | { | 638 | { |
662 | uint32_t i; | 639 | uint32_t i; |
663 | 640 | ||
664 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 641 | for (i = 0; i < c->crypto_connections_length; ++i) { |
665 | if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { | 642 | if (c->crypto_connections[i].status == CONN_HANDSHAKE_SENT) { |
666 | uint8_t temp_data[MAX_DATA_SIZE]; | 643 | uint8_t temp_data[MAX_DATA_SIZE]; |
667 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 644 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
668 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 645 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
669 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 646 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; |
670 | uint16_t len; | 647 | uint16_t len; |
671 | 648 | ||
672 | if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ | 649 | if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* handle handshake packet. */ |
673 | len = read_packet(crypto_connections[i].number, temp_data); | 650 | len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); |
674 | 651 | ||
675 | if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { | 652 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { |
676 | if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 653 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
677 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 654 | memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); |
678 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 655 | memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
679 | increment_nonce(crypto_connections[i].sent_nonce); | 656 | increment_nonce(c->crypto_connections[i].sent_nonce); |
680 | uint32_t zero = 0; | 657 | uint32_t zero = 0; |
681 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | 658 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, |
682 | crypto_connections[i].sessionsecret_key, | 659 | c->crypto_connections[i].sessionsecret_key, |
683 | crypto_connections[i].shared_key); | 660 | c->crypto_connections[i].shared_key); |
684 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ | 661 | c->crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
685 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 662 | write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); |
686 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | 663 | c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ |
687 | } | 664 | } |
688 | } | 665 | } |
689 | } else if (id_packet(crypto_connections[i].number) != -1) { // This should not happen kill the connection if it does | 666 | } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) { // This should not happen kill the connection if it does |
690 | crypto_kill(crypto_connections[i].number); | 667 | crypto_kill(c, i); |
691 | return; | 668 | return; |
692 | } | 669 | } |
693 | } | 670 | } |
694 | 671 | ||
695 | if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { | 672 | if (c->crypto_connections[i].status == CONN_NOT_CONFIRMED) { |
696 | if (id_packet(crypto_connections[i].number) == 3) { | 673 | if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { |
697 | uint8_t temp_data[MAX_DATA_SIZE]; | 674 | uint8_t temp_data[MAX_DATA_SIZE]; |
698 | uint8_t data[MAX_DATA_SIZE]; | 675 | uint8_t data[MAX_DATA_SIZE]; |
699 | int length = read_packet(crypto_connections[i].number, temp_data); | 676 | int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); |
700 | int len = decrypt_data(crypto_connections[i].peersessionpublic_key, | 677 | int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, |
701 | crypto_connections[i].sessionsecret_key, | 678 | c->crypto_connections[i].sessionsecret_key, |
702 | crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); | 679 | c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); |
703 | uint32_t zero = 0; | 680 | uint32_t zero = 0; |
704 | 681 | ||
705 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { | 682 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { |
706 | increment_nonce(crypto_connections[i].recv_nonce); | 683 | increment_nonce(c->crypto_connections[i].recv_nonce); |
707 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | 684 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, |
708 | crypto_connections[i].sessionsecret_key, | 685 | c->crypto_connections[i].sessionsecret_key, |
709 | crypto_connections[i].shared_key); | 686 | c->crypto_connections[i].shared_key); |
710 | crypto_connections[i].status = CONN_ESTABLISHED; | 687 | c->crypto_connections[i].status = CONN_ESTABLISHED; |
711 | 688 | ||
712 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ | 689 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ |
713 | kill_connection_in(crypto_connections[i].number, 3000000); | 690 | kill_connection_in(c->lossless_udp, c->crypto_connections[i].number, 3000000); |
714 | } else { | 691 | } else { |
715 | crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does | 692 | crypto_kill(c, i); // This should not happen kill the connection if it does |
716 | return; | 693 | return; |
717 | } | 694 | } |
718 | } else if (id_packet(crypto_connections[i].number) != -1) | 695 | } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) |
719 | /* This should not happen | 696 | /* This should not happen |
720 | kill the connection if it does */ | 697 | kill the connection if it does */ |
721 | crypto_kill(crypto_connections[i].number); | 698 | crypto_kill(c, i); |
722 | 699 | ||
723 | return; | 700 | return; |
724 | } | 701 | } |
@@ -727,33 +704,52 @@ static void receive_crypto(void) | |||
727 | 704 | ||
728 | /* run this to (re)initialize net_crypto | 705 | /* run this to (re)initialize net_crypto |
729 | sets all the global connection variables to their default values. */ | 706 | sets all the global connection variables to their default values. */ |
730 | void initNetCrypto(void) | 707 | Net_Crypto * new_net_crypto(Networking_Core * net) |
731 | { | 708 | { |
732 | memset(incoming_connections, -1 , sizeof(incoming_connections)); | 709 | Net_Crypto * temp = calloc(1, sizeof(Net_Crypto)); |
733 | networking_registerhandler(32, &cryptopacket_handle); | 710 | if (temp == NULL) |
711 | return NULL; | ||
712 | temp->lossless_udp = new_lossless_udp(net); | ||
713 | if (temp->lossless_udp == NULL) | ||
714 | return NULL; | ||
715 | memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); | ||
716 | //networking_registerhandler(temp, 32, &cryptopacket_handle); | ||
717 | networking_registerhandler(net, 32, &cryptopacket_handle, temp); | ||
718 | temp_net_crypto = temp; //TODO remove | ||
719 | return temp; | ||
734 | } | 720 | } |
735 | 721 | ||
736 | static void killTimedout(void) | 722 | static void kill_timedout(Net_Crypto *c) |
737 | { | 723 | { |
738 | uint32_t i; | 724 | uint32_t i; |
739 | 725 | ||
740 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 726 | for (i = 0; i < c->crypto_connections_length; ++i) { |
741 | if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4) | 727 | if (c->crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(c->lossless_udp, c->crypto_connections[i].number) == 4) |
742 | crypto_connections[i].status = CONN_TIMED_OUT; | 728 | c->crypto_connections[i].status = CONN_TIMED_OUT; |
743 | else if (is_connected(crypto_connections[i].number) == 4) { | 729 | else if (is_connected(c->lossless_udp, c->crypto_connections[i].number) == 4) { |
744 | kill_connection(crypto_connections[i].number); | 730 | kill_connection(c->lossless_udp, c->crypto_connections[i].number); |
745 | crypto_connections[i].number = ~0; | 731 | c->crypto_connections[i].number = ~0; |
746 | } | 732 | } |
747 | } | 733 | } |
748 | } | 734 | } |
749 | 735 | ||
750 | /* main loop */ | 736 | /* main loop */ |
751 | void doNetCrypto(void) | 737 | void do_net_crypto(Net_Crypto *c) |
752 | { | 738 | { |
753 | /* TODO:check if friend requests were sent correctly | 739 | do_lossless_udp(c->lossless_udp); |
754 | handle new incoming connections | 740 | handle_incomings(c); |
755 | handle friend requests */ | 741 | receive_crypto(c); |
756 | handle_incomings(); | 742 | kill_timedout(c); |
757 | receive_crypto(); | 743 | } |
758 | killTimedout(); | 744 | |
745 | void kill_net_crypto(Net_Crypto *c) | ||
746 | { | ||
747 | uint32_t i; | ||
748 | |||
749 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
750 | crypto_kill(c, i); | ||
751 | } | ||
752 | kill_lossless_udp(c->lossless_udp); | ||
753 | memset(c, 0, sizeof(Net_Crypto)); | ||
754 | free(c); | ||
759 | } | 755 | } |
diff --git a/core/net_crypto.h b/core/net_crypto.h index 742d9fdc..745f1f14 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -31,10 +31,47 @@ | |||
31 | extern "C" { | 31 | extern "C" { |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | /* Our public key. */ | 34 | #define MAX_INCOMING 64 |
35 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 35 | |
36 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];//TODO: Remove this | ||
36 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | 37 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; |
37 | 38 | ||
39 | typedef struct { | ||
40 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ | ||
41 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ | ||
42 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ | ||
43 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ | ||
44 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ | ||
45 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | ||
46 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */ | ||
47 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
48 | (we have received a handshake but no empty data packet), 3 if the connection is established. | ||
49 | 4 if the connection is timed out. */ | ||
50 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ | ||
51 | |||
52 | } Crypto_Connection; | ||
53 | |||
54 | typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len); | ||
55 | |||
56 | typedef struct { | ||
57 | Lossless_UDP * lossless_udp; | ||
58 | |||
59 | Crypto_Connection *crypto_connections; | ||
60 | |||
61 | uint32_t crypto_connections_length; /* Length of connections array */ | ||
62 | |||
63 | /* Our public and secret keys. */ | ||
64 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
65 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
66 | |||
67 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | ||
68 | int incoming_connections[MAX_INCOMING]; | ||
69 | |||
70 | cryptopacket_handler_callback cryptopackethandlers[256]; | ||
71 | } Net_Crypto; | ||
72 | |||
73 | Net_Crypto * temp_net_crypto; //TODO: remove this | ||
74 | |||
38 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) | 75 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) |
39 | 76 | ||
40 | /* returns zero if the buffer contains only zeros */ | 77 | /* returns zero if the buffer contains only zeros */ |
@@ -75,34 +112,35 @@ void random_nonce(uint8_t *nonce); | |||
75 | /* return 0 if there is no received data in the buffer | 112 | /* return 0 if there is no received data in the buffer |
76 | return -1 if the packet was discarded. | 113 | return -1 if the packet was discarded. |
77 | return length of received data if successful */ | 114 | return length of received data if successful */ |
78 | int read_cryptpacket(int crypt_connection_id, uint8_t *data); | 115 | int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data); |
79 | 116 | ||
80 | /* return 0 if data could not be put in packet queue | 117 | /* return 0 if data could not be put in packet queue |
81 | return 1 if data was put into the queue */ | 118 | return 1 if data was put into the queue */ |
82 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); | 119 | int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); |
83 | 120 | ||
84 | /* create a request to peer with public_key. | 121 | /* create a request to peer. |
85 | packet must be an array of MAX_DATA_SIZE big. | 122 | send_public_key and send_secret_key are the pub/secret keys of the sender |
86 | Data represents the data we send with the request with length being the length of the data. | 123 | recv_public_key is public key of reciever |
87 | request_id is the id of the request (32 = friend request, 254 = ping request) | 124 | packet must be an array of MAX_DATA_SIZE big. |
88 | returns -1 on failure | 125 | Data represents the data we send with the request with length being the length of the data. |
89 | returns the length of the created packet on success */ | 126 | request_id is the id of the request (32 = friend request, 254 = ping request) |
90 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id); | 127 | returns -1 on failure |
128 | returns the length of the created packet on success */ | ||
129 | int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, uint8_t *data, uint32_t length, uint8_t request_id); | ||
91 | 130 | ||
92 | 131 | ||
93 | typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len); | ||
94 | /* Function to call when request beginning with byte is received */ | 132 | /* Function to call when request beginning with byte is received */ |
95 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); | 133 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb); |
96 | 134 | ||
97 | /* Start a secure connection with other peer who has public_key and ip_port | 135 | /* Start a secure connection with other peer who has public_key and ip_port |
98 | returns -1 if failure | 136 | returns -1 if failure |
99 | returns crypt_connection_id of the initialized connection if everything went well. */ | 137 | returns crypt_connection_id of the initialized connection if everything went well. */ |
100 | int crypto_connect(uint8_t *public_key, IP_Port ip_port); | 138 | int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port); |
101 | 139 | ||
102 | /* kill a crypto connection | 140 | /* kill a crypto connection |
103 | return 0 if killed successfully | 141 | return 0 if killed successfully |
104 | return 1 if there was a problem. */ | 142 | return 1 if there was a problem. */ |
105 | int crypto_kill(int crypt_connection_id); | 143 | int crypto_kill(Net_Crypto *c, int crypt_connection_id); |
106 | 144 | ||
107 | /* handle an incoming connection | 145 | /* handle an incoming connection |
108 | return -1 if no crypto inbound connection | 146 | return -1 if no crypto inbound connection |
@@ -111,37 +149,39 @@ int crypto_kill(int crypt_connection_id); | |||
111 | and the session public key for the connection in session_key | 149 | and the session public key for the connection in session_key |
112 | to accept it see: accept_crypto_inbound(...) | 150 | to accept it see: accept_crypto_inbound(...) |
113 | to refuse it just call kill_connection(...) on the connection id */ | 151 | to refuse it just call kill_connection(...) on the connection id */ |
114 | int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); | 152 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); |
115 | 153 | ||
116 | /* accept an incoming connection using the parameters provided by crypto_inbound | 154 | /* accept an incoming connection using the parameters provided by crypto_inbound |
117 | return -1 if not successful | 155 | return -1 if not successful |
118 | returns the crypt_connection_id if successful */ | 156 | returns the crypt_connection_id if successful */ |
119 | int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); | 157 | int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); |
120 | 158 | ||
121 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | 159 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet |
122 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 160 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
123 | 4 if the connection is timed out and waiting to be killed */ | 161 | 4 if the connection is timed out and waiting to be killed */ |
124 | int is_cryptoconnected(int crypt_connection_id); | 162 | int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id); |
125 | 163 | ||
126 | 164 | ||
127 | /* Generate our public and private keys | 165 | /* Generate our public and private keys |
128 | Only call this function the first time the program starts. */ | 166 | Only call this function the first time the program starts. */ |
129 | void new_keys(void); | 167 | void new_keys(Net_Crypto *c); |
130 | 168 | ||
131 | /* save the public and private keys to the keys array | 169 | /* save the public and private keys to the keys array |
132 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 170 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
133 | void save_keys(uint8_t *keys); | 171 | void save_keys(Net_Crypto *c, uint8_t *keys); |
134 | 172 | ||
135 | /* load the public and private keys from the keys array | 173 | /* load the public and private keys from the keys array |
136 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 174 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
137 | void load_keys(uint8_t *keys); | 175 | void load_keys(Net_Crypto *c, uint8_t *keys); |
138 | 176 | ||
139 | /* run this to (re)initialize net_crypto | 177 | /* create new instance of Net_Crypto |
140 | sets all the global connection variables to their default values. */ | 178 | sets all the global connection variables to their default values. */ |
141 | void initNetCrypto(void); | 179 | Net_Crypto * new_net_crypto(Networking_Core * net); |
142 | 180 | ||
143 | /* main loop */ | 181 | /* main loop */ |
144 | void doNetCrypto(void); | 182 | void do_net_crypto(Net_Crypto *c); |
183 | |||
184 | void kill_net_crypto(Net_Crypto *c); | ||
145 | 185 | ||
146 | #ifdef __cplusplus | 186 | #ifdef __cplusplus |
147 | } | 187 | } |
diff --git a/core/network.c b/core/network.c index 1977ce38..684a4227 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -56,12 +56,9 @@ uint32_t random_int(void) | |||
56 | #endif | 56 | #endif |
57 | } | 57 | } |
58 | 58 | ||
59 | /* our UDP socket, a global variable. */ | ||
60 | static int sock; | ||
61 | |||
62 | /* Basic network functions: | 59 | /* Basic network functions: |
63 | Function to send packet(data) of length length to ip_port */ | 60 | Function to send packet(data) of length length to ip_port */ |
64 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) | 61 | int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length) |
65 | { | 62 | { |
66 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; | 63 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; |
67 | return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | 64 | return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); |
@@ -71,7 +68,7 @@ int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) | |||
71 | the packet data into data | 68 | the packet data into data |
72 | the packet length into length. | 69 | the packet length into length. |
73 | dump all empty packets. */ | 70 | dump all empty packets. */ |
74 | static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) | 71 | static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) |
75 | { | 72 | { |
76 | ADDR addr; | 73 | ADDR addr; |
77 | #ifdef WIN32 | 74 | #ifdef WIN32 |
@@ -89,36 +86,32 @@ static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) | |||
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | 88 | ||
92 | static packet_handler_callback packethandlers[256] = {0}; | 89 | void networking_registerhandler(Networking_Core * net, uint8_t byte, packet_handler_callback cb, void * object) |
93 | |||
94 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb) | ||
95 | { | 90 | { |
96 | packethandlers[byte] = cb; | 91 | net->packethandlers[byte].function = cb; |
92 | net->packethandlers[byte].object = object; | ||
97 | } | 93 | } |
98 | 94 | ||
99 | void networking_poll() | 95 | void networking_poll(Networking_Core * net) |
100 | { | 96 | { |
101 | IP_Port ip_port; | 97 | IP_Port ip_port; |
102 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 98 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
103 | uint32_t length; | 99 | uint32_t length; |
104 | 100 | ||
105 | while (receivepacket(&ip_port, data, &length) != -1) { | 101 | while (receivepacket(net->sock, &ip_port, data, &length) != -1) { |
106 | if (length < 1) continue; | 102 | if (length < 1) continue; |
107 | 103 | ||
108 | if (!packethandlers[data[0]]) continue; | 104 | if (!(net->packethandlers[data[0]].function)) continue; |
109 | 105 | ||
110 | packethandlers[data[0]](ip_port, data, length); | 106 | net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); |
111 | } | 107 | } |
112 | } | 108 | } |
113 | 109 | ||
114 | /* initialize networking | 110 | uint8_t at_startup_ran; |
115 | bind to ip and port | 111 | static void at_startup(void) |
116 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
117 | port is in host byte order (this means don't worry about it) | ||
118 | returns 0 if no problems | ||
119 | returns -1 if there are problems */ | ||
120 | int init_networking(IP ip, uint16_t port) | ||
121 | { | 112 | { |
113 | if (at_startup_ran != 0) | ||
114 | return; | ||
122 | #ifdef WIN32 | 115 | #ifdef WIN32 |
123 | WSADATA wsaData; | 116 | WSADATA wsaData; |
124 | 117 | ||
@@ -128,21 +121,48 @@ int init_networking(IP ip, uint16_t port) | |||
128 | #else | 121 | #else |
129 | srandom((uint32_t)current_time()); | 122 | srandom((uint32_t)current_time()); |
130 | #endif | 123 | #endif |
131 | srand((uint32_t)current_time()); | 124 | srand((uint32_t)current_time()); |
125 | at_startup_ran = 1; | ||
126 | } | ||
127 | |||
128 | /* TODO: put this somewhere | ||
129 | static void at_shutdown(void) | ||
130 | { | ||
131 | #ifdef WIN32 | ||
132 | WSACleanup(); | ||
133 | #endif | ||
134 | } | ||
135 | */ | ||
132 | 136 | ||
137 | /* initialize networking | ||
138 | bind to ip and port | ||
139 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
140 | port is in host byte order (this means don't worry about it) | ||
141 | returns Networking_Core object if no problems | ||
142 | returns NULL if there are problems */ | ||
143 | Networking_Core * new_networking(IP ip, uint16_t port) | ||
144 | { | ||
145 | at_startup(); | ||
133 | /* initialize our socket */ | 146 | /* initialize our socket */ |
134 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | 147 | Networking_Core * temp = calloc(1, sizeof(Networking_Core)); |
148 | if (temp == NULL) | ||
149 | return NULL; | ||
150 | temp->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
135 | 151 | ||
136 | /* Check for socket error */ | 152 | /* Check for socket error */ |
137 | #ifdef WIN32 | 153 | #ifdef WIN32 |
138 | 154 | ||
139 | if (sock == INVALID_SOCKET) /* MSDN recommends this */ | 155 | if (temp->sock == INVALID_SOCKET) { /* MSDN recommends this */ |
140 | return -1; | 156 | free(temp); |
157 | return NULL; | ||
158 | } | ||
141 | 159 | ||
142 | #else | 160 | #else |
143 | 161 | ||
144 | if (sock < 0) | 162 | if (temp->sock < 0) { |
145 | return -1; | 163 | free(temp); |
164 | return NULL; | ||
165 | } | ||
146 | 166 | ||
147 | #endif | 167 | #endif |
148 | 168 | ||
@@ -161,34 +181,34 @@ int init_networking(IP ip, uint16_t port) | |||
161 | 181 | ||
162 | /* Enable broadcast on socket */ | 182 | /* Enable broadcast on socket */ |
163 | int broadcast = 1; | 183 | int broadcast = 1; |
164 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); | 184 | setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); |
165 | 185 | ||
166 | /* Set socket nonblocking */ | 186 | /* Set socket nonblocking */ |
167 | #ifdef WIN32 | 187 | #ifdef WIN32 |
168 | /* I think this works for windows */ | 188 | /* I think this works for windows */ |
169 | u_long mode = 1; | 189 | u_long mode = 1; |
170 | /* ioctl(sock, FIONBIO, &mode); */ | 190 | /* ioctl(sock, FIONBIO, &mode); */ |
171 | ioctlsocket(sock, FIONBIO, &mode); | 191 | ioctlsocket(temp->sock, FIONBIO, &mode); |
172 | #else | 192 | #else |
173 | fcntl(sock, F_SETFL, O_NONBLOCK, 1); | 193 | fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1); |
174 | #endif | 194 | #endif |
175 | 195 | ||
176 | /* Bind our socket to port PORT and address 0.0.0.0 */ | 196 | /* Bind our socket to port PORT and address 0.0.0.0 */ |
177 | ADDR addr = {AF_INET, htons(port), ip}; | 197 | ADDR addr = {AF_INET, htons(port), ip}; |
178 | bind(sock, (struct sockaddr *)&addr, sizeof(addr)); | 198 | bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); |
179 | 199 | temp_net = temp; | |
180 | return 0; | 200 | return temp; |
181 | } | 201 | } |
182 | 202 | ||
183 | /* function to cleanup networking stuff */ | 203 | /* function to cleanup networking stuff */ |
184 | void shutdown_networking(void) | 204 | void kill_networking(Networking_Core * net) |
185 | { | 205 | { |
186 | #ifdef WIN32 | 206 | #ifdef WIN32 |
187 | closesocket(sock); | 207 | closesocket(net->sock); |
188 | WSACleanup(); | ||
189 | #else | 208 | #else |
190 | close(sock); | 209 | close(net->sock); |
191 | #endif | 210 | #endif |
211 | free(net); | ||
192 | return; | 212 | return; |
193 | } | 213 | } |
194 | 214 | ||
diff --git a/core/network.h b/core/network.h index 127a55d1..5ed25620 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -99,8 +99,20 @@ typedef struct { | |||
99 | /* Function to receive data, ip and port of sender is put into ip_port | 99 | /* Function to receive data, ip and port of sender is put into ip_port |
100 | the packet data into data | 100 | the packet data into data |
101 | the packet length into length. */ | 101 | the packet length into length. */ |
102 | typedef int (*packet_handler_callback)(IP_Port ip_port, uint8_t *data, uint32_t len); | 102 | typedef int (*packet_handler_callback)(void * object, IP_Port ip_port, uint8_t *data, uint32_t len); |
103 | 103 | ||
104 | typedef struct { | ||
105 | packet_handler_callback function; | ||
106 | void * object; | ||
107 | }Packet_Handles; | ||
108 | |||
109 | typedef struct { | ||
110 | Packet_Handles packethandlers[256]; | ||
111 | /* our UDP socket */ | ||
112 | int sock; | ||
113 | }Networking_Core; | ||
114 | |||
115 | Networking_Core * temp_net; | ||
104 | /* returns current time in milleseconds since the epoch. */ | 116 | /* returns current time in milleseconds since the epoch. */ |
105 | uint64_t current_time(void); | 117 | uint64_t current_time(void); |
106 | 118 | ||
@@ -111,13 +123,13 @@ uint32_t random_int(void); | |||
111 | /* Basic network functions: */ | 123 | /* Basic network functions: */ |
112 | 124 | ||
113 | /* Function to send packet(data) of length length to ip_port */ | 125 | /* Function to send packet(data) of length length to ip_port */ |
114 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); | 126 | int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length); |
115 | 127 | ||
116 | /* Function to call when packet beginning with byte is received */ | 128 | /* Function to call when packet beginning with byte is received */ |
117 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb); | 129 | void networking_registerhandler(Networking_Core * net, uint8_t byte, packet_handler_callback cb, void * object); |
118 | 130 | ||
119 | /* call this several times a second */ | 131 | /* call this several times a second */ |
120 | void networking_poll(); | 132 | void networking_poll(Networking_Core * net); |
121 | 133 | ||
122 | /* initialize networking | 134 | /* initialize networking |
123 | bind to ip and port | 135 | bind to ip and port |
@@ -125,10 +137,10 @@ void networking_poll(); | |||
125 | port is in host byte order (this means don't worry about it) | 137 | port is in host byte order (this means don't worry about it) |
126 | returns 0 if no problems | 138 | returns 0 if no problems |
127 | returns -1 if there were problems */ | 139 | returns -1 if there were problems */ |
128 | int init_networking(IP ip, uint16_t port); | 140 | Networking_Core * new_networking(IP ip, uint16_t port); |
129 | 141 | ||
130 | /* function to cleanup networking stuff(doesn't do much right now) */ | 142 | /* function to cleanup networking stuff(doesn't do much right now) */ |
131 | void shutdown_networking(void); | 143 | void kill_networking(Networking_Core * net); |
132 | 144 | ||
133 | /* | 145 | /* |
134 | resolve_addr(): | 146 | resolve_addr(): |
diff --git a/core/ping.c b/core/ping.c index 47d6e163..d2b290a0 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -135,7 +135,7 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id) | |||
135 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 135 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
136 | return 1; | 136 | return 1; |
137 | 137 | ||
138 | return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk)); | 138 | return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
139 | } | 139 | } |
140 | 140 | ||
141 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | 141 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) |
@@ -160,10 +160,10 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | |||
160 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 160 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
161 | return 1; | 161 | return 1; |
162 | 162 | ||
163 | return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk)); | 163 | return sendpacket(temp_net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
164 | } | 164 | } |
165 | 165 | ||
166 | int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length) | 166 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
167 | { | 167 | { |
168 | pingreq_t *p = (pingreq_t *) packet; | 168 | pingreq_t *p = (pingreq_t *) packet; |
169 | int rc; | 169 | int rc; |
@@ -190,7 +190,7 @@ int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length) | |||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length) | 193 | int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
194 | { | 194 | { |
195 | pingres_t *p = (pingres_t *) packet; | 195 | pingres_t *p = (pingres_t *) packet; |
196 | int rc; | 196 | int rc; |
diff --git a/core/ping.h b/core/ping.h index 0c44874b..6d5a0ea6 100644 --- a/core/ping.h +++ b/core/ping.h | |||
@@ -12,5 +12,5 @@ uint64_t add_ping(IP_Port ipp); | |||
12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); | 12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); |
13 | int send_ping_request(IP_Port ipp, clientid_t *client_id); | 13 | int send_ping_request(IP_Port ipp, clientid_t *client_id); |
14 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); | 14 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); |
15 | int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length); | 15 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length); |
16 | int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length); | 16 | int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_t length); |