summaryrefslogtreecommitdiff
path: root/core/Lossless_UDP.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/Lossless_UDP.c')
-rw-r--r--core/Lossless_UDP.c281
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
94static Connection connections[MAX_CONNECTIONS]; 91static 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. */
118static uint32_t randtable[6][256]; 111static 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 */
124uint32_t handshake_id(IP_Port source) 116uint32_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 */
143void change_handshake(IP_Port source) 131void 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)
191int new_inconnection(IP_Port ip_port) 174int 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()
239int kill_connection(int connection_id) 215int 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)
256int kill_connection_in(int connection_id, uint32_t seconds) 229int 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)
275int is_connected(int connection_id) 245int 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)
285IP_Port connection_ip(int connection_id) 253IP_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)
309char id_packet(int connection_id) 275char 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 */
319int read_packet(int connection_id, uint8_t * data) 284int 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)
335int write_packet(int connection_id, uint8_t * data, uint32_t length) 299int 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 */
360uint32_t missing_packets(int connection_id, uint32_t * requested) 316uint32_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
391int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) 337int 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
406int send_SYNC(uint32_t connection_id) 350int 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
433int send_data_packet(uint32_t connection_id, uint32_t packet_num) 377int 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. */
476int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) 416int 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)
515int SYNC_valid(uint32_t length) 449int 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: */
530int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) 460int 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: */
552int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 480int 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)
634int add_recv(int connection_id, uint32_t data_num, uint8_t * data, uint16_t size) 549int 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
673int handle_data(uint8_t * packet, uint32_t length, IP_Port source) 577int 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
704int LosslessUDP_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) 600int 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. */
833void doLossless_UDP() 696void 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}