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.c196
1 files changed, 123 insertions, 73 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 6be8328f..7a994724 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -45,43 +45,71 @@ timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION
45#define DATA_SYNC_RATE 30 45#define DATA_SYNC_RATE 30
46 46
47typedef struct { 47typedef struct {
48 uint8_t data[MAX_DATA_SIZE]; 48 uint8_t data[MAX_DATA_SIZE];
49 uint16_t size; 49 uint16_t size;
50} Data; 50} Data;
51 51
52typedef struct { 52typedef struct {
53 IP_Port ip_port; 53 IP_Port ip_port;
54 uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, 54 /*
55 2 if handshake is done (we start sending SYNC packets) 55 * 0 if connection is dead, 1 if attempting handshake,
56 3 if we are sending SYNC packets and can send data 56 * 2 if handshake is done (we start sending SYNC packets)
57 4 if the connection has timed out. */ 57 * 3 if we are sending SYNC packets and can send data
58 58 * 4 if the connection has timed out.
59 uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. 59 */
60 2 if incoming_connection() has not returned it yet, 1 if it has. */ 60 uint8_t status;
61 61
62 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ 62 /*
63 uint16_t data_rate; /* current data packet send rate packets per second. */ 63 * 1 or 2 if connection was initiated by someone else, 0 if not.
64 uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ 64 * 2 if incoming_connection() has not returned it yet, 1 if it has.
65 uint64_t last_sent; /* time at which our last data or handshake packet was sent. */ 65 */
66 uint64_t last_recvSYNC; /* time at which we last received a SYNC packet from the other */ 66 uint8_t inbound;
67 uint64_t last_recvdata; /* time at which we last received a DATA packet from the other */ 67
68 uint64_t killat; /* time at which to kill the connection */ 68 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
69 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ 69 uint16_t data_rate; /* current data packet send rate packets per second. */
70 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ 70
71 uint32_t handshake_id1; 71 uint64_t last_SYNC; /* time our last SYNC packet was sent. */
72 uint32_t handshake_id2; 72 uint64_t last_sent; /* time our last data or handshake packet was sent. */
73 uint32_t recv_packetnum; /* number of data packets received (also used as handshake_id1) */ 73 uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */
74 uint32_t orecv_packetnum; /* number of packets received by the other peer */ 74 uint64_t last_recvdata; /* time we last received a DATA packet from the other */
75 uint32_t sent_packetnum; /* number of data packets sent */ 75 uint64_t killat; /* time to kill the connection */
76 uint32_t osent_packetnum; /* number of packets sent by the other peer. */ 76
77 uint32_t sendbuff_packetnum; /* number of latest packet written onto the sendbuffer */ 77 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
78 uint32_t successful_sent; /* we know all packets before that number were successfully sent */ 78 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
79 uint32_t successful_read; /* packet number of last packet read with the read_packet function */ 79
80 uint32_t req_packets[BUFFER_PACKET_NUM]; /* list of currently requested packet numbers(by the other person) */ 80 uint32_t handshake_id1;
81 uint16_t num_req_paquets; /* total number of currently requested packets(by the other person) */ 81 uint32_t handshake_id2;
82 uint8_t recv_counter; 82
83 uint8_t send_counter; 83 /* number of data packets received (also used as handshake_id1) */
84 uint8_t timeout; /* connection timeout in seconds. */ 84 uint32_t recv_packetnum;
85
86 /* number of packets received by the other peer */
87 uint32_t orecv_packetnum;
88
89 /* number of data packets sent */
90 uint32_t sent_packetnum;
91
92 /* number of packets sent by the other peer. */
93 uint32_t osent_packetnum;
94
95 /* number of latest packet written onto the sendbuffer */
96 uint32_t sendbuff_packetnum;
97
98 /* we know all packets before that number were successfully sent */
99 uint32_t successful_sent;
100
101 /* packet number of last packet read with the read_packet function */
102 uint32_t successful_read;
103
104 /* list of currently requested packet numbers(by the other person) */
105 uint32_t req_packets[BUFFER_PACKET_NUM];
106
107 /* total number of currently requested packets(by the other person) */
108 uint16_t num_req_paquets;
109
110 uint8_t recv_counter;
111 uint8_t send_counter;
112 uint8_t timeout; /* connection timeout in seconds. */
85} Connection; 113} Connection;
86 114
87 115
@@ -159,22 +187,26 @@ int new_connection(IP_Port ip_port)
159 for (i = 0; i < MAX_CONNECTIONS; ++i) { 187 for (i = 0; i < MAX_CONNECTIONS; ++i) {
160 if(connections[i].status == 0) { 188 if(connections[i].status == 0) {
161 memset(&connections[i], 0, sizeof(Connection)); 189 memset(&connections[i], 0, sizeof(Connection));
162 connections[i].ip_port = ip_port; 190
163 connections[i].status = 1; 191 connections[i] = (Connection) {
164 connections[i].inbound = 0; 192 .ip_port = ip_port,
165 connections[i].handshake_id1 = handshake_id(ip_port); 193 .status = 1,
166 connections[i].sent_packetnum = connections[i].handshake_id1; 194 .inbound = 0,
167 connections[i].sendbuff_packetnum = connections[i].handshake_id1; 195 .handshake_id1 = handshake_id(ip_port),
168 connections[i].successful_sent = connections[i].handshake_id1; 196 .sent_packetnum = connections[i].handshake_id1,
169 connections[i].SYNC_rate = SYNC_RATE; 197 .sendbuff_packetnum = connections[i].handshake_id1,
170 connections[i].data_rate = DATA_SYNC_RATE; 198 .successful_sent = connections[i].handshake_id1,
171 connections[i].last_recvSYNC = current_time(); 199 .SYNC_rate = SYNC_RATE,
172 connections[i].last_sent = current_time(); 200 .data_rate = DATA_SYNC_RATE,
173 connections[i].killat = ~0; 201 .last_recvSYNC = current_time(),
174 connections[i].send_counter = 0; 202 .last_sent = current_time(),
175 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 203 .killat = ~0,
176 connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 204 .send_counter = 0,
205 /* add randomness to timeout to prevent connections getting stuck in a loop. */
206 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
207 };
177 ++connections_number; 208 ++connections_number;
209
178 return i; 210 return i;
179 } 211 }
180 } 212 }
@@ -203,18 +235,23 @@ int new_inconnection(IP_Port ip_port)
203 for (i = 0; i < MAX_CONNECTIONS; ++i) { 235 for (i = 0; i < MAX_CONNECTIONS; ++i) {
204 if (connections[i].status == 0) { 236 if (connections[i].status == 0) {
205 memset(&connections[i], 0, sizeof(Connection)); 237 memset(&connections[i], 0, sizeof(Connection));
206 connections[i].ip_port = ip_port; 238
207 connections[i].status = 2; 239 connections[i] = (Connection){
208 connections[i].inbound = 2; 240 .ip_port = ip_port,
209 connections[i].SYNC_rate = SYNC_RATE; 241 .status = 2,
210 connections[i].data_rate = DATA_SYNC_RATE; 242 .inbound = 2,
211 connections[i].last_recvSYNC = current_time(); 243 .SYNC_rate = SYNC_RATE,
212 connections[i].last_sent = current_time(); 244 .data_rate = DATA_SYNC_RATE,
213 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 245 .last_recvSYNC = current_time(),
214 connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 246 .last_sent = current_time(),
215 /* if this connection isn't handled within the timeout kill it. */ 247 .send_counter = 127,
216 connections[i].killat = current_time() + 1000000UL*connections[i].timeout; 248
217 connections[i].send_counter = 127; 249 /* add randomness to timeout to prevent connections getting stuck in a loop. */
250 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT,
251
252 /* if this connection isn't handled within the timeout kill it. */
253 .killat = current_time() + 1000000UL*connections[i].timeout
254 };
218 ++connections_number; 255 ++connections_number;
219 return i; 256 return i;
220 } 257 }
@@ -245,10 +282,12 @@ static void free_connections()
245 282
246 if(connections_length == i) 283 if(connections_length == i)
247 return; 284 return;
285
248 Connection * temp; 286 Connection * temp;
249 temp = realloc(connections, sizeof(Connection) * i); 287 temp = realloc(connections, sizeof(Connection) * i);
250 if(temp == NULL && i != 0) 288 if(temp == NULL && i != 0)
251 return; 289 return;
290
252 connections = temp; 291 connections = temp;
253 connections_length = i; 292 connections_length = i;
254} 293}
@@ -338,7 +377,7 @@ int read_packet(int connection_id, uint8_t * data)
338{ 377{
339 if (recvqueue(connection_id) != 0) { 378 if (recvqueue(connection_id) != 0) {
340 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 379 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
341 uint16_t size = connections[connection_id].recvbuffer[index].size; 380 uint16_t size = connections[connection_id].recvbuffer[index].size;
342 memcpy(data, connections[connection_id].recvbuffer[index].data, size); 381 memcpy(data, connections[connection_id].recvbuffer[index].data, size);
343 ++connections[connection_id].successful_read; 382 ++connections[connection_id].successful_read;
344 connections[connection_id].recvbuffer[index].size = 0; 383 connections[connection_id].recvbuffer[index].size = 0;
@@ -353,8 +392,10 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length)
353{ 392{
354 if (length > MAX_DATA_SIZE) 393 if (length > MAX_DATA_SIZE)
355 return 0; 394 return 0;
395
356 if (length == 0) 396 if (length == 0)
357 return 0; 397 return 0;
398
358 if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { 399 if (sendqueue(connection_id) < BUFFER_PACKET_NUM) {
359 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; 400 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
360 memcpy(connections[connection_id].sendbuffer[index].data, data, length); 401 memcpy(connections[connection_id].sendbuffer[index].data, data, length);
@@ -398,6 +439,7 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i
398 memcpy(packet + 1, &temp, 4); 439 memcpy(packet + 1, &temp, 4);
399 temp = htonl(handshake_id2); 440 temp = htonl(handshake_id2);
400 memcpy(packet + 5, &temp, 4); 441 memcpy(packet + 5, &temp, 4);
442
401 return sendpacket(ip_port, packet, sizeof(packet)); 443 return sendpacket(ip_port, packet, sizeof(packet));
402} 444}
403 445
@@ -407,12 +449,14 @@ int send_SYNC(uint32_t connection_id)
407 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; 449 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)];
408 uint16_t index = 0; 450 uint16_t index = 0;
409 451
410 IP_Port ip_port = connections[connection_id].ip_port; 452 IP_Port ip_port = connections[connection_id].ip_port;
411 uint8_t counter = connections[connection_id].send_counter; 453 uint8_t counter = connections[connection_id].send_counter;
412 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); 454 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum);
413 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); 455 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum);
456
414 uint32_t requested[BUFFER_PACKET_NUM]; 457 uint32_t requested[BUFFER_PACKET_NUM];
415 uint32_t number = missing_packets(connection_id, requested); 458 uint32_t number = missing_packets(connection_id, requested);
459
416 460
417 packet[0] = 17; 461 packet[0] = 17;
418 index += 1; 462 index += 1;
@@ -598,8 +642,10 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
598 return 0; 642 return 0;
599} 643}
600 644
601/* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value. 645/*
602 return 1 if data was too big, 0 if not. */ 646 * Add a packet to the received buffer and set the recv_packetnum of the
647 * connection to its proper value. Return 1 if data was too big, 0 if not.
648 */
603int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) 649int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
604{ 650{
605 if (size > MAX_DATA_SIZE) 651 if (size > MAX_DATA_SIZE)
@@ -635,7 +681,8 @@ int handle_data(uint8_t *packet, uint32_t length, IP_Port source)
635 if (connection == -1) 681 if (connection == -1)
636 return 1; 682 return 1;
637 683
638 if (connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ 684 /* Drop the data packet if connection is not connected. */
685 if (connections[connection].status != 3)
639 return 1; 686 return 1;
640 687
641 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) 688 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
@@ -650,10 +697,9 @@ int handle_data(uint8_t *packet, uint32_t length, IP_Port source)
650} 697}
651 698
652/* END of packet handling functions */ 699/* END of packet handling functions */
653
654int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) 700int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
655{ 701{
656 switch (packet[0]) { //TODO: check if no break statement is correct??? 702 switch (packet[0]) {
657 case 16: 703 case 16:
658 return handle_handshake(packet, length, source); 704 return handle_handshake(packet, length, source);
659 705
@@ -670,8 +716,10 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
670 return 0; 716 return 0;
671} 717}
672 718
673/* Send handshake requests 719/*
674 handshake packets are sent at the same rate as SYNC packets */ 720 * Send handshake requests
721 * handshake packets are sent at the same rate as SYNC packets
722 */
675void doNew() 723void doNew()
676{ 724{
677 uint32_t i; 725 uint32_t i;
@@ -720,11 +768,13 @@ void doData()
720 } 768 }
721} 769}
722 770
723/* TODO: flow control.
724 automatically adjusts send rates of packets for optimal transmission. */
725
726#define MAX_SYNC_RATE 10 771#define MAX_SYNC_RATE 10
727 772
773/*
774 * Automatically adjusts send rates of packets for optimal transmission.
775 *
776 * TODO: flow control.
777 */
728void adjustRates() 778void adjustRates()
729{ 779{
730 uint32_t i; 780 uint32_t i;