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.c247
1 files changed, 142 insertions, 105 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 002e2cf8..fa5f9144 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -21,7 +21,7 @@
21 * 21 *
22 */ 22 */
23 23
24/* 24/*
25 * TODO: clean this file a bit. 25 * TODO: clean this file a bit.
26 * There are a couple of useless variables to get rid of. 26 * There are a couple of useless variables to get rid of.
27 */ 27 */
@@ -59,9 +59,9 @@ typedef struct {
59 */ 59 */
60 uint8_t status; 60 uint8_t status;
61 61
62 /* 62 /*
63 * 1 or 2 if connection was initiated by someone else, 0 if not. 63 * 1 or 2 if connection was initiated by someone else, 0 if not.
64 * 2 if incoming_connection() has not returned it yet, 1 if it has. 64 * 2 if incoming_connection() has not returned it yet, 1 if it has.
65 */ 65 */
66 uint8_t inbound; 66 uint8_t inbound;
67 67
@@ -81,31 +81,31 @@ typedef struct {
81 uint32_t handshake_id2; 81 uint32_t handshake_id2;
82 82
83 /* number of data packets received (also used as handshake_id1) */ 83 /* number of data packets received (also used as handshake_id1) */
84 uint32_t recv_packetnum; 84 uint32_t recv_packetnum;
85 85
86 /* number of packets received by the other peer */ 86 /* number of packets received by the other peer */
87 uint32_t orecv_packetnum; 87 uint32_t orecv_packetnum;
88 88
89 /* number of data packets sent */ 89 /* number of data packets sent */
90 uint32_t sent_packetnum; 90 uint32_t sent_packetnum;
91 91
92 /* number of packets sent by the other peer. */ 92 /* number of packets sent by the other peer. */
93 uint32_t osent_packetnum; 93 uint32_t osent_packetnum;
94 94
95 /* number of latest packet written onto the sendbuffer */ 95 /* number of latest packet written onto the sendbuffer */
96 uint32_t sendbuff_packetnum; 96 uint32_t sendbuff_packetnum;
97 97
98 /* we know all packets before that number were successfully sent */ 98 /* we know all packets before that number were successfully sent */
99 uint32_t successful_sent; 99 uint32_t successful_sent;
100 100
101 /* packet number of last packet read with the read_packet function */ 101 /* packet number of last packet read with the read_packet function */
102 uint32_t successful_read; 102 uint32_t successful_read;
103 103
104 /* list of currently requested packet numbers(by the other person) */ 104 /* list of currently requested packet numbers(by the other person) */
105 uint32_t req_packets[BUFFER_PACKET_NUM]; 105 uint32_t req_packets[BUFFER_PACKET_NUM];
106 106
107 /* total number of currently requested packets(by the other person) */ 107 /* total number of currently requested packets(by the other person) */
108 uint16_t num_req_paquets; 108 uint16_t num_req_paquets;
109 109
110 uint8_t recv_counter; 110 uint8_t recv_counter;
111 uint8_t send_counter; 111 uint8_t send_counter;
@@ -113,7 +113,7 @@ typedef struct {
113} Connection; 113} Connection;
114 114
115 115
116static Connection * connections; 116static Connection *connections;
117 117
118static uint32_t connections_length; /* Length of connections array */ 118static uint32_t connections_length; /* Length of connections array */
119static uint32_t connections_number; /* Number of connections in connections array */ 119static uint32_t connections_number; /* Number of connections in connections array */
@@ -122,7 +122,7 @@ static uint32_t connections_number; /* Number of connections in connections arra
122 122
123/* Functions */ 123/* Functions */
124 124
125/* 125/*
126 * Get connection id from IP_Port 126 * Get connection id from IP_Port
127 * Return -1 if there are no connections like we are looking for 127 * Return -1 if there are no connections like we are looking for
128 * Return id if it found it 128 * Return id if it found it
@@ -130,10 +130,11 @@ static uint32_t connections_number; /* Number of connections in connections arra
130int getconnection_id(IP_Port ip_port) 130int getconnection_id(IP_Port ip_port)
131{ 131{
132 uint32_t i; 132 uint32_t i;
133
133 for (i = 0; i < MAX_CONNECTIONS; ++i) { 134 for (i = 0; i < MAX_CONNECTIONS; ++i) {
134 if (connections[i].ip_port.ip.i == ip_port.ip.i && 135 if (connections[i].ip_port.ip.i == ip_port.ip.i &&
135 connections[i].ip_port.port == ip_port.port && 136 connections[i].ip_port.port == ip_port.port &&
136 connections[i].status > 0) 137 connections[i].status > 0)
137 return i; 138 return i;
138 } 139 }
139 140
@@ -143,7 +144,7 @@ int getconnection_id(IP_Port ip_port)
143/* table of random numbers used below. */ 144/* table of random numbers used below. */
144static uint32_t randtable[6][256]; 145static uint32_t randtable[6][256];
145 146
146/* 147/*
147 * Generate a handshake_id which depends on the ip_port. 148 * Generate a handshake_id which depends on the ip_port.
148 * This function will always give one unique handshake_id per ip_port. 149 * This function will always give one unique handshake_id per ip_port.
149 * 150 *
@@ -152,18 +153,21 @@ static uint32_t randtable[6][256];
152static uint32_t handshake_id(IP_Port source) 153static uint32_t handshake_id(IP_Port source)
153{ 154{
154 uint32_t id = 0, i; 155 uint32_t id = 0, i;
156
155 for (i = 0; i < 6; ++i) { 157 for (i = 0; i < 6; ++i) {
156 if(randtable[i][((uint8_t *)&source)[i]] == 0) 158 if (randtable[i][((uint8_t *)&source)[i]] == 0)
157 randtable[i][((uint8_t *)&source)[i]] = random_int(); 159 randtable[i][((uint8_t *)&source)[i]] = random_int();
160
158 id ^= randtable[i][((uint8_t *)&source)[i]]; 161 id ^= randtable[i][((uint8_t *)&source)[i]];
159 } 162 }
163
160 if (id == 0) /* id can't be zero */ 164 if (id == 0) /* id can't be zero */
161 id = 1; 165 id = 1;
162 166
163 return id; 167 return id;
164} 168}
165 169
166/* 170/*
167 * Change the hanshake id associated with that ip_port 171 * Change the hanshake id associated with that ip_port
168 * 172 *
169 * TODO: make this better 173 * TODO: make this better
@@ -174,7 +178,7 @@ static void change_handshake(IP_Port source)
174 randtable[rand][((uint8_t *)&source)[rand]] = random_int(); 178 randtable[rand][((uint8_t *)&source)[rand]] = random_int();
175} 179}
176 180
177/* 181/*
178 * Initialize a new connection to ip_port 182 * Initialize a new connection to ip_port
179 * Returns an integer corresponding to the connection idt 183 * Returns an integer corresponding to the connection idt
180 * Return -1 if it could not initialize the connectiont 184 * Return -1 if it could not initialize the connectiont
@@ -183,53 +187,56 @@ static void change_handshake(IP_Port source)
183int new_connection(IP_Port ip_port) 187int new_connection(IP_Port ip_port)
184{ 188{
185 int connect = getconnection_id(ip_port); 189 int connect = getconnection_id(ip_port);
190
186 if (connect != -1) 191 if (connect != -1)
187 return connect; 192 return connect;
188 193
189 if(connections_number == connections_length) { 194 if (connections_number == connections_length) {
190 Connection * temp; 195 Connection *temp;
191 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 196 temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
192 197
193 if(temp == NULL) 198 if (temp == NULL)
194 return -1; 199 return -1;
195 200
196 memset(&temp[connections_length], 0, sizeof(Connection)); 201 memset(&temp[connections_length], 0, sizeof(Connection));
197 ++connections_length; 202 ++connections_length;
198 connections = temp; 203 connections = temp;
199 } 204 }
200 205
201 uint32_t i; 206 uint32_t i;
207
202 for (i = 0; i < MAX_CONNECTIONS; ++i) { 208 for (i = 0; i < MAX_CONNECTIONS; ++i) {
203 if(connections[i].status == 0) { 209 if (connections[i].status == 0) {
204 memset(&connections[i], 0, sizeof(Connection)); 210 memset(&connections[i], 0, sizeof(Connection));
205 uint32_t handshake_id1 = handshake_id(ip_port); 211 uint32_t handshake_id1 = handshake_id(ip_port);
206 212
207 connections[i] = (Connection) { 213 connections[i] = (Connection) {
208 .ip_port = ip_port, 214 .ip_port = ip_port,
209 .status = 1, 215 .status = 1,
210 .inbound = 0, 216 .inbound = 0,
211 .handshake_id1 = handshake_id1, 217 .handshake_id1 = handshake_id1,
212 .sent_packetnum = handshake_id1, 218 .sent_packetnum = handshake_id1,
213 .sendbuff_packetnum = handshake_id1, 219 .sendbuff_packetnum = handshake_id1,
214 .successful_sent = handshake_id1, 220 .successful_sent = handshake_id1,
215 .SYNC_rate = SYNC_RATE, 221 .SYNC_rate = SYNC_RATE,
216 .data_rate = DATA_SYNC_RATE, 222 .data_rate = DATA_SYNC_RATE,
217 .last_recvSYNC = current_time(), 223 .last_recvSYNC = current_time(),
218 .last_sent = current_time(), 224 .last_sent = current_time(),
219 .killat = ~0, 225 .killat = ~0,
220 .send_counter = 0, 226 .send_counter = 0,
221 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 227 /* add randomness to timeout to prevent connections getting stuck in a loop. */
222 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT 228 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
223 }; 229 };
224 ++connections_number; 230 ++connections_number;
225 231
226 return i; 232 return i;
227 } 233 }
228 } 234 }
235
229 return -1; 236 return -1;
230} 237}
231 238
232/* 239/*
233 * Initialize a new inbound connection from ip_port 240 * Initialize a new inbound connection from ip_port
234 * Returns an integer corresponding to the connection id. 241 * Returns an integer corresponding to the connection id.
235 * Return -1 if it could not initialize the connection. 242 * Return -1 if it could not initialize the connection.
@@ -238,55 +245,58 @@ static int new_inconnection(IP_Port ip_port)
238{ 245{
239 if (getconnection_id(ip_port) != -1) 246 if (getconnection_id(ip_port) != -1)
240 return -1; 247 return -1;
241 248
242 if(connections_number == connections_length) { 249 if (connections_number == connections_length) {
243 Connection * temp; 250 Connection *temp;
244 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 251 temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
245 252
246 if(temp == NULL) 253 if (temp == NULL)
247 return -1; 254 return -1;
248 255
249 memset(&temp[connections_length], 0, sizeof(Connection)); 256 memset(&temp[connections_length], 0, sizeof(Connection));
250 ++connections_length; 257 ++connections_length;
251 connections = temp; 258 connections = temp;
252 } 259 }
253 260
254 uint32_t i; 261 uint32_t i;
262
255 for (i = 0; i < MAX_CONNECTIONS; ++i) { 263 for (i = 0; i < MAX_CONNECTIONS; ++i) {
256 if (connections[i].status == 0) { 264 if (connections[i].status == 0) {
257 memset(&connections[i], 0, sizeof(Connection)); 265 memset(&connections[i], 0, sizeof(Connection));
258 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 266 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
259 267
260 connections[i] = (Connection){ 268 connections[i] = (Connection) {
261 .ip_port = ip_port, 269 .ip_port = ip_port,
262 .status = 2, 270 .status = 2,
263 .inbound = 2, 271 .inbound = 2,
264 .SYNC_rate = SYNC_RATE, 272 .SYNC_rate = SYNC_RATE,
265 .data_rate = DATA_SYNC_RATE, 273 .data_rate = DATA_SYNC_RATE,
266 .last_recvSYNC = current_time(), 274 .last_recvSYNC = current_time(),
267 .last_sent = current_time(), 275 .last_sent = current_time(),
268 .send_counter = 127, 276 .send_counter = 127,
269 277
270 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 278 /* add randomness to timeout to prevent connections getting stuck in a loop. */
271 .timeout = timeout, 279 .timeout = timeout,
272 280
273 /* if this connection isn't handled within the timeout kill it. */ 281 /* if this connection isn't handled within the timeout kill it. */
274 .killat = current_time() + 1000000UL*timeout 282 .killat = current_time() + 1000000UL * timeout
275 }; 283 };
276 ++connections_number; 284 ++connections_number;
277 return i; 285 return i;
278 } 286 }
279 } 287 }
288
280 return -1; 289 return -1;
281} 290}
282 291
283/* 292/*
284 * Returns an integer corresponding to the next connection in our incoming connection list. 293 * Returns an integer corresponding to the next connection in our incoming connection list.
285 * Return -1 if there are no new incoming connections in the list. 294 * Return -1 if there are no new incoming connections in the list.
286 */ 295 */
287int incoming_connection(void) 296int incoming_connection(void)
288{ 297{
289 uint32_t i; 298 uint32_t i;
299
290 for (i = 0; i < MAX_CONNECTIONS; ++i) { 300 for (i = 0; i < MAX_CONNECTIONS; ++i) {
291 if (connections[i].inbound == 2) { 301 if (connections[i].inbound == 2) {
292 connections[i].inbound = 1; 302 connections[i].inbound = 1;
@@ -301,23 +311,25 @@ int incoming_connection(void)
301static void free_connections(void) 311static void free_connections(void)
302{ 312{
303 uint32_t i; 313 uint32_t i;
304 for(i = connections_length; i != 0; --i) 314
315 for (i = connections_length; i != 0; --i)
305 if (connections[i - 1].status != 0) 316 if (connections[i - 1].status != 0)
306 break; 317 break;
307 318
308 if(connections_length == i) 319 if (connections_length == i)
309 return; 320 return;
310 321
311 Connection * temp; 322 Connection *temp;
312 temp = realloc(connections, sizeof(Connection) * i); 323 temp = realloc(connections, sizeof(Connection) * i);
313 if(temp == NULL && i != 0) 324
325 if (temp == NULL && i != 0)
314 return; 326 return;
315 327
316 connections = temp; 328 connections = temp;
317 connections_length = i; 329 connections_length = i;
318} 330}
319 331
320/* 332/*
321 * Return -1 if it could not kill the connection. 333 * Return -1 if it could not kill the connection.
322 * Return 0 if killed successfully 334 * Return 0 if killed successfully
323 */ 335 */
@@ -332,10 +344,11 @@ int kill_connection(int connection_id)
332 return 0; 344 return 0;
333 } 345 }
334 } 346 }
347
335 return -1; 348 return -1;
336} 349}
337 350
338/* 351/*
339 * Kill connection in seconds. 352 * Kill connection in seconds.
340 * Return -1 if it can not kill the connection. 353 * Return -1 if it can not kill the connection.
341 * Return 0 if it will kill it. 354 * Return 0 if it will kill it.
@@ -344,14 +357,15 @@ int kill_connection_in(int connection_id, uint32_t seconds)
344{ 357{
345 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 358 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
346 if (connections[connection_id].status > 0) { 359 if (connections[connection_id].status > 0) {
347 connections[connection_id].killat = current_time() + 1000000UL*seconds; 360 connections[connection_id].killat = current_time() + 1000000UL * seconds;
348 return 0; 361 return 0;
349 } 362 }
350 } 363 }
364
351 return -1; 365 return -1;
352} 366}
353 367
354/* 368/*
355 * Check if connection is connected: 369 * Check if connection is connected:
356 * Return 0 no. 370 * Return 0 no.
357 * Return 1 if attempting handshake. 371 * Return 1 if attempting handshake.
@@ -363,6 +377,7 @@ int is_connected(int connection_id)
363{ 377{
364 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 378 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
365 return connections[connection_id].status; 379 return connections[connection_id].status;
380
366 return 0; 381 return 0;
367} 382}
368 383
@@ -371,6 +386,7 @@ IP_Port connection_ip(int connection_id)
371{ 386{
372 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 387 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
373 return connections[connection_id].ip_port; 388 return connections[connection_id].ip_port;
389
374 IP_Port zero = {{{0}}, 0}; 390 IP_Port zero = {{{0}}, 0};
375 return zero; 391 return zero;
376} 392}
@@ -380,6 +396,7 @@ uint32_t sendqueue(int connection_id)
380{ 396{
381 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 397 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
382 return 0; 398 return 0;
399
383 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; 400 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent;
384} 401}
385 402
@@ -388,6 +405,7 @@ uint32_t recvqueue(int connection_id)
388{ 405{
389 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 406 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
390 return 0; 407 return 0;
408
391 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; 409 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read;
392} 410}
393 411
@@ -406,7 +424,7 @@ char id_packet(int connection_id)
406 424
407/* return 0 if there is no received data in the buffer. 425/* return 0 if there is no received data in the buffer.
408 return length of received packet if successful */ 426 return length of received packet if successful */
409int read_packet(int connection_id, uint8_t * data) 427int read_packet(int connection_id, uint8_t *data)
410{ 428{
411 if (recvqueue(connection_id) != 0) { 429 if (recvqueue(connection_id) != 0) {
412 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 430 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
@@ -416,14 +434,15 @@ int read_packet(int connection_id, uint8_t * data)
416 connections[connection_id].recvbuffer[index].size = 0; 434 connections[connection_id].recvbuffer[index].size = 0;
417 return size; 435 return size;
418 } 436 }
437
419 return 0; 438 return 0;
420} 439}
421 440
422/* 441/*
423 * Return 0 if data could not be put in packet queue 442 * Return 0 if data could not be put in packet queue
424 * Return 1 if data was put into the queue 443 * Return 1 if data was put into the queue
425 */ 444 */
426int write_packet(int connection_id, uint8_t * data, uint32_t length) 445int write_packet(int connection_id, uint8_t *data, uint32_t length)
427{ 446{
428 if (length > MAX_DATA_SIZE || length == 0) 447 if (length > MAX_DATA_SIZE || length == 0)
429 return 0; 448 return 0;
@@ -440,31 +459,31 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length)
440} 459}
441 460
442/* put the packet numbers the we are missing in requested and return the number */ 461/* put the packet numbers the we are missing in requested and return the number */
443uint32_t missing_packets(int connection_id, uint32_t * requested) 462uint32_t missing_packets(int connection_id, uint32_t *requested)
444{ 463{
445 uint32_t number = 0; 464 uint32_t number = 0;
446 uint32_t i; 465 uint32_t i;
447 uint32_t temp; 466 uint32_t temp;
448 467
449 /* don't request packets if the buffer is full. */ 468 /* don't request packets if the buffer is full. */
450 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) 469 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1))
451 return 0; 470 return 0;
452 471
453 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { 472 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) {
454 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { 473 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
455 temp = htonl(i); 474 temp = htonl(i);
456 memcpy(requested + number, &temp, 4); 475 memcpy(requested + number, &temp, 4);
457 ++number; 476 ++number;
458 } 477 }
459 } 478 }
460 479
461 if(number == 0) 480 if (number == 0)
462 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; 481 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
463 482
464 return number; 483 return number;
465} 484}
466 485
467/* 486/*
468 * BEGIN Packet sending functions 487 * BEGIN Packet sending functions
469 * One per packet type. 488 * One per packet type.
470 * see http://wiki.tox.im/index.php/Lossless_UDP for more information. 489 * see http://wiki.tox.im/index.php/Lossless_UDP for more information.
@@ -486,7 +505,7 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand
486 505
487static int send_SYNC(uint32_t connection_id) 506static int send_SYNC(uint32_t connection_id)
488{ 507{
489 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; 508 uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)];
490 uint16_t index = 0; 509 uint16_t index = 0;
491 510
492 IP_Port ip_port = connections[connection_id].ip_port; 511 IP_Port ip_port = connections[connection_id].ip_port;
@@ -507,7 +526,7 @@ static int send_SYNC(uint32_t connection_id)
507 index += 4; 526 index += 4;
508 memcpy(packet + index, requested, 4 * number); 527 memcpy(packet + index, requested, 4 * number);
509 528
510 return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2)); 529 return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2));
511 530
512} 531}
513 532
@@ -530,6 +549,7 @@ static int send_DATA(uint32_t connection_id)
530{ 549{
531 int ret; 550 int ret;
532 uint32_t buffer[BUFFER_PACKET_NUM]; 551 uint32_t buffer[BUFFER_PACKET_NUM];
552
533 if (connections[connection_id].num_req_paquets > 0) { 553 if (connections[connection_id].num_req_paquets > 0) {
534 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); 554 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
535 connections[connection_id].num_req_paquets--; 555 connections[connection_id].num_req_paquets--;
@@ -537,15 +557,17 @@ static int send_DATA(uint32_t connection_id)
537 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); 557 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4);
538 return ret; 558 return ret;
539 } 559 }
560
540 if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { 561 if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) {
541 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); 562 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum);
542 connections[connection_id].sent_packetnum++; 563 connections[connection_id].sent_packetnum++;
543 return ret; 564 return ret;
544 } 565 }
566
545 return 0; 567 return 0;
546} 568}
547 569
548/* 570/*
549 * END of packet sending functions 571 * END of packet sending functions
550 * 572 *
551 * 573 *
@@ -555,7 +577,7 @@ static int send_DATA(uint32_t connection_id)
555 577
556 578
557/* Return 0 if handled correctly, 1 if packet is bad. */ 579/* Return 0 if handled correctly, 1 if packet is bad. */
558static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length) 580static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length)
559{ 581{
560 if (length != (1 + 4 + 4)) 582 if (length != (1 + 4 + 4))
561 return 1; 583 return 1;
@@ -573,11 +595,12 @@ static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length)
573 send_handshake(source, handshake_id(source), handshake_id1); 595 send_handshake(source, handshake_id(source), handshake_id1);
574 return 0; 596 return 0;
575 } 597 }
598
576 if (is_connected(connection) != 1) 599 if (is_connected(connection) != 1)
577 return 1; 600 return 1;
578 601
579 /* if handshake_id2 is what we sent previously as handshake_id1 */ 602 /* if handshake_id2 is what we sent previously as handshake_id1 */
580 if (handshake_id2 == connections[connection].handshake_id1) { 603 if (handshake_id2 == connections[connection].handshake_id1) {
581 connections[connection].status = 2; 604 connections[connection].status = 2;
582 /* NOTE: is this necessary? 605 /* NOTE: is this necessary?
583 connections[connection].handshake_id2 = handshake_id1; */ 606 connections[connection].handshake_id2 = handshake_id1; */
@@ -595,9 +618,11 @@ static int SYNC_valid(uint32_t length)
595{ 618{
596 if (length < 4 + 4 + 2) 619 if (length < 4 + 4 + 2)
597 return 0; 620 return 0;
598 if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || 621
599 ((length - 4 - 4 - 2) % 4) != 0) 622 if (length > (BUFFER_PACKET_NUM * 4 + 4 + 4 + 2) ||
623 ((length - 4 - 4 - 2) % 4) != 0)
600 return 0; 624 return 0;
625
601 return 1; 626 return 1;
602} 627}
603 628
@@ -606,6 +631,7 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
606{ 631{
607 if (handshake_id(source) == recv_packetnum) { 632 if (handshake_id(source) == recv_packetnum) {
608 int x = new_inconnection(source); 633 int x = new_inconnection(source);
634
609 if (x != -1) { 635 if (x != -1) {
610 connections[x].orecv_packetnum = recv_packetnum; 636 connections[x].orecv_packetnum = recv_packetnum;
611 connections[x].sent_packetnum = recv_packetnum; 637 connections[x].sent_packetnum = recv_packetnum;
@@ -618,6 +644,7 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
618 return x; 644 return x;
619 } 645 }
620 } 646 }
647
621 return -1; 648 return -1;
622} 649}
623 650
@@ -632,11 +659,13 @@ static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packet
632 send_SYNC(connection_id); 659 send_SYNC(connection_id);
633 return 0; 660 return 0;
634 } 661 }
662
635 return 1; 663 return 1;
636} 664}
637/* case 3 in handle_SYNC: */ 665/* case 3 in handle_SYNC: */
638static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, 666static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum,
639 uint16_t number) 667 uint32_t *req_packets,
668 uint16_t number)
640{ 669{
641 uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); 670 uint8_t comp_counter = (counter - connections[connection_id].recv_counter );
642 uint32_t i, temp; 671 uint32_t i, temp;
@@ -646,9 +675,9 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet
646 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); 675 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
647 676
648 /* packet valid */ 677 /* packet valid */
649 if (comp_1 <= BUFFER_PACKET_NUM && 678 if (comp_1 <= BUFFER_PACKET_NUM &&
650 comp_2 <= BUFFER_PACKET_NUM && 679 comp_2 <= BUFFER_PACKET_NUM &&
651 comp_counter < 10 && comp_counter != 0) { 680 comp_counter < 10 && comp_counter != 0) {
652 681
653 connections[connection_id].orecv_packetnum = recv_packetnum; 682 connections[connection_id].orecv_packetnum = recv_packetnum;
654 connections[connection_id].osent_packetnum = sent_packetnum; 683 connections[connection_id].osent_packetnum = sent_packetnum;
@@ -666,6 +695,7 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet
666 connections[connection_id].num_req_paquets = number; 695 connections[connection_id].num_req_paquets = number;
667 return 0; 696 return 0;
668 } 697 }
698
669 return 1; 699 return 1;
670} 700}
671 701
@@ -680,12 +710,12 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
680 uint32_t temp; 710 uint32_t temp;
681 uint32_t recv_packetnum, sent_packetnum; 711 uint32_t recv_packetnum, sent_packetnum;
682 uint32_t req_packets[BUFFER_PACKET_NUM]; 712 uint32_t req_packets[BUFFER_PACKET_NUM];
683 uint16_t number = (length - 4 - 4 - 2)/ 4; 713 uint16_t number = (length - 4 - 4 - 2) / 4;
684 714
685 memcpy(&counter, packet + 1, 1); 715 memcpy(&counter, packet + 1, 1);
686 memcpy(&temp, packet + 2, 4); 716 memcpy(&temp, packet + 2, 4);
687 recv_packetnum = ntohl(temp); 717 recv_packetnum = ntohl(temp);
688 memcpy(&temp,packet + 6, 4); 718 memcpy(&temp, packet + 6, 4);
689 sent_packetnum = ntohl(temp); 719 sent_packetnum = ntohl(temp);
690 720
691 if (number != 0) 721 if (number != 0)
@@ -695,17 +725,18 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
695 return handle_SYNC1(source, recv_packetnum, sent_packetnum); 725 return handle_SYNC1(source, recv_packetnum, sent_packetnum);
696 726
697 if (connections[connection].status == 2) 727 if (connections[connection].status == 2)
698 return handle_SYNC2(connection, counter, 728 return handle_SYNC2(connection, counter,
699 recv_packetnum, sent_packetnum); 729 recv_packetnum, sent_packetnum);
700 730
701 if (connections[connection].status == 3) 731 if (connections[connection].status == 3)
702 return handle_SYNC3(connection, counter, recv_packetnum, 732 return handle_SYNC3(connection, counter, recv_packetnum,
703 sent_packetnum, req_packets, number); 733 sent_packetnum, req_packets, number);
734
704 return 0; 735 return 0;
705} 736}
706 737
707/* 738/*
708 * Add a packet to the received buffer and set the recv_packetnum of the 739 * Add a packet to the received buffer and set the recv_packetnum of the
709 * connection to its proper value. Return 1 if data was too big, 0 if not. 740 * connection to its proper value. Return 1 if data was too big, 0 if not.
710 */ 741 */
711static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) 742static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
@@ -766,8 +797,8 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length)
766 return add_recv(connection, number, packet + 5, size); 797 return add_recv(connection, number, packet + 5, size);
767} 798}
768 799
769/* 800/*
770 * END of packet handling functions 801 * END of packet handling functions
771 */ 802 */
772 803
773void LosslessUDP_init(void) 804void LosslessUDP_init(void)
@@ -785,17 +816,18 @@ static void doNew(void)
785{ 816{
786 uint32_t i; 817 uint32_t i;
787 uint64_t temp_time = current_time(); 818 uint64_t temp_time = current_time();
819
788 for (i = 0; i < MAX_CONNECTIONS; ++i) { 820 for (i = 0; i < MAX_CONNECTIONS; ++i) {
789 if (connections[i].status == 1) 821 if (connections[i].status == 1)
790 if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { 822 if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) {
791 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); 823 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
792 connections[i].last_sent = temp_time; 824 connections[i].last_sent = temp_time;
793 } 825 }
794 826
795 /* kill all timed out connections */ 827 /* kill all timed out connections */
796 if (connections[i].status > 0 && 828 if (connections[i].status > 0 &&
797 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 829 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
798 connections[i].status != 4) { 830 connections[i].status != 4) {
799 connections[i].status = 4; 831 connections[i].status = 4;
800 /* kill_connection(i); */ 832 /* kill_connection(i); */
801 } 833 }
@@ -809,9 +841,10 @@ static void doSYNC(void)
809{ 841{
810 uint32_t i; 842 uint32_t i;
811 uint64_t temp_time = current_time(); 843 uint64_t temp_time = current_time();
844
812 for (i = 0; i < MAX_CONNECTIONS; ++i) { 845 for (i = 0; i < MAX_CONNECTIONS; ++i) {
813 if (connections[i].status == 2 || connections[i].status == 3) 846 if (connections[i].status == 2 || connections[i].status == 3)
814 if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { 847 if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) {
815 send_SYNC(i); 848 send_SYNC(i);
816 connections[i].last_SYNC = temp_time; 849 connections[i].last_SYNC = temp_time;
817 } 850 }
@@ -823,18 +856,20 @@ static void doData(void)
823 uint32_t i; 856 uint32_t i;
824 uint64_t j; 857 uint64_t j;
825 uint64_t temp_time = current_time(); 858 uint64_t temp_time = current_time();
859
826 for (i = 0; i < MAX_CONNECTIONS; ++i) 860 for (i = 0; i < MAX_CONNECTIONS; ++i)
827 if (connections[i].status == 3 && sendqueue(i) != 0) 861 if (connections[i].status == 3 && sendqueue(i) != 0)
828 if ((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) { 862 if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) {
829 for (j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) 863 for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate))
830 send_DATA(i); 864 send_DATA(i);
865
831 connections[i].last_sent = temp_time; 866 connections[i].last_sent = temp_time;
832 } 867 }
833} 868}
834 869
835#define MAX_SYNC_RATE 10 870#define MAX_SYNC_RATE 10
836 871
837/* 872/*
838 * Automatically adjusts send rates of packets for optimal transmission. 873 * Automatically adjusts send rates of packets for optimal transmission.
839 * 874 *
840 * TODO: flow control. 875 * TODO: flow control.
@@ -843,9 +878,11 @@ static void adjustRates(void)
843{ 878{
844 uint32_t i; 879 uint32_t i;
845 uint64_t temp_time = current_time(); 880 uint64_t temp_time = current_time();
881
846 for (i = 0; i < MAX_CONNECTIONS; ++i) { 882 for (i = 0; i < MAX_CONNECTIONS; ++i) {
847 if (connections[i].status == 1 || connections[i].status == 2) 883 if (connections[i].status == 1 || connections[i].status == 2)
848 connections[i].SYNC_rate = MAX_SYNC_RATE; 884 connections[i].SYNC_rate = MAX_SYNC_RATE;
885
849 if (connections[i].status == 3) { 886 if (connections[i].status == 3) {
850 if (sendqueue(i) != 0) { 887 if (sendqueue(i) != 0) {
851 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; 888 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;