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.c570
1 files changed, 245 insertions, 325 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 506a06eb..3e71ffbb 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -28,97 +28,6 @@
28 28
29#include "Lossless_UDP.h" 29#include "Lossless_UDP.h"
30 30
31/* maximum data packets in sent and receive queues. */
32#define MAX_QUEUE_NUM 16
33
34/* maximum number of data packets in the buffer */
35#define BUFFER_PACKET_NUM (16-1)
36
37/* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
38#define CONNEXION_TIMEOUT 5
39
40/* initial amount of sync/hanshake packets to send per second. */
41#define SYNC_RATE 2
42
43/* initial send rate of data. */
44#define DATA_SYNC_RATE 30
45
46typedef struct {
47 uint8_t data[MAX_DATA_SIZE];
48 uint16_t size;
49} Data;
50
51typedef struct {
52 IP_Port ip_port;
53
54 /*
55 * 0 if connection is dead, 1 if attempting handshake,
56 * 2 if handshake is done (we start sending SYNC packets)
57 * 3 if we are sending SYNC packets and can send data
58 * 4 if the connection has timed out.
59 */
60 uint8_t status;
61
62 /*
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.
65 */
66 uint8_t inbound;
67
68 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
69 uint16_t data_rate; /* current data packet send rate packets per second. */
70
71 uint64_t last_SYNC; /* time our last SYNC packet was sent. */
72 uint64_t last_sent; /* time our last data or handshake packet was sent. */
73 uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */
74 uint64_t last_recvdata; /* time we last received a DATA packet from the other */
75 uint64_t killat; /* time to kill the connection */
76
77 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
78 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
79
80 uint32_t handshake_id1;
81 uint32_t handshake_id2;
82
83 /* number of data packets received (also used as handshake_id1) */
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. */
113} Connection;
114
115
116static Connection *connections;
117
118static uint32_t connections_length; /* Length of connections array */
119static uint32_t connections_number; /* Number of connections in connections array */
120
121#define MAX_CONNECTIONS connections_length
122 31
123/* Functions */ 32/* Functions */
124 33
@@ -127,22 +36,20 @@ static uint32_t connections_number; /* Number of connections in connections arra
127 * Return -1 if there are no connections like we are looking for 36 * Return -1 if there are no connections like we are looking for
128 * Return id if it found it 37 * Return id if it found it
129 */ 38 */
130int getconnection_id(IP_Port ip_port) 39int getconnection_id(Lossless_UDP * ludp, IP_Port ip_port)
131{ 40{
132 uint32_t i; 41 uint32_t i;
133 42
134 for (i = 0; i < MAX_CONNECTIONS; ++i) { 43 for (i = 0; i < ludp->connections_length; ++i) {
135 if (connections[i].ip_port.ip.i == ip_port.ip.i && 44 if (ludp->connections[i].ip_port.ip.i == ip_port.ip.i &&
136 connections[i].ip_port.port == ip_port.port && 45 ludp->connections[i].ip_port.port == ip_port.port &&
137 connections[i].status > 0) 46 ludp->connections[i].status > 0)
138 return i; 47 return i;
139 } 48 }
140 49
141 return -1; 50 return -1;
142} 51}
143 52
144/* table of random numbers used below. */
145static uint32_t randtable[6][256];
146 53
147/* 54/*
148 * Generate a handshake_id which depends on the ip_port. 55 * Generate a handshake_id which depends on the ip_port.
@@ -150,15 +57,15 @@ static uint32_t randtable[6][256];
150 * 57 *
151 * TODO: make this better 58 * TODO: make this better
152 */ 59 */
153static uint32_t handshake_id(IP_Port source) 60static uint32_t handshake_id(Lossless_UDP * ludp, IP_Port source)
154{ 61{
155 uint32_t id = 0, i; 62 uint32_t id = 0, i;
156 63
157 for (i = 0; i < 6; ++i) { 64 for (i = 0; i < 6; ++i) {
158 if (randtable[i][((uint8_t *)&source)[i]] == 0) 65 if (ludp->randtable[i][((uint8_t *)&source)[i]] == 0)
159 randtable[i][((uint8_t *)&source)[i]] = random_int(); 66 ludp->randtable[i][((uint8_t *)&source)[i]] = random_int();
160 67
161 id ^= randtable[i][((uint8_t *)&source)[i]]; 68 id ^= ludp->randtable[i][((uint8_t *)&source)[i]];
162 } 69 }
163 70
164 if (id == 0) /* id can't be zero */ 71 if (id == 0) /* id can't be zero */
@@ -172,10 +79,10 @@ static uint32_t handshake_id(IP_Port source)
172 * 79 *
173 * TODO: make this better 80 * TODO: make this better
174 */ 81 */
175static void change_handshake(IP_Port source) 82static void change_handshake(Lossless_UDP * ludp, IP_Port source)
176{ 83{
177 uint8_t rand = random_int() % 4; 84 uint8_t rand = random_int() % 4;
178 randtable[rand][((uint8_t *)&source)[rand]] = random_int(); 85 ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int();
179} 86}
180 87
181/* 88/*
@@ -184,33 +91,33 @@ static void change_handshake(IP_Port source)
184 * Return -1 if it could not initialize the connectiont 91 * Return -1 if it could not initialize the connectiont
185 * If there already was an existing connection to that ip_port return its number. 92 * If there already was an existing connection to that ip_port return its number.
186 */ 93 */
187int new_connection(IP_Port ip_port) 94int new_connection(Lossless_UDP * ludp, IP_Port ip_port)
188{ 95{
189 int connect = getconnection_id(ip_port); 96 int connect = getconnection_id(ludp, ip_port);
190 97
191 if (connect != -1) 98 if (connect != -1)
192 return connect; 99 return connect;
193 100
194 if (connections_number == connections_length) { 101 if (ludp->connections_number == ludp->connections_length) {
195 Connection *temp; 102 Connection *temp;
196 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 103 temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1));
197 104
198 if (temp == NULL) 105 if (temp == NULL)
199 return -1; 106 return -1;
200 107
201 memset(&temp[connections_length], 0, sizeof(Connection)); 108 memset(&temp[ludp->connections_length], 0, sizeof(Connection));
202 ++connections_length; 109 ++ludp->connections_length;
203 connections = temp; 110 ludp->connections = temp;
204 } 111 }
205 112
206 uint32_t i; 113 uint32_t i;
207 114
208 for (i = 0; i < MAX_CONNECTIONS; ++i) { 115 for (i = 0; i < ludp->connections_length; ++i) {
209 if (connections[i].status == 0) { 116 if (ludp->connections[i].status == 0) {
210 memset(&connections[i], 0, sizeof(Connection)); 117 memset(&ludp->connections[i], 0, sizeof(Connection));
211 uint32_t handshake_id1 = handshake_id(ip_port); 118 uint32_t handshake_id1 = handshake_id(ludp, ip_port);
212 119
213 connections[i] = (Connection) { 120 ludp->connections[i] = (Connection) {
214 .ip_port = ip_port, 121 .ip_port = ip_port,
215 .status = 1, 122 .status = 1,
216 .inbound = 0, 123 .inbound = 0,
@@ -227,7 +134,7 @@ int new_connection(IP_Port ip_port)
227 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 134 /* add randomness to timeout to prevent connections getting stuck in a loop. */
228 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT 135 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
229 }; 136 };
230 ++connections_number; 137 ++ludp->connections_number;
231 138
232 return i; 139 return i;
233 } 140 }
@@ -241,31 +148,31 @@ int new_connection(IP_Port ip_port)
241 * Returns an integer corresponding to the connection id. 148 * Returns an integer corresponding to the connection id.
242 * Return -1 if it could not initialize the connection. 149 * Return -1 if it could not initialize the connection.
243 */ 150 */
244static int new_inconnection(IP_Port ip_port) 151static int new_inconnection(Lossless_UDP * ludp, IP_Port ip_port)
245{ 152{
246 if (getconnection_id(ip_port) != -1) 153 if (getconnection_id(ludp, ip_port) != -1)
247 return -1; 154 return -1;
248 155
249 if (connections_number == connections_length) { 156 if (ludp->connections_number == ludp->connections_length) {
250 Connection *temp; 157 Connection *temp;
251 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 158 temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1));
252 159
253 if (temp == NULL) 160 if (temp == NULL)
254 return -1; 161 return -1;
255 162
256 memset(&temp[connections_length], 0, sizeof(Connection)); 163 memset(&temp[ludp->connections_length], 0, sizeof(Connection));
257 ++connections_length; 164 ++ludp->connections_length;
258 connections = temp; 165 ludp->connections = temp;
259 } 166 }
260 167
261 uint32_t i; 168 uint32_t i;
262 169
263 for (i = 0; i < MAX_CONNECTIONS; ++i) { 170 for (i = 0; i < ludp->connections_length; ++i) {
264 if (connections[i].status == 0) { 171 if (ludp->connections[i].status == 0) {
265 memset(&connections[i], 0, sizeof(Connection)); 172 memset(&ludp->connections[i], 0, sizeof(Connection));
266 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 173 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
267 174
268 connections[i] = (Connection) { 175 ludp->connections[i] = (Connection) {
269 .ip_port = ip_port, 176 .ip_port = ip_port,
270 .status = 2, 177 .status = 2,
271 .inbound = 2, 178 .inbound = 2,
@@ -281,7 +188,7 @@ static int new_inconnection(IP_Port ip_port)
281 /* if this connection isn't handled within the timeout kill it. */ 188 /* if this connection isn't handled within the timeout kill it. */
282 .killat = current_time() + 1000000UL * timeout 189 .killat = current_time() + 1000000UL * timeout
283 }; 190 };
284 ++connections_number; 191 ++ludp->connections_number;
285 return i; 192 return i;
286 } 193 }
287 } 194 }
@@ -293,13 +200,13 @@ static int new_inconnection(IP_Port ip_port)
293 * Returns an integer corresponding to the next connection in our incoming connection list. 200 * Returns an integer corresponding to the next connection in our incoming connection list.
294 * Return -1 if there are no new incoming connections in the list. 201 * Return -1 if there are no new incoming connections in the list.
295 */ 202 */
296int incoming_connection(void) 203int incoming_connection(Lossless_UDP * ludp)
297{ 204{
298 uint32_t i; 205 uint32_t i;
299 206
300 for (i = 0; i < MAX_CONNECTIONS; ++i) { 207 for (i = 0; i < ludp->connections_length; ++i) {
301 if (connections[i].inbound == 2) { 208 if (ludp->connections[i].inbound == 2) {
302 connections[i].inbound = 1; 209 ludp->connections[i].inbound = 1;
303 return i; 210 return i;
304 } 211 }
305 } 212 }
@@ -308,46 +215,46 @@ int incoming_connection(void)
308} 215}
309 216
310/* Try to free some memory from the connections array. */ 217/* Try to free some memory from the connections array. */
311static void free_connections(void) 218static void free_connections(Lossless_UDP * ludp)
312{ 219{
313 uint32_t i; 220 uint32_t i;
314 221
315 for (i = connections_length; i != 0; --i) 222 for (i = ludp->connections_length; i != 0; --i)
316 if (connections[i - 1].status != 0) 223 if (ludp->connections[i - 1].status != 0)
317 break; 224 break;
318 225
319 if (connections_length == i) 226 if (ludp->connections_length == i)
320 return; 227 return;
321 228
322 if (i == 0) { 229 if (i == 0) {
323 free(connections); 230 free(ludp->connections);
324 connections = NULL; 231 ludp->connections = NULL;
325 connections_length = i; 232 ludp->connections_length = i;
326 return; 233 return;
327 } 234 }
328 235
329 Connection *temp; 236 Connection *temp;
330 temp = realloc(connections, sizeof(Connection) * i); 237 temp = realloc(ludp->connections, sizeof(Connection) * i);
331 238
332 if (temp == NULL && i != 0) 239 if (temp == NULL && i != 0)
333 return; 240 return;
334 241
335 connections = temp; 242 ludp->connections = temp;
336 connections_length = i; 243 ludp->connections_length = i;
337} 244}
338 245
339/* 246/*
340 * Return -1 if it could not kill the connection. 247 * Return -1 if it could not kill the connection.
341 * Return 0 if killed successfully 248 * Return 0 if killed successfully
342 */ 249 */
343int kill_connection(int connection_id) 250int kill_connection(Lossless_UDP * ludp, int connection_id)
344{ 251{
345 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 252 if (connection_id >= 0 && connection_id < ludp->connections_length) {
346 if (connections[connection_id].status > 0) { 253 if (ludp->connections[connection_id].status > 0) {
347 connections[connection_id].status = 0; 254 ludp->connections[connection_id].status = 0;
348 change_handshake(connections[connection_id].ip_port); 255 change_handshake(ludp, ludp->connections[connection_id].ip_port);
349 --connections_number; 256 --ludp->connections_number;
350 free_connections(); 257 free_connections(ludp);
351 return 0; 258 return 0;
352 } 259 }
353 } 260 }
@@ -360,11 +267,11 @@ int kill_connection(int connection_id)
360 * Return -1 if it can not kill the connection. 267 * Return -1 if it can not kill the connection.
361 * Return 0 if it will kill it. 268 * Return 0 if it will kill it.
362 */ 269 */
363int kill_connection_in(int connection_id, uint32_t seconds) 270int kill_connection_in(Lossless_UDP * ludp, int connection_id, uint32_t seconds)
364{ 271{
365 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 272 if (connection_id >= 0 && connection_id < ludp->connections_length) {
366 if (connections[connection_id].status > 0) { 273 if (ludp->connections[connection_id].status > 0) {
367 connections[connection_id].killat = current_time() + 1000000UL * seconds; 274 ludp->connections[connection_id].killat = current_time() + 1000000UL * seconds;
368 return 0; 275 return 0;
369 } 276 }
370 } 277 }
@@ -380,65 +287,65 @@ int kill_connection_in(int connection_id, uint32_t seconds)
380 * Return 3 if fully connected. 287 * Return 3 if fully connected.
381 * Return 4 if timed out and waiting to be killed. 288 * Return 4 if timed out and waiting to be killed.
382 */ 289 */
383int is_connected(int connection_id) 290int is_connected(Lossless_UDP * ludp, int connection_id)
384{ 291{
385 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 292 if (connection_id >= 0 && connection_id < ludp->connections_length)
386 return connections[connection_id].status; 293 return ludp->connections[connection_id].status;
387 294
388 return 0; 295 return 0;
389} 296}
390 297
391/* returns the ip_port of the corresponding connection. */ 298/* returns the ip_port of the corresponding connection. */
392IP_Port connection_ip(int connection_id) 299IP_Port connection_ip(Lossless_UDP * ludp, int connection_id)
393{ 300{
394 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 301 if (connection_id >= 0 && connection_id < ludp->connections_length)
395 return connections[connection_id].ip_port; 302 return ludp->connections[connection_id].ip_port;
396 303
397 IP_Port zero = {{{0}}, 0}; 304 IP_Port zero = {{{0}}, 0};
398 return zero; 305 return zero;
399} 306}
400 307
401/* returns the number of packets in the queue waiting to be successfully sent. */ 308/* returns the number of packets in the queue waiting to be successfully sent. */
402uint32_t sendqueue(int connection_id) 309uint32_t sendqueue(Lossless_UDP * ludp, int connection_id)
403{ 310{
404 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 311 if (connection_id < 0 || connection_id >= ludp->connections_length)
405 return 0; 312 return 0;
406 313
407 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; 314 return ludp->connections[connection_id].sendbuff_packetnum - ludp->connections[connection_id].successful_sent;
408} 315}
409 316
410/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ 317/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
411uint32_t recvqueue(int connection_id) 318uint32_t recvqueue(Lossless_UDP * ludp, int connection_id)
412{ 319{
413 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 320 if (connection_id < 0 || connection_id >= ludp->connections_length)
414 return 0; 321 return 0;
415 322
416 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; 323 return ludp->connections[connection_id].recv_packetnum - ludp->connections[connection_id].successful_read;
417} 324}
418 325
419/* returns the id of the next packet in the queue 326/* returns the id of the next packet in the queue
420 return -1 if no packet in queue */ 327 return -1 if no packet in queue */
421char id_packet(int connection_id) 328char id_packet(Lossless_UDP * ludp, int connection_id)
422{ 329{
423 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 330 if (connection_id < 0 || connection_id >= ludp->connections_length)
424 return -1; 331 return -1;
425 332
426 if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) 333 if (recvqueue(ludp, connection_id) != 0 && ludp->connections[connection_id].status != 0)
427 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; 334 return ludp->connections[connection_id].recvbuffer[ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
428 335
429 return -1; 336 return -1;
430} 337}
431 338
432/* return 0 if there is no received data in the buffer. 339/* return 0 if there is no received data in the buffer.
433 return length of received packet if successful */ 340 return length of received packet if successful */
434int read_packet(int connection_id, uint8_t *data) 341int read_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data)
435{ 342{
436 if (recvqueue(connection_id) != 0) { 343 if (recvqueue(ludp, connection_id) != 0) {
437 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 344 uint16_t index = ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM;
438 uint16_t size = connections[connection_id].recvbuffer[index].size; 345 uint16_t size = ludp->connections[connection_id].recvbuffer[index].size;
439 memcpy(data, connections[connection_id].recvbuffer[index].data, size); 346 memcpy(data, ludp->connections[connection_id].recvbuffer[index].data, size);
440 ++connections[connection_id].successful_read; 347 ++ludp->connections[connection_id].successful_read;
441 connections[connection_id].recvbuffer[index].size = 0; 348 ludp->connections[connection_id].recvbuffer[index].size = 0;
442 return size; 349 return size;
443 } 350 }
444 351
@@ -449,16 +356,16 @@ int read_packet(int connection_id, uint8_t *data)
449 * Return 0 if data could not be put in packet queue 356 * Return 0 if data could not be put in packet queue
450 * Return 1 if data was put into the queue 357 * Return 1 if data was put into the queue
451 */ 358 */
452int write_packet(int connection_id, uint8_t *data, uint32_t length) 359int write_packet(Lossless_UDP * ludp, int connection_id, uint8_t *data, uint32_t length)
453{ 360{
454 if (length > MAX_DATA_SIZE || length == 0) 361 if (length > MAX_DATA_SIZE || length == 0)
455 return 0; 362 return 0;
456 363
457 if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { 364 if (sendqueue(ludp, connection_id) < BUFFER_PACKET_NUM) {
458 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; 365 uint32_t index = ludp->connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
459 memcpy(connections[connection_id].sendbuffer[index].data, data, length); 366 memcpy(ludp->connections[connection_id].sendbuffer[index].data, data, length);
460 connections[connection_id].sendbuffer[index].size = length; 367 ludp->connections[connection_id].sendbuffer[index].size = length;
461 connections[connection_id].sendbuff_packetnum++; 368 ludp->connections[connection_id].sendbuff_packetnum++;
462 return 1; 369 return 1;
463 } 370 }
464 371
@@ -466,18 +373,18 @@ int write_packet(int connection_id, uint8_t *data, uint32_t length)
466} 373}
467 374
468/* put the packet numbers the we are missing in requested and return the number */ 375/* put the packet numbers the we are missing in requested and return the number */
469uint32_t missing_packets(int connection_id, uint32_t *requested) 376uint32_t missing_packets(Lossless_UDP * ludp, int connection_id, uint32_t *requested)
470{ 377{
471 uint32_t number = 0; 378 uint32_t number = 0;
472 uint32_t i; 379 uint32_t i;
473 uint32_t temp; 380 uint32_t temp;
474 381
475 /* don't request packets if the buffer is full. */ 382 /* don't request packets if the buffer is full. */
476 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) 383 if (recvqueue(ludp, connection_id) >= (BUFFER_PACKET_NUM - 1))
477 return 0; 384 return 0;
478 385
479 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { 386 for (i = ludp->connections[connection_id].recv_packetnum; i != ludp->connections[connection_id].osent_packetnum; i++) {
480 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { 387 if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
481 temp = htonl(i); 388 temp = htonl(i);
482 memcpy(requested + number, &temp, 4); 389 memcpy(requested + number, &temp, 4);
483 ++number; 390 ++number;
@@ -485,7 +392,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested)
485 } 392 }
486 393
487 if (number == 0) 394 if (number == 0)
488 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; 395 ludp->connections[connection_id].recv_packetnum = ludp->connections[connection_id].osent_packetnum;
489 396
490 return number; 397 return number;
491} 398}
@@ -496,7 +403,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested)
496 * see http://wiki.tox.im/index.php/Lossless_UDP for more information. 403 * see http://wiki.tox.im/index.php/Lossless_UDP for more information.
497 */ 404 */
498 405
499static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) 406static int send_handshake(Lossless_UDP * ludp, IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)
500{ 407{
501 uint8_t packet[1 + 4 + 4]; 408 uint8_t packet[1 + 4 + 4];
502 uint32_t temp; 409 uint32_t temp;
@@ -507,21 +414,21 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand
507 temp = htonl(handshake_id2); 414 temp = htonl(handshake_id2);
508 memcpy(packet + 5, &temp, 4); 415 memcpy(packet + 5, &temp, 4);
509 416
510 return sendpacket(ip_port, packet, sizeof(packet)); 417 return sendpacket(ludp->net->sock, ip_port, packet, sizeof(packet));
511} 418}
512 419
513static int send_SYNC(uint32_t connection_id) 420static int send_SYNC(Lossless_UDP * ludp, uint32_t connection_id)
514{ 421{
515 uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; 422 uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)];
516 uint16_t index = 0; 423 uint16_t index = 0;
517 424
518 IP_Port ip_port = connections[connection_id].ip_port; 425 IP_Port ip_port = ludp->connections[connection_id].ip_port;
519 uint8_t counter = connections[connection_id].send_counter; 426 uint8_t counter = ludp->connections[connection_id].send_counter;
520 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); 427 uint32_t recv_packetnum = htonl(ludp->connections[connection_id].recv_packetnum);
521 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); 428 uint32_t sent_packetnum = htonl(ludp->connections[connection_id].sent_packetnum);
522 429
523 uint32_t requested[BUFFER_PACKET_NUM]; 430 uint32_t requested[BUFFER_PACKET_NUM];
524 uint32_t number = missing_packets(connection_id, requested); 431 uint32_t number = missing_packets(ludp, connection_id, requested);
525 432
526 packet[0] = 17; 433 packet[0] = 17;
527 index += 1; 434 index += 1;
@@ -533,11 +440,11 @@ static int send_SYNC(uint32_t connection_id)
533 index += 4; 440 index += 4;
534 memcpy(packet + index, requested, 4 * number); 441 memcpy(packet + index, requested, 4 * number);
535 442
536 return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2)); 443 return sendpacket(ludp->net->sock, ip_port, packet, (number * 4 + 4 + 4 + 2));
537 444
538} 445}
539 446
540static int send_data_packet(uint32_t connection_id, uint32_t packet_num) 447static int send_data_packet(Lossless_UDP * ludp, uint32_t connection_id, uint32_t packet_num)
541{ 448{
542 uint32_t index = packet_num % MAX_QUEUE_NUM; 449 uint32_t index = packet_num % MAX_QUEUE_NUM;
543 uint32_t temp; 450 uint32_t temp;
@@ -545,29 +452,29 @@ static int send_data_packet(uint32_t connection_id, uint32_t packet_num)
545 packet[0] = 18; 452 packet[0] = 18;
546 temp = htonl(packet_num); 453 temp = htonl(packet_num);
547 memcpy(packet + 1, &temp, 4); 454 memcpy(packet + 1, &temp, 4);
548 memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, 455 memcpy(packet + 5, ludp->connections[connection_id].sendbuffer[index].data,
549 connections[connection_id].sendbuffer[index].size); 456 ludp->connections[connection_id].sendbuffer[index].size);
550 return sendpacket(connections[connection_id].ip_port, packet, 457 return sendpacket(ludp->net->sock, ludp->connections[connection_id].ip_port, packet,
551 1 + 4 + connections[connection_id].sendbuffer[index].size); 458 1 + 4 + ludp->connections[connection_id].sendbuffer[index].size);
552} 459}
553 460
554/* sends 1 data packet */ 461/* sends 1 data packet */
555static int send_DATA(uint32_t connection_id) 462static int send_DATA(Lossless_UDP * ludp, uint32_t connection_id)
556{ 463{
557 int ret; 464 int ret;
558 uint32_t buffer[BUFFER_PACKET_NUM]; 465 uint32_t buffer[BUFFER_PACKET_NUM];
559 466
560 if (connections[connection_id].num_req_paquets > 0) { 467 if (ludp->connections[connection_id].num_req_paquets > 0) {
561 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); 468 ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].req_packets[0]);
562 connections[connection_id].num_req_paquets--; 469 ludp->connections[connection_id].num_req_paquets--;
563 memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); 470 memcpy(buffer, ludp->connections[connection_id].req_packets + 1, ludp->connections[connection_id].num_req_paquets * 4);
564 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); 471 memcpy(ludp->connections[connection_id].req_packets, buffer, ludp->connections[connection_id].num_req_paquets * 4);
565 return ret; 472 return ret;
566 } 473 }
567 474
568 if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { 475 if (ludp->connections[connection_id].sendbuff_packetnum != ludp->connections[connection_id].sent_packetnum) {
569 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); 476 ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].sent_packetnum);
570 connections[connection_id].sent_packetnum++; 477 ludp->connections[connection_id].sent_packetnum++;
571 return ret; 478 return ret;
572 } 479 }
573 480
@@ -584,37 +491,38 @@ static int send_DATA(uint32_t connection_id)
584 491
585 492
586/* Return 0 if handled correctly, 1 if packet is bad. */ 493/* Return 0 if handled correctly, 1 if packet is bad. */
587static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length) 494static int handle_handshake(void * object, IP_Port source, uint8_t *packet, uint32_t length)
588{ 495{
496 Lossless_UDP * ludp = object;
589 if (length != (1 + 4 + 4)) 497 if (length != (1 + 4 + 4))
590 return 1; 498 return 1;
591 499
592 uint32_t temp; 500 uint32_t temp;
593 uint32_t handshake_id1, handshake_id2; 501 uint32_t handshake_id1, handshake_id2;
594 502
595 int connection = getconnection_id(source); 503 int connection = getconnection_id(ludp, source);
596 memcpy(&temp, packet + 1, 4); 504 memcpy(&temp, packet + 1, 4);
597 handshake_id1 = ntohl(temp); 505 handshake_id1 = ntohl(temp);
598 memcpy(&temp, packet + 5, 4); 506 memcpy(&temp, packet + 5, 4);
599 handshake_id2 = ntohl(temp); 507 handshake_id2 = ntohl(temp);
600 508
601 if (handshake_id2 == 0 && is_connected(connection) < 3) { 509 if (handshake_id2 == 0 && is_connected(ludp, connection) < 3) {
602 send_handshake(source, handshake_id(source), handshake_id1); 510 send_handshake(ludp, source, handshake_id(ludp, source), handshake_id1);
603 return 0; 511 return 0;
604 } 512 }
605 513
606 if (is_connected(connection) != 1) 514 if (is_connected(ludp, connection) != 1)
607 return 1; 515 return 1;
608 516
609 /* if handshake_id2 is what we sent previously as handshake_id1 */ 517 /* if handshake_id2 is what we sent previously as handshake_id1 */
610 if (handshake_id2 == connections[connection].handshake_id1) { 518 if (handshake_id2 == ludp->connections[connection].handshake_id1) {
611 connections[connection].status = 2; 519 ludp->connections[connection].status = 2;
612 /* NOTE: is this necessary? 520 /* NOTE: is this necessary?
613 connections[connection].handshake_id2 = handshake_id1; */ 521 ludp->connections[connection].handshake_id2 = handshake_id1; */
614 connections[connection].orecv_packetnum = handshake_id2; 522 ludp->connections[connection].orecv_packetnum = handshake_id2;
615 connections[connection].osent_packetnum = handshake_id1; 523 ludp->connections[connection].osent_packetnum = handshake_id1;
616 connections[connection].recv_packetnum = handshake_id1; 524 ludp->connections[connection].recv_packetnum = handshake_id1;
617 connections[connection].successful_read = handshake_id1; 525 ludp->connections[connection].successful_read = handshake_id1;
618 } 526 }
619 527
620 return 0; 528 return 0;
@@ -634,19 +542,19 @@ static int SYNC_valid(uint32_t length)
634} 542}
635 543
636/* case 1 in handle_SYNC: */ 544/* case 1 in handle_SYNC: */
637static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) 545static int handle_SYNC1(Lossless_UDP * ludp, IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
638{ 546{
639 if (handshake_id(source) == recv_packetnum) { 547 if (handshake_id(ludp, source) == recv_packetnum) {
640 int x = new_inconnection(source); 548 int x = new_inconnection(ludp, source);
641 549
642 if (x != -1) { 550 if (x != -1) {
643 connections[x].orecv_packetnum = recv_packetnum; 551 ludp->connections[x].orecv_packetnum = recv_packetnum;
644 connections[x].sent_packetnum = recv_packetnum; 552 ludp->connections[x].sent_packetnum = recv_packetnum;
645 connections[x].sendbuff_packetnum = recv_packetnum; 553 ludp->connections[x].sendbuff_packetnum = recv_packetnum;
646 connections[x].successful_sent = recv_packetnum; 554 ludp->connections[x].successful_sent = recv_packetnum;
647 connections[x].osent_packetnum = sent_packetnum; 555 ludp->connections[x].osent_packetnum = sent_packetnum;
648 connections[x].recv_packetnum = sent_packetnum; 556 ludp->connections[x].recv_packetnum = sent_packetnum;
649 connections[x].successful_read = sent_packetnum; 557 ludp->connections[x].successful_read = sent_packetnum;
650 558
651 return x; 559 return x;
652 } 560 }
@@ -656,63 +564,63 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
656} 564}
657 565
658/* case 2 in handle_SYNC: */ 566/* case 2 in handle_SYNC: */
659static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 567static int handle_SYNC2(Lossless_UDP * ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
660{ 568{
661 if (recv_packetnum == connections[connection_id].orecv_packetnum) { 569 if (recv_packetnum == ludp->connections[connection_id].orecv_packetnum) {
662 /* && sent_packetnum == connections[connection_id].osent_packetnum) */ 570 /* && sent_packetnum == ludp->connections[connection_id].osent_packetnum) */
663 connections[connection_id].status = 3; 571 ludp->connections[connection_id].status = 3;
664 connections[connection_id].recv_counter = counter; 572 ludp->connections[connection_id].recv_counter = counter;
665 ++connections[connection_id].send_counter; 573 ++ludp->connections[connection_id].send_counter;
666 send_SYNC(connection_id); 574 send_SYNC(ludp, connection_id);
667 return 0; 575 return 0;
668 } 576 }
669 577
670 return 1; 578 return 1;
671} 579}
672/* case 3 in handle_SYNC: */ 580/* case 3 in handle_SYNC: */
673static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, 581static int handle_SYNC3(Lossless_UDP * ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum,
674 uint32_t *req_packets, 582 uint32_t *req_packets,
675 uint16_t number) 583 uint16_t number)
676{ 584{
677 uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); 585 uint8_t comp_counter = (counter - ludp->connections[connection_id].recv_counter );
678 uint32_t i, temp; 586 uint32_t i, temp;
679 /* uint32_t comp_1 = (recv_packetnum - connections[connection_id].successful_sent); 587 /* uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].successful_sent);
680 uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ 588 uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].successful_read); */
681 uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); 589 uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].orecv_packetnum);
682 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); 590 uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].osent_packetnum);
683 591
684 /* packet valid */ 592 /* packet valid */
685 if (comp_1 <= BUFFER_PACKET_NUM && 593 if (comp_1 <= BUFFER_PACKET_NUM &&
686 comp_2 <= BUFFER_PACKET_NUM && 594 comp_2 <= BUFFER_PACKET_NUM &&
687 comp_counter < 10 && comp_counter != 0) { 595 comp_counter < 10 && comp_counter != 0) {
688 596
689 connections[connection_id].orecv_packetnum = recv_packetnum; 597 ludp->connections[connection_id].orecv_packetnum = recv_packetnum;
690 connections[connection_id].osent_packetnum = sent_packetnum; 598 ludp->connections[connection_id].osent_packetnum = sent_packetnum;
691 connections[connection_id].successful_sent = recv_packetnum; 599 ludp->connections[connection_id].successful_sent = recv_packetnum;
692 connections[connection_id].last_recvSYNC = current_time(); 600 ludp->connections[connection_id].last_recvSYNC = current_time();
693 connections[connection_id].recv_counter = counter; 601 ludp->connections[connection_id].recv_counter = counter;
694 602
695 ++connections[connection_id].send_counter; 603 ++ludp->connections[connection_id].send_counter;
696 604
697 for (i = 0; i < number; ++i) { 605 for (i = 0; i < number; ++i) {
698 temp = ntohl(req_packets[i]); 606 temp = ntohl(req_packets[i]);
699 memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); 607 memcpy(ludp->connections[connection_id].req_packets + i, &temp, 4 * number);
700 } 608 }
701 609
702 connections[connection_id].num_req_paquets = number; 610 ludp->connections[connection_id].num_req_paquets = number;
703 return 0; 611 return 0;
704 } 612 }
705 613
706 return 1; 614 return 1;
707} 615}
708 616
709static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) 617static int handle_SYNC(void * object, IP_Port source, uint8_t *packet, uint32_t length)
710{ 618{
711 619 Lossless_UDP * ludp = object;
712 if (!SYNC_valid(length)) 620 if (!SYNC_valid(length))
713 return 1; 621 return 1;
714 622
715 int connection = getconnection_id(source); 623 int connection = getconnection_id(ludp, source);
716 uint8_t counter; 624 uint8_t counter;
717 uint32_t temp; 625 uint32_t temp;
718 uint32_t recv_packetnum, sent_packetnum; 626 uint32_t recv_packetnum, sent_packetnum;
@@ -729,14 +637,14 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
729 memcpy(req_packets, packet + 10, 4 * number); 637 memcpy(req_packets, packet + 10, 4 * number);
730 638
731 if (connection == -1) 639 if (connection == -1)
732 return handle_SYNC1(source, recv_packetnum, sent_packetnum); 640 return handle_SYNC1(ludp, source, recv_packetnum, sent_packetnum);
733 641
734 if (connections[connection].status == 2) 642 if (ludp->connections[connection].status == 2)
735 return handle_SYNC2(connection, counter, 643 return handle_SYNC2(ludp, connection, counter,
736 recv_packetnum, sent_packetnum); 644 recv_packetnum, sent_packetnum);
737 645
738 if (connections[connection].status == 3) 646 if (ludp->connections[connection].status == 3)
739 return handle_SYNC3(connection, counter, recv_packetnum, 647 return handle_SYNC3(ludp, connection, counter, recv_packetnum,
740 sent_packetnum, req_packets, number); 648 sent_packetnum, req_packets, number);
741 649
742 return 0; 650 return 0;
@@ -746,33 +654,33 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
746 * Add a packet to the received buffer and set the recv_packetnum of the 654 * Add a packet to the received buffer and set the recv_packetnum of the
747 * connection to its proper value. Return 1 if data was too big, 0 if not. 655 * connection to its proper value. Return 1 if data was too big, 0 if not.
748 */ 656 */
749static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) 657static int add_recv(Lossless_UDP * ludp, int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
750{ 658{
751 if (size > MAX_DATA_SIZE) 659 if (size > MAX_DATA_SIZE)
752 return 1; 660 return 1;
753 661
754 uint32_t i; 662 uint32_t i;
755 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; 663 uint32_t maxnum = ludp->connections[connection_id].successful_read + BUFFER_PACKET_NUM;
756 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; 664 uint32_t sent_packet = data_num - ludp->connections[connection_id].osent_packetnum;
757 665
758 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 666 for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) {
759 if (i == data_num) { 667 if (i == data_num) {
760 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); 668 memcpy(ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
761 669
762 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; 670 ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
763 connections[connection_id].last_recvdata = current_time(); 671 ludp->connections[connection_id].last_recvdata = current_time();
764 672
765 if (sent_packet < BUFFER_PACKET_NUM) { 673 if (sent_packet < BUFFER_PACKET_NUM) {
766 connections[connection_id].osent_packetnum = data_num; 674 ludp->connections[connection_id].osent_packetnum = data_num;
767 } 675 }
768 676
769 break; 677 break;
770 } 678 }
771 } 679 }
772 680
773 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 681 for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) {
774 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) 682 if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
775 connections[connection_id].recv_packetnum = i; 683 ludp->connections[connection_id].recv_packetnum = i;
776 else 684 else
777 break; 685 break;
778 } 686 }
@@ -780,15 +688,16 @@ static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_
780 return 0; 688 return 0;
781} 689}
782 690
783static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) 691static int handle_data(void * object, IP_Port source, uint8_t *packet, uint32_t length)
784{ 692{
785 int connection = getconnection_id(source); 693 Lossless_UDP * ludp = object;
694 int connection = getconnection_id(ludp, source);
786 695
787 if (connection == -1) 696 if (connection == -1)
788 return 1; 697 return 1;
789 698
790 /* Drop the data packet if connection is not connected. */ 699 /* Drop the data packet if connection is not connected. */
791 if (connections[connection].status != 3) 700 if (ludp->connections[connection].status != 3)
792 return 1; 701 return 1;
793 702
794 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) 703 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
@@ -801,76 +710,81 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length)
801 memcpy(&temp, packet + 1, 4); 710 memcpy(&temp, packet + 1, 4);
802 number = ntohl(temp); 711 number = ntohl(temp);
803 712
804 return add_recv(connection, number, packet + 5, size); 713 return add_recv(ludp, connection, number, packet + 5, size);
805} 714}
806 715
807/* 716/*
808 * END of packet handling functions 717 * END of packet handling functions
809 */ 718 */
810 719
811void LosslessUDP_init(void) 720Lossless_UDP * new_lossless_udp(Networking_Core * net)
812{ 721{
813 networking_registerhandler(16, &handle_handshake); 722 Lossless_UDP * temp = calloc(1, sizeof(Lossless_UDP));
814 networking_registerhandler(17, &handle_SYNC); 723 if (temp == NULL)
815 networking_registerhandler(18, &handle_data); 724 return NULL;
725 temp->net = net;
726 networking_registerhandler(net, 16, &handle_handshake, temp);
727 networking_registerhandler(net, 17, &handle_SYNC, temp);
728 networking_registerhandler(net, 18, &handle_data, temp);
729 return temp;
816} 730}
817 731
818/* 732/*
819 * Send handshake requests 733 * Send handshake requests
820 * handshake packets are sent at the same rate as SYNC packets 734 * handshake packets are sent at the same rate as SYNC packets
821 */ 735 */
822static void doNew(void) 736static void do_new(Lossless_UDP * ludp)
823{ 737{
824 uint32_t i; 738 uint32_t i;
825 uint64_t temp_time = current_time(); 739 uint64_t temp_time = current_time();
826 740
827 for (i = 0; i < MAX_CONNECTIONS; ++i) { 741 for (i = 0; i < ludp->connections_length; ++i) {
828 if (connections[i].status == 1) 742 if (ludp->connections[i].status == 1)
829 if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { 743 if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) {
830 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); 744 send_handshake(ludp, ludp->connections[i].ip_port, ludp->connections[i].handshake_id1, 0);
831 connections[i].last_sent = temp_time; 745 ludp->connections[i].last_sent = temp_time;
832 } 746 }
833 747
834 /* kill all timed out connections */ 748 /* kill all timed out connections */
835 if (connections[i].status > 0 && 749 if (ludp->connections[i].status > 0 &&
836 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 750 (ludp->connections[i].last_recvSYNC + ludp->connections[i].timeout * 1000000UL) < temp_time &&
837 connections[i].status != 4) { 751 ludp->connections[i].status != 4) {
838 connections[i].status = 4; 752 ludp->connections[i].status = 4;
839 /* kill_connection(i); */ 753 /* kill_connection(i); */
840 } 754 }
841 755
842 if (connections[i].status > 0 && connections[i].killat < temp_time) 756 if (ludp->connections[i].status > 0 && ludp->connections[i].killat < temp_time)
843 kill_connection(i); 757 kill_connection(ludp, i);
844 } 758 }
845} 759}
846 760
847static void doSYNC(void) 761static void do_SYNC(Lossless_UDP * ludp)
848{ 762{
849 uint32_t i; 763 uint32_t i;
850 uint64_t temp_time = current_time(); 764 uint64_t temp_time = current_time();
851 765
852 for (i = 0; i < MAX_CONNECTIONS; ++i) { 766 for (i = 0; i < ludp->connections_length; ++i) {
853 if (connections[i].status == 2 || connections[i].status == 3) 767 if (ludp->connections[i].status == 2 || ludp->connections[i].status == 3)
854 if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { 768 if ((ludp->connections[i].last_SYNC + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) {
855 send_SYNC(i); 769 send_SYNC(ludp, i);
856 connections[i].last_SYNC = temp_time; 770 ludp->connections[i].last_SYNC = temp_time;
857 } 771 }
858 } 772 }
859} 773}
860 774
861static void doData(void) 775static void do_data(Lossless_UDP * ludp)
862{ 776{
863 uint32_t i; 777 uint32_t i;
864 uint64_t j; 778 uint64_t j;
865 uint64_t temp_time = current_time(); 779 uint64_t temp_time = current_time();
866 780
867 for (i = 0; i < MAX_CONNECTIONS; ++i) 781 for (i = 0; i < ludp->connections_length; ++i)
868 if (connections[i].status == 3 && sendqueue(i) != 0) 782 if (ludp->connections[i].status == 3 && sendqueue(ludp, i) != 0)
869 if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) { 783 if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].data_rate)) <= temp_time) {
870 for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate)) 784 for (j = ludp->connections[i].last_sent; j < temp_time; j += (1000000UL / ludp->connections[i].data_rate))
871 send_DATA(i); 785 send_DATA(ludp, i);
872 786
873 connections[i].last_sent = temp_time; 787 ludp->connections[i].last_sent = temp_time;
874 } 788 }
875} 789}
876 790
@@ -881,32 +795,38 @@ static void doData(void)
881 * 795 *
882 * TODO: flow control. 796 * TODO: flow control.
883 */ 797 */
884static void adjustRates(void) 798static void adjust_rates(Lossless_UDP * ludp)
885{ 799{
886 uint32_t i; 800 uint32_t i;
887 uint64_t temp_time = current_time(); 801 uint64_t temp_time = current_time();
888 802
889 for (i = 0; i < MAX_CONNECTIONS; ++i) { 803 for (i = 0; i < ludp->connections_length; ++i) {
890 if (connections[i].status == 1 || connections[i].status == 2) 804 if (ludp->connections[i].status == 1 || ludp->connections[i].status == 2)
891 connections[i].SYNC_rate = MAX_SYNC_RATE; 805 ludp->connections[i].SYNC_rate = MAX_SYNC_RATE;
892 806
893 if (connections[i].status == 3) { 807 if (ludp->connections[i].status == 3) {
894 if (sendqueue(i) != 0) { 808 if (sendqueue(ludp, i) != 0) {
895 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; 809 ludp->connections[i].data_rate = (BUFFER_PACKET_NUM - ludp->connections[i].num_req_paquets) * MAX_SYNC_RATE;
896 connections[i].SYNC_rate = MAX_SYNC_RATE; 810 ludp->connections[i].SYNC_rate = MAX_SYNC_RATE;
897 } else if (connections[i].last_recvdata + 1000000UL > temp_time) 811 } else if (ludp->connections[i].last_recvdata + 1000000UL > temp_time)
898 connections[i].SYNC_rate = MAX_SYNC_RATE; 812 ludp->connections[i].SYNC_rate = MAX_SYNC_RATE;
899 else 813 else
900 connections[i].SYNC_rate = SYNC_RATE; 814 ludp->connections[i].SYNC_rate = SYNC_RATE;
901 } 815 }
902 } 816 }
903} 817}
904 818
905/* Call this function a couple times per second It's the main loop. */ 819/* Call this function a couple times per second It's the main loop. */
906void doLossless_UDP(void) 820void do_lossless_udp(Lossless_UDP * ludp)
907{ 821{
908 doNew(); 822 do_new(ludp);
909 doSYNC(); 823 do_SYNC(ludp);
910 doData(); 824 do_data(ludp);
911 adjustRates(); 825 adjust_rates(ludp);
912} 826}
827
828void kill_lossless_udp(Lossless_UDP * ludp)
829{
830 free(ludp->connections);
831 free(ludp);
832} \ No newline at end of file