diff options
Diffstat (limited to 'core/Lossless_UDP.c')
-rw-r--r-- | core/Lossless_UDP.c | 251 |
1 files changed, 195 insertions, 56 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index 7ef818e8..82a0493f 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -2,18 +2,38 @@ | |||
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 | |||
6 | Copyright (C) 2013 Tox project All Rights Reserved. | ||
7 | |||
8 | This file is part of Tox. | ||
9 | |||
10 | Tox is free software: you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation, either version 3 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | Tox is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
22 | |||
5 | */ | 23 | */ |
6 | 24 | ||
7 | #include "Lossless_UDP.h" | 25 | #include "Lossless_UDP.h" |
8 | 26 | ||
27 | |||
28 | |||
9 | //maximum data packets in sent and recieve queues. | 29 | //maximum data packets in sent and recieve queues. |
10 | #define MAX_QUEUE_NUM 32 | 30 | #define MAX_QUEUE_NUM 32 |
11 | 31 | ||
12 | //maximum length of the data in the data packets | 32 | //maximum length of the data in the data packets |
13 | #define PDATA_SIZE 1024 | 33 | #define MAX_DATA_SIZE 1024 |
14 | 34 | ||
15 | //maximum number of data packets that can be sent/recieved at the same time | 35 | //maximum number of data packets in the buffer |
16 | #define MAX_PACKET_NUM (MAX_QUEUE_NUM/4) | 36 | #define BUFFER_PACKET_NUM MAX_QUEUE_NUM |
17 | 37 | ||
18 | //Lossless UDP connection timeout. | 38 | //Lossless UDP connection timeout. |
19 | #define CONNEXION_TIMEOUT 10 | 39 | #define CONNEXION_TIMEOUT 10 |
@@ -21,12 +41,12 @@ | |||
21 | //initial amount of sync/hanshake packets to send per second. | 41 | //initial amount of sync/hanshake packets to send per second. |
22 | #define SYNC_RATE 5 | 42 | #define SYNC_RATE 5 |
23 | 43 | ||
24 | //send rate of sync packets when data is being sent/recieved. | 44 | //initial send rate of sync packets when data is being sent/recieved. |
25 | #define DATA_SYNC_RATE 20 | 45 | #define DATA_SYNC_RATE 20 |
26 | 46 | ||
27 | typedef struct | 47 | typedef struct |
28 | { | 48 | { |
29 | char data[PDATA_SIZE]; | 49 | char data[MAX_DATA_SIZE]; |
30 | uint16_t size; | 50 | uint16_t size; |
31 | }Data; | 51 | }Data; |
32 | 52 | ||
@@ -56,7 +76,7 @@ typedef struct | |||
56 | uint32_t sendbuff_packetnum; //number of latest packet written onto the sendbuffer | 76 | uint32_t sendbuff_packetnum; //number of latest packet written onto the sendbuffer |
57 | uint32_t successful_sent;//we know all packets before that number were successfully sent | 77 | uint32_t successful_sent;//we know all packets before that number were successfully sent |
58 | uint32_t successful_read;//packet number of last packet read with the read_packet function | 78 | uint32_t successful_read;//packet number of last packet read with the read_packet function |
59 | uint32_t req_packets[MAX_PACKET_NUM]; //list of currently requested packet numbers(by the other person) | 79 | uint32_t req_packets[BUFFER_PACKET_NUM]; //list of currently requested packet numbers(by the other person) |
60 | uint16_t num_req_paquets; //total number of currently requested packets(by the other person) | 80 | uint16_t num_req_paquets; //total number of currently requested packets(by the other person) |
61 | uint8_t recv_counter; | 81 | uint8_t recv_counter; |
62 | uint8_t send_counter; | 82 | uint8_t send_counter; |
@@ -83,6 +103,9 @@ int new_connection(IP_Port ip_port) | |||
83 | connections[i].status = 1; | 103 | connections[i].status = 1; |
84 | connections[i].inbound = 0; | 104 | connections[i].inbound = 0; |
85 | connections[i].handshake_id1 = random_int(); | 105 | connections[i].handshake_id1 = random_int(); |
106 | connections[i].sent_packetnum = connections[i].handshake_id1; | ||
107 | connections[i].sendbuff_packetnum = connections[i].handshake_id1; | ||
108 | connections[i].successful_sent = connections[i].handshake_id1; | ||
86 | connections[i].SYNC_rate = SYNC_RATE; | 109 | connections[i].SYNC_rate = SYNC_RATE; |
87 | connections[i].data_rate = DATA_SYNC_RATE; | 110 | connections[i].data_rate = DATA_SYNC_RATE; |
88 | connections[i].last_recv = current_time(); | 111 | connections[i].last_recv = current_time(); |
@@ -144,11 +167,41 @@ int kill_connection(int connection_id) | |||
144 | return -1; | 167 | return -1; |
145 | } | 168 | } |
146 | 169 | ||
170 | //check if connection is connected | ||
171 | //return 0 no. | ||
172 | //return 1 if attempting handshake | ||
173 | //return 2 if handshake is done | ||
174 | //return 3 if fully connected | ||
175 | int is_connected(int connection_id) | ||
176 | { | ||
177 | return connections[connection_id].status; | ||
178 | } | ||
179 | |||
180 | //returns the number of packets in the queue waiting to be successfully sent. | ||
181 | uint32_t sendqueue(int connection_id) | ||
182 | { | ||
183 | return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; | ||
184 | } | ||
185 | |||
186 | //returns the number of packets in the queue waiting to be successfully read with read_packet(...) | ||
187 | uint32_t recvqueue(int connection_id) | ||
188 | { | ||
189 | return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; | ||
190 | } | ||
191 | |||
147 | //return 0 if there is no received data in the buffer. | 192 | //return 0 if there is no received data in the buffer. |
148 | //return length of received packet if successful | 193 | //return length of received packet if successful |
149 | int read_packet(int connection_id, char * data) | 194 | int read_packet(int connection_id, char * data) |
150 | { | 195 | { |
151 | 196 | if(recvqueue(connection_id) != 0) | |
197 | { | ||
198 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; | ||
199 | uint16_t size = connections[connection_id].recvbuffer[index].size; | ||
200 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); | ||
201 | connections[connection_id].successful_read++; | ||
202 | connections[connection_id].recvbuffer[index].size = 0; | ||
203 | return size; | ||
204 | } | ||
152 | return 0; | 205 | return 0; |
153 | } | 206 | } |
154 | 207 | ||
@@ -156,34 +209,27 @@ int read_packet(int connection_id, char * data) | |||
156 | //return 1 if data was put into the queue | 209 | //return 1 if data was put into the queue |
157 | int write_packet(int connection_id, char * data, uint32_t length) | 210 | int write_packet(int connection_id, char * data, uint32_t length) |
158 | { | 211 | { |
159 | 212 | if(length > MAX_DATA_SIZE) | |
160 | 213 | { | |
214 | return 0; | ||
215 | } | ||
216 | if(length == 0) | ||
217 | { | ||
218 | return 0; | ||
219 | } | ||
220 | if(sendqueue(connection_id) < MAX_QUEUE_NUM) | ||
221 | { | ||
222 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | ||
223 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | ||
224 | connections[connection_id].sendbuffer[index].size = length; | ||
225 | connections[connection_id].sendbuff_packetnum++; | ||
226 | return 1; | ||
227 | } | ||
161 | return 0; | 228 | return 0; |
162 | } | 229 | } |
163 | 230 | ||
164 | 231 | ||
165 | 232 | ||
166 | //returns the number of packets in the queue waiting to be successfully sent. | ||
167 | int sendqueue(int connection_id) | ||
168 | { | ||
169 | return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; | ||
170 | } | ||
171 | |||
172 | //returns the number of packets in the queue waiting to be successfully read with read_packet(...) | ||
173 | int recvqueue(int connection_id) | ||
174 | { | ||
175 | return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; | ||
176 | } | ||
177 | |||
178 | //check if connection is connected | ||
179 | //return 0 no. | ||
180 | //return 1 if attempting handshake | ||
181 | //return 2 if handshake is done | ||
182 | //return 3 if fully connected | ||
183 | int is_connected(int connection_id) | ||
184 | { | ||
185 | return connections[connection_id].status; | ||
186 | } | ||
187 | 233 | ||
188 | //put the packet numbers the we are missing in requested and return the number | 234 | //put the packet numbers the we are missing in requested and return the number |
189 | uint32_t missing_packets(int connection_id, uint32_t * requested) | 235 | uint32_t missing_packets(int connection_id, uint32_t * requested) |
@@ -194,10 +240,14 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
194 | { | 240 | { |
195 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) | 241 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) |
196 | { | 242 | { |
197 | memcpy(requested, &i, number); | 243 | memcpy(requested + number, &i, 4); |
198 | number++; | 244 | number++; |
199 | } | 245 | } |
200 | } | 246 | } |
247 | if(number == 0) | ||
248 | { | ||
249 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; | ||
250 | } | ||
201 | return number; | 251 | return number; |
202 | 252 | ||
203 | } | 253 | } |
@@ -221,14 +271,14 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i | |||
221 | int send_SYNC(uint32_t connection_id) | 271 | int send_SYNC(uint32_t connection_id) |
222 | { | 272 | { |
223 | 273 | ||
224 | char packet[(MAX_PACKET_NUM*4 + 4 + 4 + 2)]; | 274 | char packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; |
225 | uint16_t index = 0; | 275 | uint16_t index = 0; |
226 | 276 | ||
227 | IP_Port ip_port = connections[connection_id].ip_port; | 277 | IP_Port ip_port = connections[connection_id].ip_port; |
228 | uint8_t counter = connections[connection_id].send_counter; | 278 | uint8_t counter = connections[connection_id].send_counter; |
229 | uint32_t recv_packetnum = connections[connection_id].recv_packetnum; | 279 | uint32_t recv_packetnum = connections[connection_id].recv_packetnum; |
230 | uint32_t sent_packetnum = connections[connection_id].sent_packetnum; | 280 | uint32_t sent_packetnum = connections[connection_id].sent_packetnum; |
231 | uint32_t requested[MAX_PACKET_NUM]; | 281 | uint32_t requested[BUFFER_PACKET_NUM]; |
232 | uint32_t number = missing_packets(connection_id, requested); | 282 | uint32_t number = missing_packets(connection_id, requested); |
233 | 283 | ||
234 | packet[0] = 17; | 284 | packet[0] = 17; |
@@ -245,21 +295,39 @@ int send_SYNC(uint32_t connection_id) | |||
245 | 295 | ||
246 | } | 296 | } |
247 | 297 | ||
248 | 298 | int send_data_packet(uint32_t connection_id, uint32_t packet_num) | |
249 | int send_data(IP_Port ip_port, uint32_t packet_num, char * data, uint32_t length) | ||
250 | { | 299 | { |
251 | if(length > PDATA_SIZE) | 300 | uint32_t index = packet_num % MAX_QUEUE_NUM; |
252 | { | 301 | char packet[1 + 4 + MAX_DATA_SIZE]; |
253 | return -1; | ||
254 | } | ||
255 | char packet[1 + 4 + PDATA_SIZE]; | ||
256 | |||
257 | packet[0] = 18; | 302 | packet[0] = 18; |
258 | memcpy(packet + 1, &packet_num, 4); | 303 | memcpy(packet + 1, &packet_num, 4); |
259 | memcpy(packet + 5, data, length); | 304 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, |
260 | return sendpacket(ip_port, packet, 1 + 4 + length); | 305 | connections[connection_id].sendbuffer[index].size); |
306 | return sendpacket(connections[connection_id].ip_port, packet, | ||
307 | 1 + 4 + connections[connection_id].sendbuffer[index].size); | ||
261 | } | 308 | } |
262 | 309 | ||
310 | //sends 1 data packet | ||
311 | int send_DATA(uint32_t connection_id) | ||
312 | { | ||
313 | int ret; | ||
314 | uint32_t buffer[BUFFER_PACKET_NUM]; | ||
315 | if(connections[connection_id].num_req_paquets > 0) | ||
316 | { | ||
317 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); | ||
318 | connections[connection_id].num_req_paquets--; | ||
319 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); | ||
320 | memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); | ||
321 | return ret; | ||
322 | } | ||
323 | if(connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) | ||
324 | { | ||
325 | ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); | ||
326 | connections[connection_id].sent_packetnum++; | ||
327 | return ret; | ||
328 | } | ||
329 | return 0; | ||
330 | } | ||
263 | 331 | ||
264 | //END of packet sending functions | 332 | //END of packet sending functions |
265 | 333 | ||
@@ -281,7 +349,7 @@ int getconnection_id(IP_Port ip_port) | |||
281 | } | 349 | } |
282 | 350 | ||
283 | //table of random numbers used below. | 351 | //table of random numbers used below. |
284 | uint32_t randtable[6][256]; | 352 | static uint32_t randtable[6][256]; |
285 | 353 | ||
286 | 354 | ||
287 | //generate a handshake_id which depends on the ip_port. | 355 | //generate a handshake_id which depends on the ip_port. |
@@ -333,9 +401,9 @@ int handle_handshake(char * packet, uint32_t length, IP_Port source) | |||
333 | //NOTE:is this necessary? | 401 | //NOTE:is this necessary? |
334 | //connections[connection].handshake_id2 = handshake_id2; | 402 | //connections[connection].handshake_id2 = handshake_id2; |
335 | connections[connection].orecv_packetnum = handshake_id1; | 403 | connections[connection].orecv_packetnum = handshake_id1; |
336 | connections[connection].sent_packetnum = handshake_id1; | ||
337 | connections[connection].osent_packetnum = handshake_id2; | 404 | connections[connection].osent_packetnum = handshake_id2; |
338 | connections[connection].recv_packetnum = handshake_id2; | 405 | connections[connection].recv_packetnum = handshake_id2; |
406 | connections[connection].successful_read = handshake_id2; | ||
339 | } | 407 | } |
340 | return 0; | 408 | return 0; |
341 | 409 | ||
@@ -349,7 +417,7 @@ int SYNC_valid(uint32_t length) | |||
349 | { | 417 | { |
350 | return 0; | 418 | return 0; |
351 | } | 419 | } |
352 | if(length > (MAX_PACKET_NUM*4 + 4 + 4 + 2) || | 420 | if(length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || |
353 | ((length - 4 - 4 - 2) % 4) != 0) | 421 | ((length - 4 - 4 - 2) % 4) != 0) |
354 | { | 422 | { |
355 | return 0; | 423 | return 0; |
@@ -367,9 +435,12 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
367 | { | 435 | { |
368 | connections[x].orecv_packetnum = recv_packetnum; | 436 | connections[x].orecv_packetnum = recv_packetnum; |
369 | connections[x].sent_packetnum = recv_packetnum; | 437 | connections[x].sent_packetnum = recv_packetnum; |
438 | connections[x].sendbuff_packetnum = recv_packetnum; | ||
439 | connections[x].successful_sent = recv_packetnum; | ||
370 | connections[x].osent_packetnum = sent_packetnum; | 440 | connections[x].osent_packetnum = sent_packetnum; |
371 | connections[x].recv_packetnum = sent_packetnum; | 441 | connections[x].recv_packetnum = sent_packetnum; |
372 | 442 | connections[x].successful_read = sent_packetnum; | |
443 | |||
373 | return x; | 444 | return x; |
374 | } | 445 | } |
375 | } | 446 | } |
@@ -379,26 +450,28 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
379 | //case 2: | 450 | //case 2: |
380 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 451 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
381 | { | 452 | { |
382 | if(recv_packetnum == connections[connection_id].orecv_packetnum && | 453 | if(recv_packetnum == connections[connection_id].orecv_packetnum) |
383 | sent_packetnum == connections[connection_id].osent_packetnum) | 454 | //&& sent_packetnum == connections[connection_id].osent_packetnum) |
384 | { | 455 | { |
385 | connections[connection_id].status = 3; | 456 | connections[connection_id].status = 3; |
386 | connections[connection_id].recv_counter = counter; | 457 | connections[connection_id].recv_counter = counter; |
387 | connections[connection_id].send_counter++; | 458 | connections[connection_id].send_counter++; |
388 | return 0; | 459 | return 0; |
389 | } | 460 | } |
461 | return 1; | ||
390 | } | 462 | } |
391 | //case 3: | 463 | //case 3: |
392 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, | 464 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, |
393 | uint16_t number) | 465 | uint16_t number) |
394 | { | 466 | { |
395 | uint8_t comp_counter = (connections[connection_id].recv_counter + 1); | 467 | uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); |
396 | if((recv_packetnum - connections[connection_id].orecv_packetnum) < MAX_PACKET_NUM && | 468 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); |
397 | (sent_packetnum - connections[connection_id].osent_packetnum) < MAX_PACKET_NUM && | 469 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); |
398 | counter == comp_counter) //packet valid | 470 | if(comp_1 < BUFFER_PACKET_NUM && comp_2 < BUFFER_PACKET_NUM && comp_counter < 10) //packet valid |
399 | { | 471 | { |
400 | connections[connection_id].orecv_packetnum = recv_packetnum; | 472 | connections[connection_id].orecv_packetnum = recv_packetnum; |
401 | connections[connection_id].osent_packetnum = sent_packetnum; | 473 | connections[connection_id].osent_packetnum = sent_packetnum; |
474 | connections[connection_id].successful_sent = recv_packetnum; | ||
402 | connections[connection_id].last_recv = current_time(); | 475 | connections[connection_id].last_recv = current_time(); |
403 | connections[connection_id].recv_counter = counter; | 476 | connections[connection_id].recv_counter = counter; |
404 | connections[connection_id].send_counter++; | 477 | connections[connection_id].send_counter++; |
@@ -419,7 +492,7 @@ int handle_SYNC(char * packet, uint32_t length, IP_Port source) | |||
419 | int connection = getconnection_id(source); | 492 | int connection = getconnection_id(source); |
420 | uint8_t counter; | 493 | uint8_t counter; |
421 | uint32_t recv_packetnum, sent_packetnum; | 494 | uint32_t recv_packetnum, sent_packetnum; |
422 | uint32_t req_packets[MAX_PACKET_NUM]; | 495 | uint32_t req_packets[BUFFER_PACKET_NUM]; |
423 | uint16_t number = (length - 4 - 4 - 2)/ 4; | 496 | uint16_t number = (length - 4 - 4 - 2)/ 4; |
424 | 497 | ||
425 | memcpy(&counter, packet + 1, 1); | 498 | memcpy(&counter, packet + 1, 1); |
@@ -446,8 +519,63 @@ int handle_SYNC(char * packet, uint32_t length, IP_Port source) | |||
446 | return 0; | 519 | return 0; |
447 | } | 520 | } |
448 | 521 | ||
522 | //add a packet to the recieved buffer and set the recv_packetnum of the connection to its proper value. | ||
523 | //return 1 if data was too big, 0 if not. | ||
524 | int add_recv(int connection_id, uint32_t data_num, char * data, uint16_t size) | ||
525 | { | ||
526 | if(size > MAX_DATA_SIZE) | ||
527 | { | ||
528 | return 1; | ||
529 | } | ||
530 | |||
531 | uint32_t i; | ||
532 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | ||
533 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | ||
534 | for(i = connections[connection_id].recv_packetnum; i != maxnum; i++) | ||
535 | { | ||
536 | if(i == data_num) | ||
537 | { | ||
538 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | ||
539 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | ||
540 | if(sent_packet < BUFFER_PACKET_NUM) | ||
541 | { | ||
542 | connections[connection_id].osent_packetnum = data_num; | ||
543 | } | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | for(i = connections[connection_id].recv_packetnum; i != maxnum; i++) | ||
548 | { | ||
549 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | ||
550 | { | ||
551 | connections[connection_id].recv_packetnum = i; | ||
552 | } | ||
553 | else | ||
554 | { | ||
555 | break; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
449 | int handle_data(char * packet, uint32_t length, IP_Port source) | 562 | int handle_data(char * packet, uint32_t length, IP_Port source) |
450 | { | 563 | { |
564 | int connection = getconnection_id(source); | ||
565 | |||
566 | if(connection == -1) | ||
567 | { | ||
568 | return 1; | ||
569 | } | ||
570 | if(length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) | ||
571 | { | ||
572 | return 1; | ||
573 | } | ||
574 | uint32_t number; | ||
575 | uint16_t size = length - 1 - 4; | ||
576 | |||
577 | memcpy(&number, packet + 1, 4); | ||
578 | return add_recv(connection, number, packet + 5, size); | ||
451 | 579 | ||
452 | } | 580 | } |
453 | 581 | ||
@@ -477,7 +605,6 @@ int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source) | |||
477 | } | 605 | } |
478 | 606 | ||
479 | //Send handshake requests | 607 | //Send handshake requests |
480 | //TODO: optimize this. | ||
481 | //handshake packets are sent at the same rate as SYNC packets | 608 | //handshake packets are sent at the same rate as SYNC packets |
482 | void doNew() | 609 | void doNew() |
483 | { | 610 | { |
@@ -521,7 +648,19 @@ void doSYNC() | |||
521 | 648 | ||
522 | void doData() | 649 | void doData() |
523 | { | 650 | { |
524 | 651 | uint32_t i; | |
652 | uint64_t temp_time = current_time(); | ||
653 | for(i = 0; i < MAX_CONNECTIONS; i++) | ||
654 | { | ||
655 | if(connections[i].status == 3) | ||
656 | { | ||
657 | if((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) | ||
658 | { | ||
659 | send_DATA(i); | ||
660 | connections[i].last_sent = temp_time; | ||
661 | } | ||
662 | } | ||
663 | } | ||
525 | } | 664 | } |
526 | 665 | ||
527 | //TODO: flow control. | 666 | //TODO: flow control. |