summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-06-29 11:14:33 -0400
committerirungentoo <irungentoo@gmail.com>2013-06-29 11:14:33 -0400
commitd86a39ebfd2d1b0cf3e80a9c026259a0c71f3422 (patch)
tree78302c5e9ebebddf3dfa48818f5959ef99c45349 /core
parentc9d0c208a5c1c67a0514c01a6c4a3ac360767bfd (diff)
Cleaned bunch of stuff. Only the actual data transmission is left to do.
Diffstat (limited to 'core')
-rw-r--r--core/Lossless_UDP.c363
-rw-r--r--core/Lossless_UDP.h2
2 files changed, 236 insertions, 129 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 3f058c44..7ef818e8 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -3,10 +3,10 @@
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*/
6#include "Lossless_UDP.h"
7 6
7#include "Lossless_UDP.h"
8 8
9//maximum data packets in sent and recieve queues. 9 //maximum data packets in sent and recieve queues.
10#define MAX_QUEUE_NUM 32 10#define MAX_QUEUE_NUM 32
11 11
12//maximum length of the data in the data packets 12//maximum length of the data in the data packets
@@ -18,6 +18,12 @@
18//Lossless UDP connection timeout. 18//Lossless UDP connection timeout.
19#define CONNEXION_TIMEOUT 10 19#define CONNEXION_TIMEOUT 10
20 20
21//initial amount of sync/hanshake packets to send per second.
22#define SYNC_RATE 5
23
24//send rate of sync packets when data is being sent/recieved.
25#define DATA_SYNC_RATE 20
26
21typedef struct 27typedef struct
22{ 28{
23 char data[PDATA_SIZE]; 29 char data[PDATA_SIZE];
@@ -37,18 +43,23 @@ typedef struct
37 uint16_t SYNC_rate;//current SYNC packet send rate packets per second. 43 uint16_t SYNC_rate;//current SYNC packet send rate packets per second.
38 uint16_t data_rate;//current data packet send rate packets per second. 44 uint16_t data_rate;//current data packet send rate packets per second.
39 uint64_t last_SYNC; //time at which our last SYNC packet was sent. 45 uint64_t last_SYNC; //time at which our last SYNC packet was sent.
46 uint64_t last_sent; //time at which our last data or handshake packet was sent.
40 uint64_t last_recv; //time at which we last recieved something from the other 47 uint64_t last_recv; //time at which we last recieved something from the other
41 uint16_t SYNC_packetsize; 48 Data sendbuffer[MAX_QUEUE_NUM];//packet send buffer.
42 char SYNC_packet[(MAX_PACKET_NUM*4 + 4 + 4 + 3)]; //the SYNC packet itself 49 Data recvbuffer[MAX_QUEUE_NUM];//packet recieve buffer.
43 Data sendbuffer[MAX_PACKET_NUM];//packet send buffer. 50 uint32_t handshake_id1;
44 Data recvbuffer[MAX_PACKET_NUM];//packet recieve buffer. 51 uint32_t handshake_id2;
45 uint32_t recv_packetnum; //number of data packets recieved (also used as handshake_id1) 52 uint32_t recv_packetnum; //number of data packets recieved (also used as handshake_id1)
53 uint32_t orecv_packetnum; //number of packets recieved by the other peer
46 uint32_t sent_packetnum; //number of data packets sent 54 uint32_t sent_packetnum; //number of data packets sent
55 uint32_t osent_packetnum; //number of packets sent by the other peer.
56 uint32_t sendbuff_packetnum; //number of latest packet written onto the sendbuffer
47 uint32_t successful_sent;//we know all packets before that number were successfully sent 57 uint32_t successful_sent;//we know all packets before that number were successfully sent
48 uint32_t successful_read;//packet number of last packet read with the read_packet function 58 uint32_t successful_read;//packet number of last packet read with the read_packet function
49 uint32_t req_packets[MAX_PACKET_NUM]; //list of currently requested packet numbers. 59 uint32_t req_packets[MAX_PACKET_NUM]; //list of currently requested packet numbers(by the other person)
50 uint16_t num_req_paquets; //total number of currently requested packets 60 uint16_t num_req_paquets; //total number of currently requested packets(by the other person)
51 uint8_t counter; 61 uint8_t recv_counter;
62 uint8_t send_counter;
52}Connection; 63}Connection;
53 64
54 65
@@ -56,7 +67,6 @@ typedef struct
56 67
57Connection connections[MAX_CONNECTIONS]; 68Connection connections[MAX_CONNECTIONS];
58 69
59
60//Functions 70//Functions
61 71
62//initialize a new connection to ip_port 72//initialize a new connection to ip_port
@@ -69,9 +79,37 @@ int new_connection(IP_Port ip_port)
69 { 79 {
70 if(connections[i].status == 0) 80 if(connections[i].status == 0)
71 { 81 {
82 connections[i].ip_port = ip_port;
72 connections[i].status = 1; 83 connections[i].status = 1;
73 connections[i].inbound = 0; 84 connections[i].inbound = 0;
74 connections[i].recv_packetnum = random_int(); //handshake_id1 85 connections[i].handshake_id1 = random_int();
86 connections[i].SYNC_rate = SYNC_RATE;
87 connections[i].data_rate = DATA_SYNC_RATE;
88 connections[i].last_recv = current_time();
89 connections[i].send_counter = 0;
90 return i;
91 }
92 }
93 return -1;
94}
95
96//initialize a new inbound connection from ip_port
97//returns an integer corresponding to the connection id.
98//return -1 if it could not initialize the connection.
99int new_inconnection(IP_Port ip_port)
100{
101 uint32_t i;
102 for(i = 0; i < MAX_CONNECTIONS; i++)
103 {
104 if(connections[i].status == 0)
105 {
106 connections[i].ip_port = ip_port;
107 connections[i].status = 2;
108 connections[i].inbound = 2;
109 connections[i].SYNC_rate = SYNC_RATE;
110 connections[i].data_rate = DATA_SYNC_RATE;
111 connections[i].last_recv = current_time();
112 connections[i].send_counter = 127;
75 return i; 113 return i;
76 } 114 }
77 } 115 }
@@ -110,16 +148,7 @@ int kill_connection(int connection_id)
110//return length of received packet if successful 148//return length of received packet if successful
111int read_packet(int connection_id, char * data) 149int read_packet(int connection_id, char * data)
112{ 150{
113 //NOTE: like this to handle overflow 151
114 if(connections[connection_id].recv_packetnum - connections[connection_id].successful_read < MAX_QUEUE_NUM &&
115 connections[connection_id].recv_packetnum - connections[connection_id].successful_read != 0)
116 {
117 uint16_t index = (connections[connection_id].successful_read % MAX_QUEUE_NUM);
118 memcpy(data, connections[connection_id].sendbuffer[index].data,
119 connections[connection_id].sendbuffer[index].size);
120 connections[connection_id].successful_read++;
121 return connections[connection_id].sendbuffer[index].size;
122 }
123 return 0; 152 return 0;
124} 153}
125 154
@@ -127,21 +156,17 @@ int read_packet(int connection_id, char * data)
127//return 1 if data was put into the queue 156//return 1 if data was put into the queue
128int write_packet(int connection_id, char * data, uint32_t length) 157int write_packet(int connection_id, char * data, uint32_t length)
129{ 158{
130 //NOTE: like this to handle overflow 159
131 if(connections[connection_id].sent_packetnum - connections[connection_id].successful_sent < MAX_QUEUE_NUM) 160
132 {
133 uint16_t index = (connections[connection_id].successful_sent % MAX_QUEUE_NUM);
134 memcpy(connections[connection_id].sendbuffer[index].data, data, length);
135 connections[connection_id].sendbuffer[index].size = length;
136 return 1;
137 }
138 return 0; 161 return 0;
139} 162}
140 163
164
165
141//returns the number of packets in the queue waiting to be successfully sent. 166//returns the number of packets in the queue waiting to be successfully sent.
142int sendqueue(int connection_id) 167int sendqueue(int connection_id)
143{ 168{
144 return connections[connection_id].sent_packetnum - connections[connection_id].successful_sent; 169 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent;
145} 170}
146 171
147//returns the number of packets in the queue waiting to be successfully read with read_packet(...) 172//returns the number of packets in the queue waiting to be successfully read with read_packet(...)
@@ -160,42 +185,23 @@ int is_connected(int connection_id)
160 return connections[connection_id].status; 185 return connections[connection_id].status;
161} 186}
162 187
163//add a packet number to the list of packet numbers we are requesting 188//put the packet numbers the we are missing in requested and return the number
164//return 0 if added successfully 189uint32_t missing_packets(int connection_id, uint32_t * requested)
165//return 1 if it did not because the list was full (should never ever happen)
166int request_packet(int connection_id, uint32_t number)
167{
168 if(connections[connection_id].num_req_paquets >= MAX_PACKET_NUM)
169 {
170 connections[connection_id].req_packets[connections[connection_id].num_req_paquets] = number;
171 connections[connection_id].num_req_paquets++;
172 return 0;
173 }
174 return 1;
175
176}
177
178//remove a packet number from the list of packet numbers we are requesting
179//return 0 if removed successfully
180//return 1 if it did not because it was not in the list.
181int unrequest_packet(int connection_id, uint32_t number)
182{ 190{
191 uint32_t number = 0;
183 uint32_t i; 192 uint32_t i;
184 for(i = 0; i < connections[connection_id].num_req_paquets; i++) 193 for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ )
185 { 194 {
186 if(connections[connection_id].req_packets[i] == number) 195 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0)
187 { 196 {
188 connections[connection_id].num_req_paquets--; 197 memcpy(requested, &i, number);
189 connections[connection_id].req_packets[i] = 198 number++;
190 connections[connection_id].req_packets[connections[connection_id].num_req_paquets];
191 return 0;
192 } 199 }
193 } 200 }
194 return 1; 201 return number;
202
195} 203}
196 204
197
198
199//Packet sending functions 205//Packet sending functions
200//One per packet type. 206//One per packet type.
201//see docs/Lossless_UDP.txt for more information. 207//see docs/Lossless_UDP.txt for more information.
@@ -212,19 +218,21 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i
212} 218}
213 219
214 220
215int send_SYNC(IP_Port ip_port, char type, uint8_t counter, uint32_t recv_packetnum, 221int send_SYNC(uint32_t connection_id)
216 uint32_t sent_packetnum, uint32_t * requested, uint32_t number)
217{ 222{
218 if(number > MAX_PACKET_NUM) 223
219 { 224 char packet[(MAX_PACKET_NUM*4 + 4 + 4 + 2)];
220 return -1;
221 }
222 char packet[(MAX_PACKET_NUM*4 + 4 + 4 + 3)];
223 uint16_t index = 0; 225 uint16_t index = 0;
224 226
227 IP_Port ip_port = connections[connection_id].ip_port;
228 uint8_t counter = connections[connection_id].send_counter;
229 uint32_t recv_packetnum = connections[connection_id].recv_packetnum;
230 uint32_t sent_packetnum = connections[connection_id].sent_packetnum;
231 uint32_t requested[MAX_PACKET_NUM];
232 uint32_t number = missing_packets(connection_id, requested);
233
225 packet[0] = 17; 234 packet[0] = 17;
226 packet[1] = type; 235 index += 1;
227 index += 2;
228 memcpy(packet + index, &counter, 1); 236 memcpy(packet + index, &counter, 1);
229 index += 1; 237 index += 1;
230 memcpy(packet + index, &recv_packetnum, 4); 238 memcpy(packet + index, &recv_packetnum, 4);
@@ -233,7 +241,7 @@ int send_SYNC(IP_Port ip_port, char type, uint8_t counter, uint32_t recv_packetn
233 index += 4; 241 index += 4;
234 memcpy(packet + index, requested, 4 * number); 242 memcpy(packet + index, requested, 4 * number);
235 243
236 return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 3)); 244 return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2));
237 245
238} 246}
239 247
@@ -257,7 +265,7 @@ int send_data(IP_Port ip_port, uint32_t packet_num, char * data, uint32_t length
257 265
258//get connection id from IP_Port 266//get connection id from IP_Port
259//return -1 if there are no connections like we are looking for 267//return -1 if there are no connections like we are looking for
260//return id 268//return id if it found it
261int getconnection_id(IP_Port ip_port) 269int getconnection_id(IP_Port ip_port)
262{ 270{
263 uint32_t i; 271 uint32_t i;
@@ -301,109 +309,151 @@ uint32_t handshake_id(IP_Port source)
301//One to handle each type of packets we recieve 309//One to handle each type of packets we recieve
302//return 0 if handled correctly, 1 if packet is bad. 310//return 0 if handled correctly, 1 if packet is bad.
303int handle_handshake(char * packet, uint32_t length, IP_Port source) 311int handle_handshake(char * packet, uint32_t length, IP_Port source)
304{ 312{
305 if(length != (1 + 4 + 4)) 313 if(length != (1 + 4 + 4))
306 { 314 {
307 return 1; 315 return 1;
308 } 316 }
309 uint32_t handshake_id1, handshake_id2; 317 uint32_t handshake_id1, handshake_id2;
310 memcpy(&handshake_id1, packet + 1, length); 318 memcpy(&handshake_id1, packet + 1, 4);
311 memcpy(&handshake_id2, packet + 5, length); 319 memcpy(&handshake_id2, packet + 5, 4);
312
313 if(handshake_id2 == 0) 320 if(handshake_id2 == 0)
314 { 321 {
315 send_handshake(source, handshake_id1, handshake_id(source)); 322 send_handshake(source, handshake_id1, handshake_id(source));
316 return 0; 323 return 0;
317 } 324 }
318 int connection = getconnection_id(source); 325 int connection = getconnection_id(source);
319 if(connection != 1) 326 if(is_connected(connection) != 1)
320 { 327 {
321 return 0; 328 return 1;
322 } 329 }
323 if(handshake_id1 == connections[connection].recv_packetnum)//if handshake_id1 is what we sent previously. 330 if(handshake_id1 == connections[connection].handshake_id1)//if handshake_id1 is what we sent previously.
324 { 331 {
325 connections[connection].status = 2; 332 connections[connection].status = 2;
333 //NOTE:is this necessary?
334 //connections[connection].handshake_id2 = handshake_id2;
335 connections[connection].orecv_packetnum = handshake_id1;
336 connections[connection].sent_packetnum = handshake_id1;
337 connections[connection].osent_packetnum = handshake_id2;
338 connections[connection].recv_packetnum = handshake_id2;
326 } 339 }
327 return 0; 340 return 0;
328 341
329} 342}
330 343
344//returns 1 if sync packet is valid
345//0 if not.
346int SYNC_valid(uint32_t length)
347{
348 if(length < 4 + 4 + 2)
349 {
350 return 0;
351 }
352 if(length > (MAX_PACKET_NUM*4 + 4 + 4 + 2) ||
353 ((length - 4 - 4 - 2) % 4) != 0)
354 {
355 return 0;
356 }
357 return 1;
358}
331 359
332handle_SYNC(char * packet, uint32_t length, IP_Port source) 360//case 1:
361int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
333{ 362{
334 if(length < 4 + 4 + 3) 363 if(handshake_id(source) == recv_packetnum)
335 { 364 {
336 return 1; 365 int x = new_inconnection(source);
366 if(x != -1)
367 {
368 connections[x].orecv_packetnum = recv_packetnum;
369 connections[x].sent_packetnum = recv_packetnum;
370 connections[x].osent_packetnum = sent_packetnum;
371 connections[x].recv_packetnum = sent_packetnum;
372
373 return x;
374 }
337 } 375 }
338 if(length > (MAX_PACKET_NUM*4 + 4 + 4 + 3) || 376 return -1;
339 ((length - 4 - 4 - 3) % 4) != 0) 377}
378
379//case 2:
380int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
381{
382 if(recv_packetnum == connections[connection_id].orecv_packetnum &&
383 sent_packetnum == connections[connection_id].osent_packetnum)
340 { 384 {
341 return 1; 385 connections[connection_id].status = 3;
386 connections[connection_id].recv_counter = counter;
387 connections[connection_id].send_counter++;
388 return 0;
389 }
390}
391//case 3:
392int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets,
393 uint16_t number)
394{
395 uint8_t comp_counter = (connections[connection_id].recv_counter + 1);
396 if((recv_packetnum - connections[connection_id].orecv_packetnum) < MAX_PACKET_NUM &&
397 (sent_packetnum - connections[connection_id].osent_packetnum) < MAX_PACKET_NUM &&
398 counter == comp_counter) //packet valid
399 {
400 connections[connection_id].orecv_packetnum = recv_packetnum;
401 connections[connection_id].osent_packetnum = sent_packetnum;
402 connections[connection_id].last_recv = current_time();
403 connections[connection_id].recv_counter = counter;
404 connections[connection_id].send_counter++;
405 memcpy(connections[connection_id].req_packets, req_packets, 4 * number);
406 connections[connection_id].num_req_paquets = number;
407 return 0;
408 }
409 return 1;
410}
411
412int handle_SYNC(char * packet, uint32_t length, IP_Port source)
413{
414
415 if(!SYNC_valid(length))
416 {
417 return 1;
342 } 418 }
343 uint32_t reqpackets[MAX_PACKET_NUM];
344 int connection = getconnection_id(source); 419 int connection = getconnection_id(source);
345 char type;
346 uint8_t counter; 420 uint8_t counter;
347 uint32_t recv_packetnum, sent_packetnum; 421 uint32_t recv_packetnum, sent_packetnum;
348 uint32_t requested[MAX_PACKET_NUM]; 422 uint32_t req_packets[MAX_PACKET_NUM];
349 int16_t index = 2; 423 uint16_t number = (length - 4 - 4 - 2)/ 4;
350
351 memcpy(&counter, packet + index, 1);
352 index += 1;
353 memcpy(&recv_packetnum, packet + index, 4);
354 index += 4;
355 memcpy(&sent_packetnum,packet + index, 4);
356 index += 4;
357
358 //memcpy(requested, packet + index, 4 * number);
359 424
360 425 memcpy(&counter, packet + 1, 1);
361 if(connection == -1) //we are not connected to the person who sent us that packet 426 memcpy(&recv_packetnum, packet + 2, 4);
427 memcpy(&sent_packetnum,packet + 6, 4);
428 if(number != 0)
362 { 429 {
363 if(handshake_id(source) == recv_packetnum) 430 memcpy(req_packets, packet + 10, 4 * number);
364 {
365 //TODO: handle new inbound connection
366 }
367 else
368 {
369 return 1;
370 }
371 } 431 }
372 if(connections[connection].status == 2) //we have just recieved our first SYNC packet from the other. 432 if(connection == -1)
373 { 433 {
374 if(connections[connection].recv_packetnum == recv_packetnum && 434 handle_SYNC1(source, recv_packetnum, sent_packetnum);
375 connections[connection].sent_packetnum == sent_packetnum) 435 return 0;
376 {
377 connections[connection].status = 3;
378 connections[connection].counter = counter + 1;
379 connections[connection].last_recv = current_time();
380 }
381
382 } 436 }
383 if(connections[connection].status == 3) //we are connected and the other person just sent us a SYNC packet 437 if(connections[connection].status == 2)
384 { 438 {
385 439 handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum);
386 //TODO: finish this function. 440 return 0;
387
388
389 } 441 }
390 442 if(connections[connection].status == 3)
443 {
444 handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number);
445 }
446 return 0;
391} 447}
392 448
393 449int handle_data(char * packet, uint32_t length, IP_Port source)
394handle_data(char * packet, uint32_t length, IP_Port source)
395{ 450{
396 451
397
398
399} 452}
400 453
401//END of packet handling functions 454//END of packet handling functions
402 455
403 456
404//if we receive a Lossless_UDP packet we call this function so it can be handled.
405//Return 0 if packet is handled correctly.
406//return 1 if it didn't handle the packet or if the packet was shit.
407int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source) 457int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source)
408{ 458{
409 459
@@ -426,11 +476,70 @@ int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source)
426 476
427} 477}
428 478
479//Send handshake requests
480//TODO: optimize this.
481//handshake packets are sent at the same rate as SYNC packets
482void doNew()
483{
484 uint32_t i;
485 uint64_t temp_time = current_time();
486 for(i = 0; i < MAX_CONNECTIONS; i++)
487 {
488 if(connections[i].status == 1)
489 {
490 if((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time)
491 {
492 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
493 connections[i].last_sent = temp_time;
494 }
495
496 }
497 //kill all timed out connections
498 if( connections[i].status > 0 && (connections[i].last_recv + CONNEXION_TIMEOUT * 1000000UL) < temp_time)
499 {
500 kill_connection(i);
501 }
502 }
503}
504
505void doSYNC()
506{
507 uint32_t i;
508 uint64_t temp_time = current_time();
509 for(i = 0; i < MAX_CONNECTIONS; i++)
510 {
511 if(connections[i].status == 2 || connections[i].status == 3)
512 {
513 if((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time)
514 {
515 send_SYNC(i);
516 connections[i].last_SYNC = temp_time;
517 }
518 }
519 }
520}
521
522void doData()
523{
524
525}
526
527//TODO: flow control.
528//automatically adjusts send rates of packets for optimal transmission.
529void adjustRates()
530{
531 //if()
532
533}
429 534
430//Call this function a couple times per second 535//Call this function a couple times per second
431//It's the main loop. 536//It's the main loop.
432void doLossless_UDP() 537void doLossless_UDP()
433{ 538{
539 doNew();
540 doSYNC();
541 doData();
542 adjustRates();
434 543
435 544
436} \ No newline at end of file 545} \ No newline at end of file
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index 38b41309..f8021f5a 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -9,8 +9,6 @@
9#include "network.h" 9#include "network.h"
10 10
11 11
12
13
14//Functions 12//Functions
15 13
16//initialize a new connection to ip_port 14//initialize a new connection to ip_port