diff options
Diffstat (limited to 'core/Lossless_UDP.c')
-rw-r--r-- | core/Lossless_UDP.c | 281 |
1 files changed, 71 insertions, 210 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index c4c464b6..43f61b5b 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -1,32 +1,30 @@ | |||
1 | /* Lossless_UDP.c | 1 | /* Lossless_UDP.c |
2 | * | 2 | * |
3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt | 3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt |
4 | * | 4 | * |
5 | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. | |
6 | Copyright (C) 2013 Tox project All Rights Reserved. | 6 | * |
7 | 7 | * This file is part of Tox. | |
8 | This file is part of Tox. | 8 | * |
9 | 9 | * Tox is free software: you can redistribute it and/or modify | |
10 | Tox is free software: you can redistribute it and/or modify | 10 | * it under the terms of the GNU General Public License as published by |
11 | it under the terms of the GNU General Public License as published by | 11 | * the Free Software Foundation, either version 3 of the License, or |
12 | the Free Software Foundation, either version 3 of the License, or | 12 | * (at your option) any later version. |
13 | (at your option) any later version. | 13 | * |
14 | 14 | * Tox is distributed in the hope that it will be useful, | |
15 | Tox is distributed in the hope that it will be useful, | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * GNU General Public License for more details. |
18 | GNU General Public License for more details. | 18 | * |
19 | 19 | * You should have received a copy of the GNU General Public License | |
20 | You should have received a copy of the GNU General Public License | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | along with Tox. If not, see <http://www.gnu.org/licenses/>. | 21 | * |
22 | 22 | */ | |
23 | */ | 23 | |
24 | /* TODO: clean this file a bit. | 24 | /* TODO: clean this file a bit. |
25 | There are a couple of useless variables to get rid of. */ | 25 | There are a couple of useless variables to get rid of. */ |
26 | #include "Lossless_UDP.h" | 26 | #include "Lossless_UDP.h" |
27 | 27 | ||
28 | |||
29 | |||
30 | /* maximum data packets in sent and receive queues. */ | 28 | /* maximum data packets in sent and receive queues. */ |
31 | #define MAX_QUEUE_NUM 16 | 29 | #define MAX_QUEUE_NUM 16 |
32 | 30 | ||
@@ -88,7 +86,6 @@ typedef struct | |||
88 | uint8_t timeout; /* connection timeout in seconds. */ | 86 | uint8_t timeout; /* connection timeout in seconds. */ |
89 | }Connection; | 87 | }Connection; |
90 | 88 | ||
91 | |||
92 | #define MAX_CONNECTIONS 256 | 89 | #define MAX_CONNECTIONS 256 |
93 | 90 | ||
94 | static Connection connections[MAX_CONNECTIONS]; | 91 | static Connection connections[MAX_CONNECTIONS]; |
@@ -104,40 +101,31 @@ int getconnection_id(IP_Port ip_port) | |||
104 | { | 101 | { |
105 | uint32_t i; | 102 | uint32_t i; |
106 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 103 | for(i = 0; i < MAX_CONNECTIONS; ++i) |
107 | { | ||
108 | if(connections[i].ip_port.ip.i == ip_port.ip.i && | 104 | if(connections[i].ip_port.ip.i == ip_port.ip.i && |
109 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) | 105 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) |
110 | { | ||
111 | return i; | 106 | return i; |
112 | } | ||
113 | } | ||
114 | return -1; | 107 | return -1; |
115 | } | 108 | } |
116 | 109 | ||
117 | /* table of random numbers used below. */ | 110 | /* table of random numbers used below. */ |
118 | static uint32_t randtable[6][256]; | 111 | static uint32_t randtable[6][256]; |
119 | 112 | ||
120 | |||
121 | /* generate a handshake_id which depends on the ip_port. | 113 | /* generate a handshake_id which depends on the ip_port. |
122 | this function will always give one unique handshake_id per ip_port. | 114 | this function will always give one unique handshake_id per ip_port. |
123 | TODO: make this better */ | 115 | TODO: make this better */ |
124 | uint32_t handshake_id(IP_Port source) | 116 | uint32_t handshake_id(IP_Port source) |
125 | { | 117 | { |
126 | uint32_t id = 0, i; | 118 | uint32_t id = 0, i; |
127 | for(i = 0; i < 6; ++i) | 119 | for(i = 0; i < 6; ++i) { |
128 | { | ||
129 | if(randtable[i][((uint8_t *)&source)[i]] == 0) | 120 | if(randtable[i][((uint8_t *)&source)[i]] == 0) |
130 | { | ||
131 | randtable[i][((uint8_t *)&source)[i]] = random_int(); | 121 | randtable[i][((uint8_t *)&source)[i]] = random_int(); |
132 | } | ||
133 | id ^= randtable[i][((uint8_t *)&source)[i]]; | 122 | id ^= randtable[i][((uint8_t *)&source)[i]]; |
134 | } | 123 | } |
135 | if(id == 0) /* id can't be zero */ | 124 | if(id == 0) /* id can't be zero */ |
136 | { | ||
137 | id = 1; | 125 | id = 1; |
138 | } | ||
139 | return id; | 126 | return id; |
140 | } | 127 | } |
128 | |||
141 | /* change the hnshake id associated with that ip_port | 129 | /* change the hnshake id associated with that ip_port |
142 | TODO: make this better */ | 130 | TODO: make this better */ |
143 | void change_handshake(IP_Port source) | 131 | void change_handshake(IP_Port source) |
@@ -146,7 +134,6 @@ void change_handshake(IP_Port source) | |||
146 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); | 134 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); |
147 | } | 135 | } |
148 | 136 | ||
149 | |||
150 | /* initialize a new connection to ip_port | 137 | /* initialize a new connection to ip_port |
151 | returns an integer corresponding to the connection id. | 138 | returns an integer corresponding to the connection id. |
152 | return -1 if it could not initialize the connection. | 139 | return -1 if it could not initialize the connection. |
@@ -155,14 +142,10 @@ int new_connection(IP_Port ip_port) | |||
155 | { | 142 | { |
156 | int connect = getconnection_id(ip_port); | 143 | int connect = getconnection_id(ip_port); |
157 | if(connect != -1) | 144 | if(connect != -1) |
158 | { | ||
159 | return connect; | 145 | return connect; |
160 | } | ||
161 | uint32_t i; | 146 | uint32_t i; |
162 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 147 | for(i = 0; i < MAX_CONNECTIONS; ++i) { |
163 | { | 148 | if(connections[i].status == 0) { |
164 | if(connections[i].status == 0) | ||
165 | { | ||
166 | memset(&connections[i], 0, sizeof(Connection)); | 149 | memset(&connections[i], 0, sizeof(Connection)); |
167 | connections[i].ip_port = ip_port; | 150 | connections[i].ip_port = ip_port; |
168 | connections[i].status = 1; | 151 | connections[i].status = 1; |
@@ -191,14 +174,10 @@ int new_connection(IP_Port ip_port) | |||
191 | int new_inconnection(IP_Port ip_port) | 174 | int new_inconnection(IP_Port ip_port) |
192 | { | 175 | { |
193 | if(getconnection_id(ip_port) != -1) | 176 | if(getconnection_id(ip_port) != -1) |
194 | { | ||
195 | return -1; | 177 | return -1; |
196 | } | ||
197 | uint32_t i; | 178 | uint32_t i; |
198 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 179 | for(i = 0; i < MAX_CONNECTIONS; ++i) { |
199 | { | 180 | if(connections[i].status == 0) { |
200 | if(connections[i].status == 0) | ||
201 | { | ||
202 | memset(&connections[i], 0, sizeof(Connection)); | 181 | memset(&connections[i], 0, sizeof(Connection)); |
203 | connections[i].ip_port = ip_port; | 182 | connections[i].ip_port = ip_port; |
204 | connections[i].status = 2; | 183 | connections[i].status = 2; |
@@ -224,13 +203,10 @@ int incoming_connection() | |||
224 | { | 203 | { |
225 | uint32_t i; | 204 | uint32_t i; |
226 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 205 | for(i = 0; i < MAX_CONNECTIONS; ++i) |
227 | { | 206 | if(connections[i].inbound == 2) { |
228 | if(connections[i].inbound == 2) | ||
229 | { | ||
230 | connections[i].inbound = 1; | 207 | connections[i].inbound = 1; |
231 | return i; | 208 | return i; |
232 | } | 209 | } |
233 | } | ||
234 | return -1; | 210 | return -1; |
235 | } | 211 | } |
236 | 212 | ||
@@ -239,14 +215,11 @@ int incoming_connection() | |||
239 | int kill_connection(int connection_id) | 215 | int kill_connection(int connection_id) |
240 | { | 216 | { |
241 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 217 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
242 | { | 218 | if(connections[connection_id].status > 0) { |
243 | if(connections[connection_id].status > 0) | ||
244 | { | ||
245 | connections[connection_id].status = 0; | 219 | connections[connection_id].status = 0; |
246 | change_handshake(connections[connection_id].ip_port); | 220 | change_handshake(connections[connection_id].ip_port); |
247 | return 0; | 221 | return 0; |
248 | } | 222 | } |
249 | } | ||
250 | return -1; | 223 | return -1; |
251 | } | 224 | } |
252 | 225 | ||
@@ -256,13 +229,10 @@ int kill_connection(int connection_id) | |||
256 | int kill_connection_in(int connection_id, uint32_t seconds) | 229 | int kill_connection_in(int connection_id, uint32_t seconds) |
257 | { | 230 | { |
258 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 231 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
259 | { | 232 | if(connections[connection_id].status > 0) { |
260 | if(connections[connection_id].status > 0) | ||
261 | { | ||
262 | connections[connection_id].killat = current_time() + 1000000UL*seconds; | 233 | connections[connection_id].killat = current_time() + 1000000UL*seconds; |
263 | return 0; | 234 | return 0; |
264 | } | 235 | } |
265 | } | ||
266 | return -1; | 236 | return -1; |
267 | } | 237 | } |
268 | 238 | ||
@@ -275,9 +245,7 @@ int kill_connection_in(int connection_id, uint32_t seconds) | |||
275 | int is_connected(int connection_id) | 245 | int is_connected(int connection_id) |
276 | { | 246 | { |
277 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 247 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
278 | { | ||
279 | return connections[connection_id].status; | 248 | return connections[connection_id].status; |
280 | } | ||
281 | return 0; | 249 | return 0; |
282 | } | 250 | } |
283 | 251 | ||
@@ -285,9 +253,7 @@ int is_connected(int connection_id) | |||
285 | IP_Port connection_ip(int connection_id) | 253 | IP_Port connection_ip(int connection_id) |
286 | { | 254 | { |
287 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 255 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
288 | { | ||
289 | return connections[connection_id].ip_port; | 256 | return connections[connection_id].ip_port; |
290 | } | ||
291 | IP_Port zero = {{{0}}, 0}; | 257 | IP_Port zero = {{{0}}, 0}; |
292 | return zero; | 258 | return zero; |
293 | } | 259 | } |
@@ -309,17 +275,15 @@ uint32_t recvqueue(int connection_id) | |||
309 | char id_packet(int connection_id) | 275 | char id_packet(int connection_id) |
310 | { | 276 | { |
311 | if(recvqueue(connection_id) != 0 && connections[connection_id].status != 0) | 277 | if(recvqueue(connection_id) != 0 && connections[connection_id].status != 0) |
312 | { | ||
313 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; | 278 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; |
314 | } | ||
315 | return -1; | 279 | return -1; |
316 | } | 280 | } |
281 | |||
317 | /* return 0 if there is no received data in the buffer. | 282 | /* return 0 if there is no received data in the buffer. |
318 | return length of received packet if successful */ | 283 | return length of received packet if successful */ |
319 | int read_packet(int connection_id, uint8_t * data) | 284 | int read_packet(int connection_id, uint8_t * data) |
320 | { | 285 | { |
321 | if(recvqueue(connection_id) != 0) | 286 | if(recvqueue(connection_id) != 0) { |
322 | { | ||
323 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; | 287 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; |
324 | uint16_t size = connections[connection_id].recvbuffer[index].size; | 288 | uint16_t size = connections[connection_id].recvbuffer[index].size; |
325 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); | 289 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); |
@@ -335,15 +299,10 @@ int read_packet(int connection_id, uint8_t * data) | |||
335 | int write_packet(int connection_id, uint8_t * data, uint32_t length) | 299 | int write_packet(int connection_id, uint8_t * data, uint32_t length) |
336 | { | 300 | { |
337 | if(length > MAX_DATA_SIZE) | 301 | if(length > MAX_DATA_SIZE) |
338 | { | ||
339 | return 0; | 302 | return 0; |
340 | } | ||
341 | if(length == 0) | 303 | if(length == 0) |
342 | { | ||
343 | return 0; | 304 | return 0; |
344 | } | 305 | if(sendqueue(connection_id) < BUFFER_PACKET_NUM) { |
345 | if(sendqueue(connection_id) < BUFFER_PACKET_NUM) | ||
346 | { | ||
347 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | 306 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; |
348 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | 307 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); |
349 | connections[connection_id].sendbuffer[index].size = length; | 308 | connections[connection_id].sendbuffer[index].size = length; |
@@ -353,9 +312,6 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length) | |||
353 | return 0; | 312 | return 0; |
354 | } | 313 | } |
355 | 314 | ||
356 | |||
357 | |||
358 | |||
359 | /* put the packet numbers the we are missing in requested and return the number */ | 315 | /* put the packet numbers the we are missing in requested and return the number */ |
360 | uint32_t missing_packets(int connection_id, uint32_t * requested) | 316 | uint32_t missing_packets(int connection_id, uint32_t * requested) |
361 | { | 317 | { |
@@ -363,59 +319,47 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
363 | uint32_t i; | 319 | uint32_t i; |
364 | uint32_t temp; | 320 | uint32_t temp; |
365 | if(recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ | 321 | if(recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ |
366 | { | ||
367 | return 0; | 322 | return 0; |
368 | } | ||
369 | for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ ) | 323 | for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ ) |
370 | { | 324 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { |
371 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) | ||
372 | { | ||
373 | temp = htonl(i); | 325 | temp = htonl(i); |
374 | memcpy(requested + number, &temp, 4); | 326 | memcpy(requested + number, &temp, 4); |
375 | ++number; | 327 | ++number; |
376 | } | 328 | } |
377 | } | ||
378 | if(number == 0) | 329 | if(number == 0) |
379 | { | ||
380 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; | 330 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; |
381 | } | ||
382 | return number; | 331 | return number; |
383 | |||
384 | } | 332 | } |
385 | 333 | ||
386 | /* Packet sending functions | 334 | /* Packet sending functions |
387 | One per packet type. | 335 | One per packet type. |
388 | see docs/Lossless_UDP.txt for more information. */ | 336 | see docs/Lossless_UDP.txt for more information. */ |
389 | |||
390 | |||
391 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 337 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) |
392 | { | 338 | { |
393 | uint8_t packet[1 + 4 + 4]; | 339 | uint8_t packet[1 + 4 + 4]; |
394 | uint32_t temp; | 340 | uint32_t temp; |
395 | 341 | ||
396 | packet[0] = 16; | 342 | packet[0] = 16; |
397 | temp = htonl(handshake_id1); | 343 | temp = htonl(handshake_id1); |
398 | memcpy(packet + 1, &temp, 4); | 344 | memcpy(packet + 1, &temp, 4); |
399 | temp = htonl(handshake_id2); | 345 | temp = htonl(handshake_id2); |
400 | memcpy(packet + 5, &temp, 4); | 346 | memcpy(packet + 5, &temp, 4); |
401 | return sendpacket(ip_port, packet, sizeof(packet)); | 347 | return sendpacket(ip_port, packet, sizeof(packet)); |
402 | |||
403 | } | 348 | } |
404 | 349 | ||
405 | |||
406 | int send_SYNC(uint32_t connection_id) | 350 | int send_SYNC(uint32_t connection_id) |
407 | { | 351 | { |
408 | 352 | ||
409 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; | 353 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; |
410 | uint16_t index = 0; | 354 | uint16_t index = 0; |
411 | 355 | ||
412 | IP_Port ip_port = connections[connection_id].ip_port; | 356 | IP_Port ip_port = connections[connection_id].ip_port; |
413 | uint8_t counter = connections[connection_id].send_counter; | 357 | uint8_t counter = connections[connection_id].send_counter; |
414 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); | 358 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); |
415 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); | 359 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); |
416 | uint32_t requested[BUFFER_PACKET_NUM]; | 360 | uint32_t requested[BUFFER_PACKET_NUM]; |
417 | uint32_t number = missing_packets(connection_id, requested); | 361 | uint32_t number = missing_packets(connection_id, requested); |
418 | 362 | ||
419 | packet[0] = 17; | 363 | packet[0] = 17; |
420 | index += 1; | 364 | index += 1; |
421 | memcpy(packet + index, &counter, 1); | 365 | memcpy(packet + index, &counter, 1); |
@@ -427,7 +371,7 @@ int send_SYNC(uint32_t connection_id) | |||
427 | memcpy(packet + index, requested, 4 * number); | 371 | memcpy(packet + index, requested, 4 * number); |
428 | 372 | ||
429 | return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2)); | 373 | return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2)); |
430 | 374 | ||
431 | } | 375 | } |
432 | 376 | ||
433 | int send_data_packet(uint32_t connection_id, uint32_t packet_num) | 377 | int send_data_packet(uint32_t connection_id, uint32_t packet_num) |
@@ -449,16 +393,14 @@ int send_DATA(uint32_t connection_id) | |||
449 | { | 393 | { |
450 | int ret; | 394 | int ret; |
451 | uint32_t buffer[BUFFER_PACKET_NUM]; | 395 | uint32_t buffer[BUFFER_PACKET_NUM]; |
452 | if(connections[connection_id].num_req_paquets > 0) | 396 | if(connections[connection_id].num_req_paquets > 0) { |
453 | { | ||
454 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); | 397 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); |
455 | connections[connection_id].num_req_paquets--; | 398 | connections[connection_id].num_req_paquets--; |
456 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); | 399 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); |
457 | memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); | 400 | memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); |
458 | return ret; | 401 | return ret; |
459 | } | 402 | } |
460 | if(connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) | 403 | if(connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { |
461 | { | ||
462 | ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); | 404 | ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); |
463 | connections[connection_id].sent_packetnum++; | 405 | connections[connection_id].sent_packetnum++; |
464 | return ret; | 406 | return ret; |
@@ -468,17 +410,13 @@ int send_DATA(uint32_t connection_id) | |||
468 | 410 | ||
469 | /* END of packet sending functions */ | 411 | /* END of packet sending functions */ |
470 | 412 | ||
471 | |||
472 | |||
473 | /* Packet handling functions | 413 | /* Packet handling functions |
474 | One to handle each type of packets we receive | 414 | One to handle each type of packets we receive |
475 | return 0 if handled correctly, 1 if packet is bad. */ | 415 | return 0 if handled correctly, 1 if packet is bad. */ |
476 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 416 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) |
477 | { | 417 | { |
478 | if(length != (1 + 4 + 4)) | 418 | if(length != (1 + 4 + 4)) |
479 | { | ||
480 | return 1; | 419 | return 1; |
481 | } | ||
482 | uint32_t temp; | 420 | uint32_t temp; |
483 | uint32_t handshake_id1, handshake_id2; | 421 | uint32_t handshake_id1, handshake_id2; |
484 | int connection = getconnection_id(source); | 422 | int connection = getconnection_id(source); |
@@ -487,17 +425,13 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | |||
487 | memcpy(&temp, packet + 5, 4); | 425 | memcpy(&temp, packet + 5, 4); |
488 | handshake_id2 = ntohl(temp); | 426 | handshake_id2 = ntohl(temp); |
489 | 427 | ||
490 | if(handshake_id2 == 0) | 428 | if(handshake_id2 == 0) { |
491 | { | ||
492 | send_handshake(source, handshake_id(source), handshake_id1); | 429 | send_handshake(source, handshake_id(source), handshake_id1); |
493 | return 0; | 430 | return 0; |
494 | } | 431 | } |
495 | if(is_connected(connection) != 1) | 432 | if(is_connected(connection) != 1) |
496 | { | ||
497 | return 1; | 433 | return 1; |
498 | } | 434 | if(handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */ |
499 | if(handshake_id2 == connections[connection].handshake_id1) /* if handshake_id2 is what we sent previously as handshake_id1 */ | ||
500 | { | ||
501 | connections[connection].status = 2; | 435 | connections[connection].status = 2; |
502 | /* NOTE: is this necessary? | 436 | /* NOTE: is this necessary? |
503 | connections[connection].handshake_id2 = handshake_id1; */ | 437 | connections[connection].handshake_id2 = handshake_id1; */ |
@@ -515,25 +449,19 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | |||
515 | int SYNC_valid(uint32_t length) | 449 | int SYNC_valid(uint32_t length) |
516 | { | 450 | { |
517 | if(length < 4 + 4 + 2) | 451 | if(length < 4 + 4 + 2) |
518 | { | ||
519 | return 0; | 452 | return 0; |
520 | } | ||
521 | if(length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || | 453 | if(length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || |
522 | ((length - 4 - 4 - 2) % 4) != 0) | 454 | ((length - 4 - 4 - 2) % 4) != 0) |
523 | { | ||
524 | return 0; | 455 | return 0; |
525 | } | ||
526 | return 1; | 456 | return 1; |
527 | } | 457 | } |
528 | 458 | ||
529 | /* case 1: */ | 459 | /* case 1: */ |
530 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 460 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) |
531 | { | 461 | { |
532 | if(handshake_id(source) == recv_packetnum) | 462 | if(handshake_id(source) == recv_packetnum) { |
533 | { | ||
534 | int x = new_inconnection(source); | 463 | int x = new_inconnection(source); |
535 | if(x != -1) | 464 | if(x != -1) { |
536 | { | ||
537 | connections[x].orecv_packetnum = recv_packetnum; | 465 | connections[x].orecv_packetnum = recv_packetnum; |
538 | connections[x].sent_packetnum = recv_packetnum; | 466 | connections[x].sent_packetnum = recv_packetnum; |
539 | connections[x].sendbuff_packetnum = recv_packetnum; | 467 | connections[x].sendbuff_packetnum = recv_packetnum; |
@@ -551,9 +479,8 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
551 | /* case 2: */ | 479 | /* case 2: */ |
552 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 480 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
553 | { | 481 | { |
554 | if(recv_packetnum == connections[connection_id].orecv_packetnum) | 482 | if(recv_packetnum == connections[connection_id].orecv_packetnum) { |
555 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ | 483 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ |
556 | { | ||
557 | connections[connection_id].status = 3; | 484 | connections[connection_id].status = 3; |
558 | connections[connection_id].recv_counter = counter; | 485 | connections[connection_id].recv_counter = counter; |
559 | ++connections[connection_id].send_counter; | 486 | ++connections[connection_id].send_counter; |
@@ -572,16 +499,14 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
572 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ | 499 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ |
573 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); | 500 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); |
574 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); | 501 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); |
575 | if(comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) /* packet valid */ | 502 | if(comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */ |
576 | { | ||
577 | connections[connection_id].orecv_packetnum = recv_packetnum; | 503 | connections[connection_id].orecv_packetnum = recv_packetnum; |
578 | connections[connection_id].osent_packetnum = sent_packetnum; | 504 | connections[connection_id].osent_packetnum = sent_packetnum; |
579 | connections[connection_id].successful_sent = recv_packetnum; | 505 | connections[connection_id].successful_sent = recv_packetnum; |
580 | connections[connection_id].last_recvSYNC = current_time(); | 506 | connections[connection_id].last_recvSYNC = current_time(); |
581 | connections[connection_id].recv_counter = counter; | 507 | connections[connection_id].recv_counter = counter; |
582 | ++connections[connection_id].send_counter; | 508 | ++connections[connection_id].send_counter; |
583 | for(i = 0; i < number; ++i) | 509 | for(i = 0; i < number; ++i) { |
584 | { | ||
585 | temp = ntohl(req_packets[i]); | 510 | temp = ntohl(req_packets[i]); |
586 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); | 511 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); |
587 | } | 512 | } |
@@ -595,9 +520,7 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source) | |||
595 | { | 520 | { |
596 | 521 | ||
597 | if(!SYNC_valid(length)) | 522 | if(!SYNC_valid(length)) |
598 | { | ||
599 | return 1; | 523 | return 1; |
600 | } | ||
601 | int connection = getconnection_id(source); | 524 | int connection = getconnection_id(source); |
602 | uint8_t counter; | 525 | uint8_t counter; |
603 | uint32_t temp; | 526 | uint32_t temp; |
@@ -611,21 +534,13 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source) | |||
611 | memcpy(&temp,packet + 6, 4); | 534 | memcpy(&temp,packet + 6, 4); |
612 | sent_packetnum = ntohl(temp); | 535 | sent_packetnum = ntohl(temp); |
613 | if(number != 0) | 536 | if(number != 0) |
614 | { | ||
615 | memcpy(req_packets, packet + 10, 4 * number); | 537 | memcpy(req_packets, packet + 10, 4 * number); |
616 | } | ||
617 | if(connection == -1) | 538 | if(connection == -1) |
618 | { | ||
619 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); | 539 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); |
620 | } | ||
621 | if(connections[connection].status == 2) | 540 | if(connections[connection].status == 2) |
622 | { | ||
623 | return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); | 541 | return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); |
624 | } | ||
625 | if(connections[connection].status == 3) | 542 | if(connections[connection].status == 3) |
626 | { | ||
627 | return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); | 543 | return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); |
628 | } | ||
629 | return 0; | 544 | return 0; |
630 | } | 545 | } |
631 | 546 | ||
@@ -634,37 +549,26 @@ int handle_SYNC(uint8_t * packet, uint32_t length, IP_Port source) | |||
634 | int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size) | 549 | int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size) |
635 | { | 550 | { |
636 | if(size > MAX_DATA_SIZE) | 551 | if(size > MAX_DATA_SIZE) |
637 | { | ||
638 | return 1; | 552 | return 1; |
639 | } | ||
640 | 553 | ||
641 | uint32_t i; | 554 | uint32_t i; |
642 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 555 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
643 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 556 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; |
644 | for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) | 557 | for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
645 | { | 558 | if(i == data_num) { |
646 | if(i == data_num) | ||
647 | { | ||
648 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 559 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
649 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 560 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
650 | connections[connection_id].last_recvdata = current_time(); | 561 | connections[connection_id].last_recvdata = current_time(); |
651 | if(sent_packet < BUFFER_PACKET_NUM) | 562 | if(sent_packet < BUFFER_PACKET_NUM) |
652 | { | ||
653 | connections[connection_id].osent_packetnum = data_num; | 563 | connections[connection_id].osent_packetnum = data_num; |
654 | } | ||
655 | break; | 564 | break; |
656 | } | 565 | } |
657 | } | 566 | } |
658 | for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) | 567 | for(i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
659 | { | ||
660 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 568 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
661 | { | ||
662 | connections[connection_id].recv_packetnum = i; | 569 | connections[connection_id].recv_packetnum = i; |
663 | } | ||
664 | else | 570 | else |
665 | { | ||
666 | break; | 571 | break; |
667 | } | ||
668 | } | 572 | } |
669 | 573 | ||
670 | return 0; | 574 | return 0; |
@@ -673,54 +577,43 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size | |||
673 | int handle_data(uint8_t * packet, uint32_t length, IP_Port source) | 577 | int handle_data(uint8_t * packet, uint32_t length, IP_Port source) |
674 | { | 578 | { |
675 | int connection = getconnection_id(source); | 579 | int connection = getconnection_id(source); |
676 | 580 | ||
677 | if(connection == -1) | 581 | if(connection == -1) |
678 | { | ||
679 | return 1; | 582 | return 1; |
680 | } | 583 | |
681 | |||
682 | if(connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ | 584 | if(connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ |
683 | { | ||
684 | return 1; | 585 | return 1; |
685 | } | 586 | |
686 | |||
687 | if(length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) | 587 | if(length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) |
688 | { | ||
689 | return 1; | 588 | return 1; |
690 | } | ||
691 | uint32_t temp; | 589 | uint32_t temp; |
692 | uint32_t number; | 590 | uint32_t number; |
693 | uint16_t size = length - 1 - 4; | 591 | uint16_t size = length - 1 - 4; |
694 | 592 | ||
695 | memcpy(&temp, packet + 1, 4); | 593 | memcpy(&temp, packet + 1, 4); |
696 | number = ntohl(temp); | 594 | number = ntohl(temp); |
697 | return add_recv(connection, number, packet + 5, size); | 595 | return add_recv(connection, number, packet + 5, size); |
698 | |||
699 | } | 596 | } |
700 | 597 | ||
701 | /* END of packet handling functions */ | 598 | /* END of packet handling functions */ |
702 | 599 | ||
703 | |||
704 | int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | 600 | int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) |
705 | { | 601 | { |
706 | |||
707 | switch (packet[0]) { | 602 | switch (packet[0]) { |
708 | case 16: | 603 | case 16: |
709 | return handle_handshake(packet, length, source); | 604 | return handle_handshake(packet, length, source); |
710 | 605 | ||
711 | case 17: | 606 | case 17: |
712 | return handle_SYNC(packet, length, source); | 607 | return handle_SYNC(packet, length, source); |
713 | 608 | ||
714 | case 18: | 609 | case 18: |
715 | return handle_data(packet, length, source); | 610 | return handle_data(packet, length, source); |
716 | 611 | ||
717 | default: | 612 | default: |
718 | return 1; | 613 | return 1; |
719 | |||
720 | } | 614 | } |
721 | 615 | ||
722 | return 0; | 616 | return 0; |
723 | |||
724 | } | 617 | } |
725 | 618 | ||
726 | /* Send handshake requests | 619 | /* Send handshake requests |
@@ -729,28 +622,20 @@ void doNew() | |||
729 | { | 622 | { |
730 | uint32_t i; | 623 | uint32_t i; |
731 | uint64_t temp_time = current_time(); | 624 | uint64_t temp_time = current_time(); |
732 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 625 | for(i = 0; i < MAX_CONNECTIONS; ++i) { |
733 | { | ||
734 | if(connections[i].status == 1) | 626 | if(connections[i].status == 1) |
735 | { | 627 | if((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { |
736 | if((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) | ||
737 | { | ||
738 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); | 628 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); |
739 | connections[i].last_sent = temp_time; | 629 | connections[i].last_sent = temp_time; |
740 | } | 630 | } |
741 | 631 | ||
742 | } | ||
743 | /* kill all timed out connections */ | 632 | /* kill all timed out connections */ |
744 | if( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 633 | if( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && |
745 | connections[i].status != 4) | 634 | connections[i].status != 4) |
746 | { | ||
747 | /* kill_connection(i); */ | 635 | /* kill_connection(i); */ |
748 | connections[i].status = 4; | 636 | connections[i].status = 4; |
749 | } | ||
750 | if(connections[i].status > 0 && connections[i].killat < temp_time) | 637 | if(connections[i].status > 0 && connections[i].killat < temp_time) |
751 | { | ||
752 | kill_connection(i); | 638 | kill_connection(i); |
753 | } | ||
754 | } | 639 | } |
755 | } | 640 | } |
756 | 641 | ||
@@ -758,16 +643,12 @@ void doSYNC() | |||
758 | { | 643 | { |
759 | uint32_t i; | 644 | uint32_t i; |
760 | uint64_t temp_time = current_time(); | 645 | uint64_t temp_time = current_time(); |
761 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 646 | for(i = 0; i < MAX_CONNECTIONS; ++i) { |
762 | { | ||
763 | if(connections[i].status == 2 || connections[i].status == 3) | 647 | if(connections[i].status == 2 || connections[i].status == 3) |
764 | { | 648 | if((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { |
765 | if((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) | ||
766 | { | ||
767 | send_SYNC(i); | 649 | send_SYNC(i); |
768 | connections[i].last_SYNC = temp_time; | 650 | connections[i].last_SYNC = temp_time; |
769 | } | 651 | } |
770 | } | ||
771 | } | 652 | } |
772 | } | 653 | } |
773 | 654 | ||
@@ -777,19 +658,12 @@ void doData() | |||
777 | uint64_t j; | 658 | uint64_t j; |
778 | uint64_t temp_time = current_time(); | 659 | uint64_t temp_time = current_time(); |
779 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 660 | for(i = 0; i < MAX_CONNECTIONS; ++i) |
780 | { | ||
781 | if(connections[i].status == 3 && sendqueue(i) != 0) | 661 | if(connections[i].status == 3 && sendqueue(i) != 0) |
782 | { | 662 | if((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) { |
783 | if((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) | ||
784 | { | ||
785 | for(j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) | 663 | for(j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) |
786 | { | ||
787 | send_DATA(i); | 664 | send_DATA(i); |
788 | } | ||
789 | connections[i].last_sent = temp_time; | 665 | connections[i].last_sent = temp_time; |
790 | } | 666 | } |
791 | } | ||
792 | } | ||
793 | } | 667 | } |
794 | 668 | ||
795 | /* TODO: flow control. | 669 | /* TODO: flow control. |
@@ -801,33 +675,22 @@ void adjustRates() | |||
801 | { | 675 | { |
802 | uint32_t i; | 676 | uint32_t i; |
803 | uint64_t temp_time = current_time(); | 677 | uint64_t temp_time = current_time(); |
804 | for(i = 0; i < MAX_CONNECTIONS; ++i) | 678 | for(i = 0; i < MAX_CONNECTIONS; ++i) { |
805 | { | ||
806 | if(connections[i].status == 1 || connections[i].status == 2) | 679 | if(connections[i].status == 1 || connections[i].status == 2) |
807 | { | ||
808 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 680 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
809 | } | 681 | if(connections[i].status == 3) { |
810 | if(connections[i].status == 3) | 682 | if(sendqueue(i) != 0) { |
811 | { | ||
812 | if(sendqueue(i) != 0) | ||
813 | { | ||
814 | |||
815 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; | 683 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; |
816 | |||
817 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 684 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
818 | |||
819 | } | 685 | } |
820 | else if(connections[i].last_recvdata + 1000000UL > temp_time) | 686 | else if(connections[i].last_recvdata + 1000000UL > temp_time) |
821 | { | ||
822 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 687 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
823 | } | ||
824 | else | 688 | else |
825 | { | ||
826 | connections[i].SYNC_rate = SYNC_RATE; | 689 | connections[i].SYNC_rate = SYNC_RATE; |
827 | } | ||
828 | } | 690 | } |
829 | } | 691 | } |
830 | } | 692 | } |
693 | |||
831 | /* Call this function a couple times per second | 694 | /* Call this function a couple times per second |
832 | It's the main loop. */ | 695 | It's the main loop. */ |
833 | void doLossless_UDP() | 696 | void doLossless_UDP() |
@@ -836,6 +699,4 @@ void doLossless_UDP() | |||
836 | doSYNC(); | 699 | doSYNC(); |
837 | doData(); | 700 | doData(); |
838 | adjustRates(); | 701 | adjustRates(); |
839 | |||
840 | |||
841 | } | 702 | } |