summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Lossless_UDP.c143
-rw-r--r--core/Lossless_UDP.h22
-rw-r--r--docs/Lossless_UDP.txt5
-rw-r--r--testing/Lossless_UDP_testclient.c4
-rw-r--r--testing/Lossless_UDP_testserver.c2
5 files changed, 115 insertions, 61 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 82a0493f..b92e6806 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -21,7 +21,8 @@
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 along with Tox. If not, see <http://www.gnu.org/licenses/>.
22 22
23*/ 23*/
24 24//TODO: clean this file a bit.
25//There are a couple of useless variables to get rid of.
25#include "Lossless_UDP.h" 26#include "Lossless_UDP.h"
26 27
27 28
@@ -89,11 +90,61 @@ Connection connections[MAX_CONNECTIONS];
89 90
90//Functions 91//Functions
91 92
93//get connection id from IP_Port
94//return -1 if there are no connections like we are looking for
95//return id if it found it
96int getconnection_id(IP_Port ip_port)
97{
98 uint32_t i;
99 for(i = 0; i < MAX_CONNECTIONS; i++ )
100 {
101 if(connections[i].ip_port.ip.i == ip_port.ip.i &&
102 connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
103 {
104 return i;
105 }
106 }
107 return -1;
108}
109
110//table of random numbers used below.
111static uint32_t randtable[6][256];
112
113
114//generate a handshake_id which depends on the ip_port.
115//this function will always give one unique handshake_id per ip_port.
116//TODO: make this better
117uint32_t handshake_id(IP_Port source)
118{
119 uint32_t id = 0, i;
120 for(i = 0; i < 6; i++)
121 {
122 if(randtable[i][((uint8_t *)&source)[i]] == 0)
123 {
124 randtable[i][((uint8_t *)&source)[i]] = random_int();
125 }
126 id ^= randtable[i][((uint8_t *)&source)[i]];
127 }
128 if(id == 0)//id can't be zero
129 {
130 id = 1;
131 }
132 return id;
133}
134
135
136
92//initialize a new connection to ip_port 137//initialize a new connection to ip_port
93//returns an integer corresponding to the connection id. 138//returns an integer corresponding to the connection id.
94//return -1 if it could not initialize the connection. 139//return -1 if it could not initialize the connection.
140//if there already was an existing connection to that ip_port return its number.
95int new_connection(IP_Port ip_port) 141int new_connection(IP_Port ip_port)
96{ 142{
143 int connect = getconnection_id(ip_port);
144 if(connect != -1)
145 {
146 return connect;
147 }
97 uint32_t i; 148 uint32_t i;
98 for(i = 0; i < MAX_CONNECTIONS; i++) 149 for(i = 0; i < MAX_CONNECTIONS; i++)
99 { 150 {
@@ -102,7 +153,7 @@ int new_connection(IP_Port ip_port)
102 connections[i].ip_port = ip_port; 153 connections[i].ip_port = ip_port;
103 connections[i].status = 1; 154 connections[i].status = 1;
104 connections[i].inbound = 0; 155 connections[i].inbound = 0;
105 connections[i].handshake_id1 = random_int(); 156 connections[i].handshake_id1 = handshake_id(ip_port);
106 connections[i].sent_packetnum = connections[i].handshake_id1; 157 connections[i].sent_packetnum = connections[i].handshake_id1;
107 connections[i].sendbuff_packetnum = connections[i].handshake_id1; 158 connections[i].sendbuff_packetnum = connections[i].handshake_id1;
108 connections[i].successful_sent = connections[i].handshake_id1; 159 connections[i].successful_sent = connections[i].handshake_id1;
@@ -121,6 +172,10 @@ int new_connection(IP_Port ip_port)
121//return -1 if it could not initialize the connection. 172//return -1 if it could not initialize the connection.
122int new_inconnection(IP_Port ip_port) 173int new_inconnection(IP_Port ip_port)
123{ 174{
175 if(getconnection_id(ip_port) != -1)
176 {
177 return -1;
178 }
124 uint32_t i; 179 uint32_t i;
125 for(i = 0; i < MAX_CONNECTIONS; i++) 180 for(i = 0; i < MAX_CONNECTIONS; i++)
126 { 181 {
@@ -159,10 +214,13 @@ int incoming_connection()
159//return 0 if killed successfully 214//return 0 if killed successfully
160int kill_connection(int connection_id) 215int kill_connection(int connection_id)
161{ 216{
162 if(connections[connection_id].status > 0) 217 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
163 { 218 {
164 connections[connection_id].status = 0; 219 if(connections[connection_id].status > 0)
165 return 0; 220 {
221 connections[connection_id].status = 0;
222 return 0;
223 }
166 } 224 }
167 return -1; 225 return -1;
168} 226}
@@ -174,7 +232,22 @@ int kill_connection(int connection_id)
174//return 3 if fully connected 232//return 3 if fully connected
175int is_connected(int connection_id) 233int is_connected(int connection_id)
176{ 234{
177 return connections[connection_id].status; 235 if(connection_id >= 0 && connection_id < MAX_CONNECTIONS)
236 {
237 return connections[connection_id].status;
238 }
239 return 0;
240}
241
242//returns the ip_port of the corresponding connection.
243IP_Port connection_ip(int connection_id)
244{
245 if(connection_id > 0 && connection_id < MAX_CONNECTIONS)
246 {
247 return connections[connection_id].ip_port;
248 }
249 IP_Port zero = {{{0}}, 0};
250 return zero;
178} 251}
179 252
180//returns the number of packets in the queue waiting to be successfully sent. 253//returns the number of packets in the queue waiting to be successfully sent.
@@ -331,48 +404,8 @@ int send_DATA(uint32_t connection_id)
331 404
332//END of packet sending functions 405//END of packet sending functions
333 406
334//get connection id from IP_Port
335//return -1 if there are no connections like we are looking for
336//return id if it found it
337int getconnection_id(IP_Port ip_port)
338{
339 uint32_t i;
340 for(i = 0; i < MAX_CONNECTIONS; i++ )
341 {
342 if(connections[i].ip_port.ip.i == ip_port.ip.i &&
343 connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
344 {
345 return i;
346 }
347 }
348 return -1;
349}
350
351//table of random numbers used below.
352static uint32_t randtable[6][256];
353 407
354 408
355//generate a handshake_id which depends on the ip_port.
356//this function will always give one unique handshake_id per ip_port.
357//TODO: make this better
358uint32_t handshake_id(IP_Port source)
359{
360 uint32_t id = 0, i;
361 for(i = 0; i < 6; i++)
362 {
363 if(randtable[i][((uint8_t *)&source)[i]] == 0)
364 {
365 randtable[i][((uint8_t *)&source)[i]] = random_int();
366 }
367 id ^= randtable[i][((uint8_t *)&source)[i]];
368 }
369 if(id == 0)//id can't be zero
370 {
371 id = 1;
372 }
373 return id;
374}
375
376//Packet handling functions 409//Packet handling functions
377//One to handle each type of packets we recieve 410//One to handle each type of packets we recieve
378//return 0 if handled correctly, 1 if packet is bad. 411//return 0 if handled correctly, 1 if packet is bad.
@@ -383,27 +416,29 @@ int handle_handshake(char * packet, uint32_t length, IP_Port source)
383 return 1; 416 return 1;
384 } 417 }
385 uint32_t handshake_id1, handshake_id2; 418 uint32_t handshake_id1, handshake_id2;
419 int connection = getconnection_id(source);
386 memcpy(&handshake_id1, packet + 1, 4); 420 memcpy(&handshake_id1, packet + 1, 4);
387 memcpy(&handshake_id2, packet + 5, 4); 421 memcpy(&handshake_id2, packet + 5, 4);
422
423
388 if(handshake_id2 == 0) 424 if(handshake_id2 == 0)
389 { 425 {
390 send_handshake(source, handshake_id1, handshake_id(source)); 426 send_handshake(source, handshake_id(source), handshake_id1);
391 return 0; 427 return 0;
392 } 428 }
393 int connection = getconnection_id(source);
394 if(is_connected(connection) != 1) 429 if(is_connected(connection) != 1)
395 { 430 {
396 return 1; 431 return 1;
397 } 432 }
398 if(handshake_id1 == connections[connection].handshake_id1)//if handshake_id1 is what we sent previously. 433 if(handshake_id2 == connections[connection].handshake_id1)//if handshake_id2 is what we sent previously as handshake_id1
399 { 434 {
400 connections[connection].status = 2; 435 connections[connection].status = 2;
401 //NOTE:is this necessary? 436 //NOTE:is this necessary?
402 //connections[connection].handshake_id2 = handshake_id2; 437 //connections[connection].handshake_id2 = handshake_id1;
403 connections[connection].orecv_packetnum = handshake_id1; 438 connections[connection].orecv_packetnum = handshake_id2;
404 connections[connection].osent_packetnum = handshake_id2; 439 connections[connection].osent_packetnum = handshake_id1;
405 connections[connection].recv_packetnum = handshake_id2; 440 connections[connection].recv_packetnum = handshake_id1;
406 connections[connection].successful_read = handshake_id2; 441 connections[connection].successful_read = handshake_id1;
407 } 442 }
408 return 0; 443 return 0;
409 444
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index 8f5503ea..91e71019 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -33,43 +33,59 @@
33//initialize a new connection to ip_port 33//initialize a new connection to ip_port
34//returns an integer corresponding to the connection id. 34//returns an integer corresponding to the connection id.
35//return -1 if it could not initialize the connection. 35//return -1 if it could not initialize the connection.
36//if there already was an existing connection to that ip_port return its number.
36int new_connection(IP_Port ip_port); 37int new_connection(IP_Port ip_port);
37 38
39
38//returns an integer corresponding to the next connection in our imcoming connection list 40//returns an integer corresponding to the next connection in our imcoming connection list
39//return -1 if there are no new incoming connections in the list. 41//return -1 if there are no new incoming connections in the list.
40int incoming_connection(); 42int incoming_connection();
41 43
44
42//return -1 if it could not kill the connection. 45//return -1 if it could not kill the connection.
43//return 0 if killed successfully 46//return 0 if killed successfully
44int kill_connection(int connection_id); 47int kill_connection(int connection_id);
45 48
49
50//returns the ip_port of the corresponding connection.
51//return 0 if there is no such connection.
52IP_Port connection_ip(int connection_id);
53
54
46//return 0 if there is no received data in the buffer. 55//return 0 if there is no received data in the buffer.
47//return length of recieved packet if successful 56//return length of recieved packet if successful
48int read_packet(int connection_id, char * data); 57int read_packet(int connection_id, char * data);
49 58
59
50//return 0 if data could not be put in packet queue 60//return 0 if data could not be put in packet queue
51//return 1 if data was put into the queue 61//return 1 if data was put into the queue
52int write_packet(int connection_id, char * data, uint32_t length); 62int write_packet(int connection_id, char * data, uint32_t length);
53 63
64
54//returns the number of packets in the queue waiting to be successfully sent. 65//returns the number of packets in the queue waiting to be successfully sent.
55uint32_t sendqueue(int connection_id); 66uint32_t sendqueue(int connection_id);
56 67
68
57//returns the number of packets in the queue waiting to be successfully read with read_packet(...) 69//returns the number of packets in the queue waiting to be successfully read with read_packet(...)
58uint32_t recvqueue(int connection_id); 70uint32_t recvqueue(int connection_id);
59 71
72
60//check if connection is connected 73//check if connection is connected
61//return 0 no. 74//return 0 no.
62//return 1 if yes 75//return 1 if attempting handshake
63//return 2 if the initial attempt isn't over yet. 76//return 2 if handshake is done
77//return 3 if fully connected
64int is_connected(int connection_id); 78int is_connected(int connection_id);
65 79
80
66//Call this function a couple times per second 81//Call this function a couple times per second
67//It's the main loop. 82//It's the main loop.
68void doLossless_UDP(); 83void doLossless_UDP();
69 84
85
70//if we receive a Lossless_UDP packet we call this function so it can be handled. 86//if we receive a Lossless_UDP packet we call this function so it can be handled.
71//Return 0 if packet is handled correctly. 87//Return 0 if packet is handled correctly.
72//return 1 if it didn't handle the packet or if the packet was shit. 88//return 1 if it didn't handle the packet or if the packet was shit.
73int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source); 89int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source);
74 90
75#endif \ No newline at end of file 91#endif
diff --git a/docs/Lossless_UDP.txt b/docs/Lossless_UDP.txt
index e303703b..7886bf5d 100644
--- a/docs/Lossless_UDP.txt
+++ b/docs/Lossless_UDP.txt
@@ -63,7 +63,10 @@ Lossless UDP:
63 63
64 The client receives a Connection handshake packet(not initiating connection): 64 The client receives a Connection handshake packet(not initiating connection):
65 If handshake_id2 is zero: 65 If handshake_id2 is zero:
66 add our random handshake_id2 to it and send it back 66 use the handshake_id1 in the packet as the handshake_id2 of the response.
67 use our random handshake_id1 as handshake_id1.
68 send the response packet.
69
67 70
68 71
69 The client receives a Connection handshake packet(initiating connection): 72 The client receives a Connection handshake packet(initiating connection):
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c
index 5790ad3b..79ae4a37 100644
--- a/testing/Lossless_UDP_testclient.c
+++ b/testing/Lossless_UDP_testclient.c
@@ -6,8 +6,8 @@
6 * 6 *
7 * Compile with: gcc -O2 -Wall -o testclient ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testclient.c 7 * Compile with: gcc -O2 -Wall -o testclient ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testclient.c
8 * 8 *
9 * Command line arguments are the ip and port to cennect and send the file to. 9 * Command line arguments are the ip and port to connect and send the file to.
10 * EX: ./test 127.0.0.1 33445 filename.txt 10 * EX: ./testclient 127.0.0.1 33445 filename.txt
11 */ 11 */
12 12
13#include "../core/network.h" 13#include "../core/network.h"
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c
index 5370da9e..00e537ac 100644
--- a/testing/Lossless_UDP_testserver.c
+++ b/testing/Lossless_UDP_testserver.c
@@ -7,7 +7,7 @@
7 * Compile with: gcc -O2 -Wall -o testserver ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testserver.c 7 * Compile with: gcc -O2 -Wall -o testserver ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testserver.c
8 * 8 *
9 * Command line argument is the name of the file to save what we recieve to. 9 * Command line argument is the name of the file to save what we recieve to.
10 * EX: ./test filename1.txt 10 * EX: ./testserver filename1.txt
11 */ 11 */
12 12
13#include "../core/network.h" 13#include "../core/network.h"