summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Lossless_UDP.c251
-rw-r--r--core/Lossless_UDP.h23
-rw-r--r--testing/Lossless_UDP_testclient.c42
-rw-r--r--testing/Lossless_UDP_testserver.c37
4 files changed, 260 insertions, 93 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
27typedef struct 47typedef 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
175int 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.
181uint32_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(...)
187uint32_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
149int read_packet(int connection_id, char * data) 194int 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
157int write_packet(int connection_id, char * data, uint32_t length) 210int 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.
167int 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(...)
173int 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
183int 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
189uint32_t missing_packets(int connection_id, uint32_t * requested) 235uint32_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
221int send_SYNC(uint32_t connection_id) 271int 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 298int send_data_packet(uint32_t connection_id, uint32_t packet_num)
249int 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
311int 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.
284uint32_t randtable[6][256]; 352static 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:
380int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 451int 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:
392int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, 464int 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.
524int 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
449int handle_data(char * packet, uint32_t length, IP_Port source) 562int 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
482void doNew() 609void doNew()
483{ 610{
@@ -521,7 +648,19 @@ void doSYNC()
521 648
522void doData() 649void 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.
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index f8021f5a..8f5503ea 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -2,7 +2,26 @@
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*/
24
6#ifndef LOSSLESS_UDP_H 25#ifndef LOSSLESS_UDP_H
7#define LOSSLESS_UDP_H 26#define LOSSLESS_UDP_H
8 27
@@ -33,10 +52,10 @@ int read_packet(int connection_id, char * data);
33int write_packet(int connection_id, char * data, uint32_t length); 52int write_packet(int connection_id, char * data, uint32_t length);
34 53
35//returns the number of packets in the queue waiting to be successfully sent. 54//returns the number of packets in the queue waiting to be successfully sent.
36int sendqueue(int connection_id); 55uint32_t sendqueue(int connection_id);
37 56
38//returns the number of packets in the queue waiting to be successfully read with read_packet(...) 57//returns the number of packets in the queue waiting to be successfully read with read_packet(...)
39int recvqueue(int connection_id); 58uint32_t recvqueue(int connection_id);
40 59
41//check if connection is connected 60//check if connection is connected
42//return 0 no. 61//return 0 no.
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c
index 20fae86f..5790ad3b 100644
--- a/testing/Lossless_UDP_testclient.c
+++ b/testing/Lossless_UDP_testclient.c
@@ -1,5 +1,6 @@
1/* Lossless_UDP testclient 1/* Lossless_UDP testclient
2 * A program that connects and sends a file using our lossless UDP algorithm. 2 * A program that connects and sends a file using our lossless UDP algorithm.
3 * NOTE: this program simulates a 33% packet loss.
3 * 4 *
4 * Best used in combination with Lossless_UDP_testserver 5 * Best used in combination with Lossless_UDP_testserver
5 * 6 *
@@ -44,7 +45,7 @@ void printip(IP_Port ip_port)
44{ 45{
45 printf("\nIP: %u.%u.%u.%u Port: %u",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); 46 printf("\nIP: %u.%u.%u.%u Port: %u",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
46} 47}
47 48/*
48void printpackets(Data test) 49void printpackets(Data test)
49{ 50{
50 int i; 51 int i;
@@ -80,14 +81,14 @@ void printconnection(int connection_id)
80 } 81 }
81 Data sendbuffer[MAX_QUEUE_NUM]; 82 Data sendbuffer[MAX_QUEUE_NUM];
82 Data recvbuffer[MAX_QUEUE_NUM]; 83 Data recvbuffer[MAX_QUEUE_NUM];
83 printf("recv_num: %u, recv_sync: %u, sent_packetnum %u, send_packetnum: %u, successful_sent: %u, successful_read: %u\n", 84 printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
84 connections[connection_id].recv_packetnum, 85 connections[connection_id].recv_packetnum,
85 connections[connection_id].recv_packetnum_sync, connections[connection_id].sent_packetnum, connections[connection_id].send_packetnum, 86 connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
86 connections[connection_id].successful_sent, 87 connections[connection_id].successful_sent,
87 connections[connection_id].successful_read); 88 connections[connection_id].successful_read);
88 89
89 printf("req packets: \n"); 90 printf("req packets: \n");
90 for(i = 0; i < MAX_PACKET_NUM; i++) 91 for(i = 0; i < BUFFER_PACKET_NUM; i++)
91 { 92 {
92 printf(" %u ", connections[connection_id].req_packets[i]); 93 printf(" %u ", connections[connection_id].req_packets[i]);
93 } 94 }
@@ -97,7 +98,7 @@ void printconnection(int connection_id)
97 printf("--------------------END---------------------\n"); 98 printf("--------------------END---------------------\n");
98 99
99} 100}
100 101*/
101//recieve packets and send them to the packethandler 102//recieve packets and send them to the packethandler
102//run doLossless_UDP(); 103//run doLossless_UDP();
103void Lossless_UDP() 104void Lossless_UDP()
@@ -107,18 +108,19 @@ void Lossless_UDP()
107 uint32_t length; 108 uint32_t length;
108 while(recievepacket(&ip_port, data, &length) != -1) 109 while(recievepacket(&ip_port, data, &length) != -1)
109 { 110 {
111 printf("packet with length: %u\n", length);
110 if(rand() % 3 != 1)//add packet loss 112 if(rand() % 3 != 1)//add packet loss
111 113 {
112 if(LosslessUDP_handlepacket(data, length, ip_port)) 114 if(LosslessUDP_handlepacket(data, length, ip_port))
113 { 115 {
114 printpacket(data, length, ip_port); 116 printpacket(data, length, ip_port);
115 } 117 }
116 else 118 else
117 { 119 {
118 //printconnection(0); 120 //printconnection(0);
119 printf("Received handled packet with length: %u\n", length); 121 printf("Received handled packet with length: %u\n", length);
122 }
120 } 123 }
121
122 } 124 }
123 125
124 doLossless_UDP(); 126 doLossless_UDP();
@@ -155,6 +157,7 @@ int main(int argc, char *argv[])
155 uint64_t timer = current_time(); 157 uint64_t timer = current_time();
156 while(1) 158 while(1)
157 { 159 {
160 // printconnection(connection);
158 Lossless_UDP(); 161 Lossless_UDP();
159 if(is_connected(connection) == 3) 162 if(is_connected(connection) == 3)
160 { 163 {
@@ -166,27 +169,28 @@ int main(int argc, char *argv[])
166 printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer)); 169 printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
167 return 1; 170 return 1;
168 } 171 }
169 c_sleep(100); 172 c_sleep(1);
170 } 173 }
171 timer = current_time(); 174 timer = current_time();
172 175
173 176
174 //read first part of file 177 //read first part of file
175 read = fread(buffer, 1, 1, file); 178 read = fread(buffer, 1, 128, file);
176 179
177 while(1) 180 while(1)
178 { 181 {
179 //printconnection(connection); 182 //printconnection(connection);
180 Lossless_UDP(); 183 Lossless_UDP();
181
182 if(is_connected(connection) == 3) 184 if(is_connected(connection) == 3)
183 { 185 {
184 186
185 if(write_packet(connection, buffer, read)) 187 if(write_packet(connection, buffer, read))
186 { 188 {
187 //printf("Wrote data.\n"); 189 //printf("Wrote data.\n");
188 read = fread(buffer, 1, 1, file); 190 read = fread(buffer, 1, 128, file);
191
189 } 192 }
193 //printf("%u\n", sendqueue(connection));
190 if(sendqueue(connection) == 0) 194 if(sendqueue(connection) == 0)
191 { 195 {
192 if(read == 0) 196 if(read == 0)
@@ -201,7 +205,7 @@ int main(int argc, char *argv[])
201 printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); 205 printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
202 return 0; 206 return 0;
203 } 207 }
204 c_sleep(50); 208 c_sleep(1);
205 } 209 }
206 210
207 return 0; 211 return 0;
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c
index 9a180cbb..5370da9e 100644
--- a/testing/Lossless_UDP_testserver.c
+++ b/testing/Lossless_UDP_testserver.c
@@ -1,5 +1,6 @@
1/* Lossless_UDP testserver 1/* Lossless_UDP testserver
2 * A program that waits for a lossless UDP connection and then saves all the data recieved to a file. 2 * A program that waits for a lossless UDP connection and then saves all the data recieved to a file.
3 * NOTE: this program simulates a 33% packet loss.
3 * 4 *
4 * Best used in combination with Lossless_UDP_testclient 5 * Best used in combination with Lossless_UDP_testclient
5 * 6 *
@@ -40,6 +41,7 @@ void printpacket(char * data, uint32_t length, IP_Port ip_port)
40 } 41 }
41 printf("\n--------------------END-----------------------------\n\n\n"); 42 printf("\n--------------------END-----------------------------\n\n\n");
42} 43}
44/*
43void printpackets(Data test) 45void printpackets(Data test)
44{ 46{
45 int i; 47 int i;
@@ -75,14 +77,14 @@ void printconnection(int connection_id)
75 } 77 }
76 Data sendbuffer[MAX_QUEUE_NUM]; 78 Data sendbuffer[MAX_QUEUE_NUM];
77 Data recvbuffer[MAX_QUEUE_NUM]; 79 Data recvbuffer[MAX_QUEUE_NUM];
78 printf("recv_num: %u, recv_sync: %u, sent_packetnum %u, send_packetnum: %u, successful_sent: %u, successful_read: %u\n", 80 printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
79 connections[connection_id].recv_packetnum, 81 connections[connection_id].recv_packetnum,
80 connections[connection_id].recv_packetnum_sync, connections[connection_id].sent_packetnum, connections[connection_id].send_packetnum, 82 connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
81 connections[connection_id].successful_sent, 83 connections[connection_id].successful_sent,
82 connections[connection_id].successful_read); 84 connections[connection_id].successful_read);
83 85
84 printf("req packets: \n"); 86 printf("req packets: \n");
85 for(i = 0; i < MAX_PACKET_NUM; i++) 87 for(i = 0; i < BUFFER_PACKET_NUM; i++)
86 { 88 {
87 printf(" %u ", connections[connection_id].req_packets[i]); 89 printf(" %u ", connections[connection_id].req_packets[i]);
88 } 90 }
@@ -92,7 +94,7 @@ void printconnection(int connection_id)
92 printf("--------------------END---------------------\n"); 94 printf("--------------------END---------------------\n");
93 95
94} 96}
95 97*/
96//recieve packets and send them to the packethandler 98//recieve packets and send them to the packethandler
97//run doLossless_UDP(); 99//run doLossless_UDP();
98void Lossless_UDP() 100void Lossless_UDP()
@@ -103,14 +105,16 @@ void Lossless_UDP()
103 while(recievepacket(&ip_port, data, &length) != -1) 105 while(recievepacket(&ip_port, data, &length) != -1)
104 { 106 {
105 if(rand() % 3 != 1)//add packet loss 107 if(rand() % 3 != 1)//add packet loss
106 if(LosslessUDP_handlepacket(data, length, ip_port))
107 {
108 printpacket(data, length, ip_port);
109 }
110 else
111 { 108 {
112 // printconnection(0); 109 if(LosslessUDP_handlepacket(data, length, ip_port))
113 printf("Received handled packet with length: %u\n", length); 110 {
111 printpacket(data, length, ip_port);
112 }
113 else
114 {
115 //printconnection(0);
116 // printf("Received handled packet with length: %u\n", length);
117 }
114 } 118 }
115 } 119 }
116 120
@@ -151,13 +155,14 @@ int main(int argc, char *argv[])
151 connection = incoming_connection(); 155 connection = incoming_connection();
152 if(connection != -1) 156 if(connection != -1)
153 { 157 {
154 if(is_connected(connection) == 3) 158 if(is_connected(connection) == 2)
155 { 159 {
156 printf("Recieved the connection.\n"); 160 printf("Recieved the connection.\n");
161
157 } 162 }
158 break; 163 break;
159 } 164 }
160 c_sleep(100); 165 c_sleep(1);
161 } 166 }
162 167
163 timer = current_time(); 168 timer = current_time();
@@ -166,13 +171,13 @@ int main(int argc, char *argv[])
166 { 171 {
167 //printconnection(0); 172 //printconnection(0);
168 Lossless_UDP(); 173 Lossless_UDP();
169 if(is_connected(connection) == 3) 174 if(is_connected(connection) >= 2)
170 { 175 {
171 read = read_packet(connection, buffer); 176 read = read_packet(connection, buffer);
172 177
173 if(read != 0) 178 if(read != 0)
174 { 179 {
175 printf("Recieved data.\n"); 180 // printf("Recieved data.\n");
176 if(!fwrite(buffer, read, 1, file)) 181 if(!fwrite(buffer, read, 1, file))
177 { 182 {
178 printf("file write error\n"); 183 printf("file write error\n");
@@ -185,7 +190,7 @@ int main(int argc, char *argv[])
185 fclose(file); 190 fclose(file);
186 return 1; 191 return 1;
187 } 192 }
188 c_sleep(50); 193 c_sleep(1);
189 } 194 }
190 195
191 return 0; 196 return 0;