diff options
Diffstat (limited to 'core/Lossless_UDP.c')
-rw-r--r-- | core/Lossless_UDP.c | 570 |
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 | |||
46 | typedef struct { | ||
47 | uint8_t data[MAX_DATA_SIZE]; | ||
48 | uint16_t size; | ||
49 | } Data; | ||
50 | |||
51 | typedef 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 | |||
116 | static Connection *connections; | ||
117 | |||
118 | static uint32_t connections_length; /* Length of connections array */ | ||
119 | static 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 | */ |
130 | int getconnection_id(IP_Port ip_port) | 39 | int 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. */ | ||
145 | static 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 | */ |
153 | static uint32_t handshake_id(IP_Port source) | 60 | static 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 | */ |
175 | static void change_handshake(IP_Port source) | 82 | static 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 | */ |
187 | int new_connection(IP_Port ip_port) | 94 | int 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 | */ |
244 | static int new_inconnection(IP_Port ip_port) | 151 | static 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 | */ |
296 | int incoming_connection(void) | 203 | int 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. */ |
311 | static void free_connections(void) | 218 | static 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 | */ |
343 | int kill_connection(int connection_id) | 250 | int 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 | */ |
363 | int kill_connection_in(int connection_id, uint32_t seconds) | 270 | int 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 | */ |
383 | int is_connected(int connection_id) | 290 | int 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. */ |
392 | IP_Port connection_ip(int connection_id) | 299 | IP_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. */ |
402 | uint32_t sendqueue(int connection_id) | 309 | uint32_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(...) */ |
411 | uint32_t recvqueue(int connection_id) | 318 | uint32_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 */ |
421 | char id_packet(int connection_id) | 328 | char 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 */ |
434 | int read_packet(int connection_id, uint8_t *data) | 341 | int 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 | */ |
452 | int write_packet(int connection_id, uint8_t *data, uint32_t length) | 359 | int 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 */ |
469 | uint32_t missing_packets(int connection_id, uint32_t *requested) | 376 | uint32_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 | ||
499 | static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 406 | static 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 | ||
513 | static int send_SYNC(uint32_t connection_id) | 420 | static 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 | ||
540 | static int send_data_packet(uint32_t connection_id, uint32_t packet_num) | 447 | static 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 */ |
555 | static int send_DATA(uint32_t connection_id) | 462 | static 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. */ |
587 | static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length) | 494 | static 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: */ |
637 | static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 545 | static 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: */ |
659 | static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 567 | static 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: */ |
673 | static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, | 581 | static 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 | ||
709 | static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | 617 | static 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 | */ |
749 | static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | 657 | static 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 | ||
783 | static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) | 691 | static 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 | ||
811 | void LosslessUDP_init(void) | 720 | Lossless_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 | */ |
822 | static void doNew(void) | 736 | static 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 | ||
847 | static void doSYNC(void) | 761 | static 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 | ||
861 | static void doData(void) | 775 | static 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 | */ |
884 | static void adjustRates(void) | 798 | static 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. */ |
906 | void doLossless_UDP(void) | 820 | void 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 | |||
828 | void kill_lossless_udp(Lossless_UDP * ludp) | ||
829 | { | ||
830 | free(ludp->connections); | ||
831 | free(ludp); | ||
832 | } \ No newline at end of file | ||