diff options
-rw-r--r-- | core/Lossless_UDP.c | 143 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 22 | ||||
-rw-r--r-- | docs/Lossless_UDP.txt | 5 | ||||
-rw-r--r-- | testing/Lossless_UDP_testclient.c | 4 | ||||
-rw-r--r-- | testing/Lossless_UDP_testserver.c | 2 |
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 | ||
96 | int 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. | ||
111 | static 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 | ||
117 | uint32_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. | ||
95 | int new_connection(IP_Port ip_port) | 141 | int 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. |
122 | int new_inconnection(IP_Port ip_port) | 173 | int 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 |
160 | int kill_connection(int connection_id) | 215 | int 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 |
175 | int is_connected(int connection_id) | 233 | int 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. | ||
243 | IP_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 | ||
337 | int 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. | ||
352 | static 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 | ||
358 | uint32_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. | ||
36 | int new_connection(IP_Port ip_port); | 37 | int 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. |
40 | int incoming_connection(); | 42 | int 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 |
44 | int kill_connection(int connection_id); | 47 | int 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. | ||
52 | IP_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 |
48 | int read_packet(int connection_id, char * data); | 57 | int 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 |
52 | int write_packet(int connection_id, char * data, uint32_t length); | 62 | int 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. |
55 | uint32_t sendqueue(int connection_id); | 66 | uint32_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(...) |
58 | uint32_t recvqueue(int connection_id); | 70 | uint32_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 | ||
64 | int is_connected(int connection_id); | 78 | int 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. |
68 | void doLossless_UDP(); | 83 | void 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. |
73 | int LosslessUDP_handlepacket(char * packet, uint32_t length, IP_Port source); | 89 | int 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" |