diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 157 | ||||
-rw-r--r-- | toxcore/Lossless_UDP.c | 292 | ||||
-rw-r--r-- | toxcore/Lossless_UDP.h | 52 | ||||
-rw-r--r-- | toxcore/Messenger.c | 88 | ||||
-rw-r--r-- | toxcore/Messenger.h | 22 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 69 | ||||
-rw-r--r-- | toxcore/net_crypto.h | 5 | ||||
-rw-r--r-- | toxcore/network.c | 68 | ||||
-rw-r--r-- | toxcore/network.h | 9 | ||||
-rw-r--r-- | toxcore/tox.c | 38 | ||||
-rw-r--r-- | toxcore/tox.h | 35 |
11 files changed, 661 insertions, 174 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 1761f50b..ad4c8a1d 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -131,14 +131,32 @@ static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout) | |||
131 | * | 131 | * |
132 | * return True(1) or False(0) | 132 | * return True(1) or False(0) |
133 | */ | 133 | */ |
134 | static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port) | 134 | static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port) |
135 | { | 135 | { |
136 | uint32_t i; | 136 | uint32_t i; |
137 | uint64_t temp_time = unix_time(); | 137 | uint64_t temp_time = unix_time(); |
138 | 138 | ||
139 | uint8_t candropipv4 = 1; | ||
140 | if (ip_port.ip.family == AF_INET6) { | ||
141 | uint8_t ipv6cnt = 0; | ||
142 | |||
143 | /* ipv6: count how many spots are used */ | ||
144 | for(i = 0; i < length; i++) | ||
145 | if (list[i].ip_port.ip.family == AF_INET6) | ||
146 | ipv6cnt++; | ||
147 | |||
148 | /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ | ||
149 | if (ipv6cnt > length / 2) | ||
150 | candropipv4 = 0; | ||
151 | } | ||
152 | |||
139 | /* if client_id is in list, find it and maybe overwrite ip_port */ | 153 | /* if client_id is in list, find it and maybe overwrite ip_port */ |
140 | for (i = 0; i < length; ++i) | 154 | for (i = 0; i < length; ++i) |
141 | if (id_equal(list[i].client_id, client_id)) { | 155 | if (id_equal(list[i].client_id, client_id)) { |
156 | /* if we got "too many" ipv6 addresses already, keep the ipv4 address */ | ||
157 | if (!candropipv4 && (list[i].ip_port.ip.family == AF_INET)) | ||
158 | return 1; | ||
159 | |||
142 | /* Refresh the client timestamp. */ | 160 | /* Refresh the client timestamp. */ |
143 | list[i].timestamp = temp_time; | 161 | list[i].timestamp = temp_time; |
144 | list[i].ip_port = ip_port; | 162 | list[i].ip_port = ip_port; |
@@ -299,15 +317,31 @@ static int replace_bad( Client_data *list, | |||
299 | uint32_t i; | 317 | uint32_t i; |
300 | uint64_t temp_time = unix_time(); | 318 | uint64_t temp_time = unix_time(); |
301 | 319 | ||
320 | uint8_t candropipv4 = 1; | ||
321 | if (ip_port.ip.family == AF_INET6) { | ||
322 | uint32_t ipv6cnt = 0; | ||
323 | |||
324 | /* ipv6: count how many spots are used */ | ||
325 | for(i = 0; i < length; i++) | ||
326 | if (list[i].ip_port.ip.family == AF_INET6) | ||
327 | ipv6cnt++; | ||
328 | |||
329 | /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ | ||
330 | if (ipv6cnt > length / 2) | ||
331 | candropipv4 = 0; | ||
332 | } | ||
333 | |||
302 | for (i = 0; i < length; ++i) { | 334 | for (i = 0; i < length; ++i) { |
303 | /* If node is bad */ | 335 | /* If node is bad */ |
304 | if (is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) { | 336 | Client_data *client = &list[i]; |
305 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 337 | if ((candropipv4 || (client->ip_port.ip.family == AF_INET6)) && |
306 | list[i].ip_port = ip_port; | 338 | is_timeout(temp_time, client->timestamp, BAD_NODE_TIMEOUT)) { |
307 | list[i].timestamp = temp_time; | 339 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); |
308 | ip_reset(&list[i].ret_ip_port.ip); | 340 | client->ip_port = ip_port; |
309 | list[i].ret_ip_port.port = 0; | 341 | client->timestamp = temp_time; |
310 | list[i].ret_timestamp = 0; | 342 | ip_reset(&client->ret_ip_port.ip); |
343 | client->ret_ip_port.port = 0; | ||
344 | client->ret_timestamp = 0; | ||
311 | return 0; | 345 | return 0; |
312 | } | 346 | } |
313 | } | 347 | } |
@@ -344,20 +378,69 @@ static int replace_good( Client_data *list, | |||
344 | IP_Port ip_port, | 378 | IP_Port ip_port, |
345 | uint8_t *comp_client_id ) | 379 | uint8_t *comp_client_id ) |
346 | { | 380 | { |
347 | uint32_t i; | ||
348 | uint64_t temp_time = unix_time(); | ||
349 | sort_list(list, length, comp_client_id); | 381 | sort_list(list, length, comp_client_id); |
350 | 382 | ||
351 | for (i = 0; i < length; ++i) | 383 | uint8_t candropipv4 = 1; |
352 | if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) { | 384 | if (ip_port.ip.family == AF_INET6) { |
353 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 385 | uint32_t i, ipv6cnt = 0; |
354 | list[i].ip_port = ip_port; | 386 | |
355 | list[i].timestamp = temp_time; | 387 | /* ipv6: count how many spots are used */ |
356 | ip_reset(&list[i].ret_ip_port.ip); | 388 | for(i = 0; i < length; i++) |
357 | list[i].ret_ip_port.port = 0; | 389 | if (list[i].ip_port.ip.family == AF_INET6) |
358 | list[i].ret_timestamp = 0; | 390 | ipv6cnt++; |
359 | return 0; | 391 | |
392 | /* more than half the list filled with ipv6: block ipv4->ipv6 overwrite */ | ||
393 | if (ipv6cnt > length / 2) | ||
394 | candropipv4 = 0; | ||
395 | } | ||
396 | |||
397 | int8_t replace = -1; | ||
398 | uint32_t i; | ||
399 | |||
400 | if (candropipv4) { | ||
401 | /* either we got an ipv4 address, or we're "allowed" to push out an ipv4 | ||
402 | * address in favor of an ipv6 one | ||
403 | * | ||
404 | * because the list is sorted, we can simply check the client_id at the | ||
405 | * border, either it is closer, then every other one is as well, or it is | ||
406 | * further, then it gets pushed out in favor of the new address, which | ||
407 | * will with the next sort() move to its "rightful" position | ||
408 | * | ||
409 | * CAVEAT: weirdly enough, the list is sorted DESCENDING in distance | ||
410 | * so the furthest element is the first, NOT the last (at least that's | ||
411 | * what the comment above sort_list() claims) | ||
412 | */ | ||
413 | if (id_closest(comp_client_id, list[0].client_id, client_id) == 2) | ||
414 | replace = 0; | ||
415 | } else { | ||
416 | /* ipv6 case without a right to push out an ipv4: only look for ipv6 | ||
417 | * addresses, the first one we find is either closer (then we can skip | ||
418 | * out like above) or further (then we can replace it, like above) | ||
419 | */ | ||
420 | for (i = 0; i < length; i++) { | ||
421 | Client_data *client = &list[i]; | ||
422 | if (client->ip_port.ip.family == AF_INET6) { | ||
423 | if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) | ||
424 | replace = i; | ||
425 | |||
426 | break; | ||
427 | } | ||
360 | } | 428 | } |
429 | } | ||
430 | |||
431 | if (replace != -1) { | ||
432 | #ifdef DEBUG | ||
433 | assert(replace >= 0 && replace < length); | ||
434 | #endif | ||
435 | Client_data *client = &list[replace]; | ||
436 | memcpy(client->client_id, client_id, CLIENT_ID_SIZE); | ||
437 | client->ip_port = ip_port; | ||
438 | client->timestamp = unix_time(); | ||
439 | ip_reset(&client->ret_ip_port.ip); | ||
440 | client->ret_ip_port.port = 0; | ||
441 | client->ret_timestamp = 0; | ||
442 | return 0; | ||
443 | } | ||
361 | 444 | ||
362 | return 1; | 445 | return 1; |
363 | } | 446 | } |
@@ -369,36 +452,32 @@ void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) | |||
369 | { | 452 | { |
370 | uint32_t i; | 453 | uint32_t i; |
371 | 454 | ||
455 | /* convert IPv4-in-IPv6 to IPv4 */ | ||
456 | if ((ip_port.ip.family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&ip_port.ip.ip6.in6_addr)) { | ||
457 | ip_port.ip.family = AF_INET; | ||
458 | ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3]; | ||
459 | } | ||
460 | |||
372 | /* NOTE: Current behavior if there are two clients with the same id is | 461 | /* NOTE: Current behavior if there are two clients with the same id is |
373 | * to replace the first ip by the second. | 462 | * to replace the first ip by the second. |
374 | */ | 463 | */ |
375 | if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 464 | if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
376 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 465 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
377 | /* If we can't replace bad nodes we try replacing good ones. */ | 466 | /* If we can't replace bad nodes we try replacing good ones. */ |
378 | replace_good( dht->close_clientlist, | 467 | replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, |
379 | LCLIENT_LIST, | 468 | dht->c->self_public_key); |
380 | client_id, | ||
381 | ip_port, | ||
382 | dht->c->self_public_key ); | ||
383 | } | 469 | } |
384 | } | 470 | } |
385 | 471 | ||
386 | for (i = 0; i < dht->num_friends; ++i) { | 472 | for (i = 0; i < dht->num_friends; ++i) { |
387 | if (!client_in_list( dht->friends_list[i].client_list, | 473 | if (!client_or_ip_port_in_list(dht->friends_list[i].client_list, |
388 | MAX_FRIEND_CLIENTS, | 474 | MAX_FRIEND_CLIENTS, client_id, ip_port)) { |
389 | client_id, | 475 | |
390 | ip_port )) { | 476 | if (replace_bad(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
391 | 477 | client_id, ip_port)) { | |
392 | if (replace_bad( dht->friends_list[i].client_list, | ||
393 | MAX_FRIEND_CLIENTS, | ||
394 | client_id, | ||
395 | ip_port )) { | ||
396 | /* If we can't replace bad nodes we try replacing good ones. */ | 478 | /* If we can't replace bad nodes we try replacing good ones. */ |
397 | replace_good( dht->friends_list[i].client_list, | 479 | replace_good(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
398 | MAX_FRIEND_CLIENTS, | 480 | client_id, ip_port, dht->friends_list[i].client_id); |
399 | client_id, | ||
400 | ip_port, | ||
401 | dht->friends_list[i].client_id ); | ||
402 | } | 481 | } |
403 | } | 482 | } |
404 | } | 483 | } |
diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c index 83a5b338..8d447534 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c | |||
@@ -52,6 +52,43 @@ int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) | |||
52 | return -1; | 52 | return -1; |
53 | } | 53 | } |
54 | 54 | ||
55 | /* Resize a queue | ||
56 | * return length of queue on success. | ||
57 | * return ~0 on failure. | ||
58 | */ | ||
59 | uint32_t resize_queue(Data **buffer, uint32_t length, uint32_t new_length, uint32_t min_packetnum, | ||
60 | uint32_t max_packetnum) | ||
61 | { | ||
62 | if (MAX_QUEUE_NUM < new_length) | ||
63 | new_length = MAX_QUEUE_NUM; | ||
64 | |||
65 | if (max_packetnum - min_packetnum > new_length) | ||
66 | return ~0; | ||
67 | |||
68 | if (length == new_length) | ||
69 | return new_length; | ||
70 | |||
71 | Data *temp = calloc(1, sizeof(Data) * new_length); | ||
72 | |||
73 | if (temp == NULL) | ||
74 | return ~0; | ||
75 | |||
76 | if (*buffer == NULL) { | ||
77 | *buffer = temp; | ||
78 | return new_length; | ||
79 | } | ||
80 | |||
81 | uint32_t i; | ||
82 | |||
83 | for (i = min_packetnum; i != max_packetnum; ++i) | ||
84 | memcpy(temp + (i % new_length), *buffer + (i % length), sizeof(Data)); | ||
85 | |||
86 | free(*buffer); | ||
87 | *buffer = temp; | ||
88 | return new_length; | ||
89 | } | ||
90 | |||
91 | |||
55 | 92 | ||
56 | /* | 93 | /* |
57 | * Generate a handshake_id which depends on the ip_port. | 94 | * Generate a handshake_id which depends on the ip_port. |
@@ -148,8 +185,10 @@ int new_connection(Lossless_UDP *ludp, IP_Port ip_port) | |||
148 | { | 185 | { |
149 | int connection_id = getconnection_id(ludp, ip_port); | 186 | int connection_id = getconnection_id(ludp, ip_port); |
150 | 187 | ||
151 | if (connection_id != -1) | 188 | if (connection_id != -1) { |
189 | confirm_connection(ludp, connection_id); | ||
152 | return connection_id; | 190 | return connection_id; |
191 | } | ||
153 | 192 | ||
154 | tox_array_for_each(&ludp->connections, Connection, tmp) { | 193 | tox_array_for_each(&ludp->connections, Connection, tmp) { |
155 | if (tmp->status == 0) { | 194 | if (tmp->status == 0) { |
@@ -170,7 +209,8 @@ int new_connection(Lossless_UDP *ludp, IP_Port ip_port) | |||
170 | memset(connection, 0, sizeof(Connection)); | 209 | memset(connection, 0, sizeof(Connection)); |
171 | 210 | ||
172 | uint32_t handshake_id1 = handshake_id(ludp, ip_port); | 211 | uint32_t handshake_id1 = handshake_id(ludp, ip_port); |
173 | uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 212 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ |
213 | uint8_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | ||
174 | 214 | ||
175 | *connection = (Connection) { | 215 | *connection = (Connection) { |
176 | .ip_port = ip_port, | 216 | .ip_port = ip_port, |
@@ -186,9 +226,18 @@ int new_connection(Lossless_UDP *ludp, IP_Port ip_port) | |||
186 | .last_sent = current_time(), | 226 | .last_sent = current_time(), |
187 | .killat = ~0, | 227 | .killat = ~0, |
188 | .send_counter = 0, | 228 | .send_counter = 0, |
189 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 229 | .timeout = timeout, |
190 | .timeout = timeout | 230 | .confirmed = 1 |
191 | }; | 231 | }; |
232 | connection->sendbuffer_length = resize_queue(&connection->sendbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0); | ||
233 | connection->recvbuffer_length = resize_queue(&connection->recvbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0); | ||
234 | |||
235 | if (connection->sendbuffer_length == (uint32_t)~0 || connection->recvbuffer_length == (uint32_t)~0) { | ||
236 | free(connection->sendbuffer); | ||
237 | free(connection->recvbuffer); | ||
238 | memset(connection, 0, sizeof(Connection)); | ||
239 | return -1; | ||
240 | } | ||
192 | 241 | ||
193 | return connection_id; | 242 | return connection_id; |
194 | } | 243 | } |
@@ -221,8 +270,8 @@ static int new_inconnection(Lossless_UDP *ludp, IP_Port ip_port) | |||
221 | 270 | ||
222 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 271 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
223 | memset(connection, 0, sizeof(Connection)); | 272 | memset(connection, 0, sizeof(Connection)); |
224 | 273 | /* Add randomness to timeout to prevent connections getting stuck in a loop. */ | |
225 | uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 274 | uint8_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; |
226 | 275 | ||
227 | *connection = (Connection) { | 276 | *connection = (Connection) { |
228 | .ip_port = ip_port, | 277 | .ip_port = ip_port, |
@@ -234,24 +283,33 @@ static int new_inconnection(Lossless_UDP *ludp, IP_Port ip_port) | |||
234 | .last_sent = current_time(), | 283 | .last_sent = current_time(), |
235 | .send_counter = 127, | 284 | .send_counter = 127, |
236 | 285 | ||
237 | /* Add randomness to timeout to prevent connections getting stuck in a loop. */ | ||
238 | .timeout = timeout, | 286 | .timeout = timeout, |
239 | 287 | ||
240 | /* If this connection isn't handled within the timeout kill it. */ | 288 | /* If this connection isn't handled within the timeout kill it. */ |
241 | .killat = current_time() + 1000000UL * timeout | 289 | .killat = current_time() + 1000000UL * timeout, |
290 | .confirmed = 0 | ||
242 | }; | 291 | }; |
292 | connection->sendbuffer_length = resize_queue(&connection->sendbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0); | ||
293 | connection->recvbuffer_length = resize_queue(&connection->recvbuffer, 0, DEFAULT_QUEUE_NUM, 0, 0); | ||
294 | |||
295 | if (connection->sendbuffer_length == (uint32_t)~0 || connection->recvbuffer_length == (uint32_t)~0) { | ||
296 | free(connection->sendbuffer); | ||
297 | free(connection->recvbuffer); | ||
298 | memset(connection, 0, sizeof(Connection)); | ||
299 | return -1; | ||
300 | } | ||
243 | 301 | ||
244 | return connection_id; | 302 | return connection_id; |
245 | } | 303 | } |
246 | 304 | ||
247 | /* | 305 | /* |
248 | * return an integer corresponding to the next connection in our incoming connection list. | 306 | * return an integer corresponding to the next connection in our incoming connection list with at least numpackets in the recieve queue. |
249 | * return -1 if there are no new incoming connections in the list. | 307 | * return -1 if there are no new incoming connections in the list. |
250 | */ | 308 | */ |
251 | int incoming_connection(Lossless_UDP *ludp) | 309 | int incoming_connection(Lossless_UDP *ludp, uint32_t numpackets) |
252 | { | 310 | { |
253 | tox_array_for_each(&ludp->connections, Connection, tmp) { | 311 | tox_array_for_each(&ludp->connections, Connection, tmp) { |
254 | if (tmp->inbound == 2) { | 312 | if (tmp->inbound == 2 && tmp->recv_packetnum - tmp->successful_read >= numpackets) { |
255 | tmp->inbound = 1; | 313 | tmp->inbound = 1; |
256 | return tmp_i; | 314 | return tmp_i; |
257 | } | 315 | } |
@@ -286,6 +344,8 @@ int kill_connection(Lossless_UDP *ludp, int connection_id) | |||
286 | if (connection->status > 0) { | 344 | if (connection->status > 0) { |
287 | connection->status = 0; | 345 | connection->status = 0; |
288 | change_handshake(ludp, connection->ip_port); | 346 | change_handshake(ludp, connection->ip_port); |
347 | free(connection->sendbuffer); | ||
348 | free(connection->recvbuffer); | ||
289 | memset(connection, 0, sizeof(Connection)); | 349 | memset(connection, 0, sizeof(Connection)); |
290 | free_connections(ludp); | 350 | free_connections(ludp); |
291 | return 0; | 351 | return 0; |
@@ -332,6 +392,49 @@ int is_connected(Lossless_UDP *ludp, int connection_id) | |||
332 | return 0; | 392 | return 0; |
333 | } | 393 | } |
334 | 394 | ||
395 | /* Check if connection is confirmed. | ||
396 | * | ||
397 | * returns 1 if yes. | ||
398 | * returns 0 if no/failure. | ||
399 | */ | ||
400 | int connection_confirmed(Lossless_UDP *ludp, int connection_id) | ||
401 | { | ||
402 | if ((unsigned int)connection_id >= ludp->connections.len) | ||
403 | return 0; | ||
404 | |||
405 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | ||
406 | |||
407 | if (connection->status == 0) | ||
408 | return 0; | ||
409 | |||
410 | if (connection->confirmed == 1) | ||
411 | return 1; | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | /* Confirm an incoming connection. | ||
417 | * Also disables the auto kill timeout on incomming connections. | ||
418 | * | ||
419 | * return 0 on success | ||
420 | * return -1 on failure. | ||
421 | */ | ||
422 | int confirm_connection(Lossless_UDP *ludp, int connection_id) | ||
423 | { | ||
424 | if ((unsigned int)connection_id >= ludp->connections.len) | ||
425 | return -1; | ||
426 | |||
427 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | ||
428 | |||
429 | if (connection->status == 0) | ||
430 | return -1; | ||
431 | |||
432 | connection->killat = ~0; | ||
433 | connection->confirmed = 1; | ||
434 | connection->inbound = 0; | ||
435 | return 0; | ||
436 | } | ||
437 | |||
335 | /* return the ip_port of the corresponding connection. */ | 438 | /* return the ip_port of the corresponding connection. */ |
336 | IP_Port connection_ip(Lossless_UDP *ludp, int connection_id) | 439 | IP_Port connection_ip(Lossless_UDP *ludp, int connection_id) |
337 | { | 440 | { |
@@ -383,7 +486,7 @@ char id_packet(Lossless_UDP *ludp, int connection_id) | |||
383 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 486 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
384 | 487 | ||
385 | if (connection->status != 0) | 488 | if (connection->status != 0) |
386 | return connection->recvbuffer[connection->successful_read % MAX_QUEUE_NUM].data[0]; | 489 | return connection->recvbuffer[connection->successful_read % connection->recvbuffer_length].data[0]; |
387 | 490 | ||
388 | return -1; | 491 | return -1; |
389 | } | 492 | } |
@@ -401,13 +504,47 @@ int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data) | |||
401 | if (connection->status == 0) | 504 | if (connection->status == 0) |
402 | return 0; | 505 | return 0; |
403 | 506 | ||
404 | uint16_t index = connection->successful_read % MAX_QUEUE_NUM; | 507 | uint16_t index = connection->successful_read % connection->recvbuffer_length; |
405 | uint16_t size = connection->recvbuffer[index].size; | 508 | uint16_t size = connection->recvbuffer[index].size; |
406 | memcpy(data, connection->recvbuffer[index].data, size); | 509 | memcpy(data, connection->recvbuffer[index].data, size); |
407 | ++connection->successful_read; | 510 | ++connection->successful_read; |
408 | connection->recvbuffer[index].size = 0; | 511 | connection->recvbuffer[index].size = 0; |
409 | return size; | 512 | return size; |
513 | } | ||
514 | |||
515 | /* Like read_packet() but does leaves the queue as is. | ||
516 | * return 0 if there is no received data in the buffer. | ||
517 | * return length of received packet if successful. | ||
518 | */ | ||
519 | int read_packet_silent(Lossless_UDP *ludp, int connection_id, uint8_t *data) | ||
520 | { | ||
521 | if (recvqueue(ludp, connection_id) == 0) | ||
522 | return 0; | ||
523 | |||
524 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | ||
525 | |||
526 | if (connection->status == 0) | ||
527 | return 0; | ||
528 | |||
529 | uint16_t index = connection->successful_read % connection->recvbuffer_length; | ||
530 | uint16_t size = connection->recvbuffer[index].size; | ||
531 | memcpy(data, connection->recvbuffer[index].data, size); | ||
532 | return size; | ||
533 | } | ||
534 | /* Discard the next packet to be read from the queue | ||
535 | * return 0 if success. | ||
536 | * return -1 if failure. | ||
537 | */ | ||
538 | int discard_packet(Lossless_UDP *ludp, int connection_id) | ||
539 | { | ||
540 | if (recvqueue(ludp, connection_id) == 0) | ||
541 | return -1; | ||
410 | 542 | ||
543 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | ||
544 | uint16_t index = connection->successful_read % connection->recvbuffer_length; | ||
545 | ++connection->successful_read; | ||
546 | connection->recvbuffer[index].size = 0; | ||
547 | return 0; | ||
411 | } | 548 | } |
412 | 549 | ||
413 | /* return 0 if data could not be put in packet queue. | 550 | /* return 0 if data could not be put in packet queue. |
@@ -418,15 +555,27 @@ int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t | |||
418 | if ((unsigned int)connection_id >= ludp->connections.len) | 555 | if ((unsigned int)connection_id >= ludp->connections.len) |
419 | return 0; | 556 | return 0; |
420 | 557 | ||
421 | if (length > MAX_DATA_SIZE || length == 0 || sendqueue(ludp, connection_id) >= BUFFER_PACKET_NUM) | ||
422 | return 0; | ||
423 | |||
424 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 558 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
425 | 559 | ||
426 | if (connection->status == 0) | 560 | if (connection->status == 0) |
427 | return 0; | 561 | return 0; |
428 | 562 | ||
429 | uint32_t index = connection->sendbuff_packetnum % MAX_QUEUE_NUM; | 563 | if (length > MAX_DATA_SIZE || length == 0 || sendqueue(ludp, connection_id) >= MAX_QUEUE_NUM) |
564 | return 0; | ||
565 | |||
566 | if (sendqueue(ludp, connection_id) >= connection->sendbuffer_length && connection->sendbuffer_length != 0) { | ||
567 | uint32_t newlen = connection->sendbuffer_length = resize_queue(&connection->sendbuffer, connection->sendbuffer_length, | ||
568 | connection->sendbuffer_length * 2, connection->successful_sent, connection->sendbuff_packetnum); | ||
569 | |||
570 | if (newlen == (uint32_t)~0) | ||
571 | return 0; | ||
572 | |||
573 | connection->sendbuffer_length = newlen; | ||
574 | return write_packet(ludp, connection_id, data, length); | ||
575 | } | ||
576 | |||
577 | |||
578 | uint32_t index = connection->sendbuff_packetnum % connection->sendbuffer_length; | ||
430 | memcpy(connection->sendbuffer[index].data, data, length); | 579 | memcpy(connection->sendbuffer[index].data, data, length); |
431 | connection->sendbuffer[index].size = length; | 580 | connection->sendbuffer[index].size = length; |
432 | connection->sendbuff_packetnum++; | 581 | connection->sendbuff_packetnum++; |
@@ -434,26 +583,32 @@ int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t | |||
434 | } | 583 | } |
435 | 584 | ||
436 | /* Put the packet numbers the we are missing in requested and return the number. */ | 585 | /* Put the packet numbers the we are missing in requested and return the number. */ |
437 | uint32_t missing_packets(Lossless_UDP *ludp, int connection_id, uint32_t *requested) | 586 | static uint32_t missing_packets(Lossless_UDP *ludp, int connection_id, uint32_t *requested) |
438 | { | 587 | { |
588 | if ((unsigned int)connection_id >= ludp->connections.len) | ||
589 | return 0; | ||
590 | |||
591 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | ||
592 | |||
439 | /* Don't request packets if the buffer is full. */ | 593 | /* Don't request packets if the buffer is full. */ |
440 | if (recvqueue(ludp, connection_id) >= (BUFFER_PACKET_NUM - 1)) | 594 | if (recvqueue(ludp, connection_id) >= (connection->recvbuffer_length - 1)) |
441 | return 0; | 595 | return 0; |
442 | 596 | ||
443 | uint32_t number = 0; | 597 | uint32_t number = 0; |
444 | uint32_t i; | 598 | uint32_t i; |
445 | uint32_t temp; | 599 | uint32_t temp; |
446 | 600 | ||
447 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | ||
448 | |||
449 | for (i = connection->recv_packetnum; | 601 | for (i = connection->recv_packetnum; |
450 | i != connection->osent_packetnum; | 602 | i != connection->osent_packetnum; |
451 | i++) { | 603 | i++) { |
452 | if (connection->recvbuffer[i % MAX_QUEUE_NUM].size == 0) { | 604 | if (connection->recvbuffer[i % connection->recvbuffer_length].size == 0) { |
453 | temp = htonl(i); | 605 | temp = htonl(i); |
454 | memcpy(requested + number, &temp, 4); | 606 | memcpy(requested + number, &temp, 4); |
455 | ++number; | 607 | ++number; |
456 | } | 608 | } |
609 | |||
610 | if (number >= MAX_REQUESTED_PACKETS) | ||
611 | return number; | ||
457 | } | 612 | } |
458 | 613 | ||
459 | if (number == 0) | 614 | if (number == 0) |
@@ -485,7 +640,7 @@ static int send_handshake(Lossless_UDP *ludp, IP_Port ip_port, uint32_t handshak | |||
485 | static int send_SYNC(Lossless_UDP *ludp, int connection_id) | 640 | static int send_SYNC(Lossless_UDP *ludp, int connection_id) |
486 | { | 641 | { |
487 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 642 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
488 | uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; | 643 | uint8_t packet[(MAX_REQUESTED_PACKETS * 4 + 4 + 4 + 2)]; |
489 | uint16_t index = 0; | 644 | uint16_t index = 0; |
490 | 645 | ||
491 | IP_Port ip_port = connection->ip_port; | 646 | IP_Port ip_port = connection->ip_port; |
@@ -493,7 +648,7 @@ static int send_SYNC(Lossless_UDP *ludp, int connection_id) | |||
493 | uint32_t recv_packetnum = htonl(connection->recv_packetnum); | 648 | uint32_t recv_packetnum = htonl(connection->recv_packetnum); |
494 | uint32_t sent_packetnum = htonl(connection->sent_packetnum); | 649 | uint32_t sent_packetnum = htonl(connection->sent_packetnum); |
495 | 650 | ||
496 | uint32_t requested[BUFFER_PACKET_NUM]; | 651 | uint32_t requested[MAX_REQUESTED_PACKETS]; |
497 | uint32_t number = missing_packets(ludp, connection_id, requested); | 652 | uint32_t number = missing_packets(ludp, connection_id, requested); |
498 | 653 | ||
499 | packet[0] = NET_PACKET_SYNC; | 654 | packet[0] = NET_PACKET_SYNC; |
@@ -514,7 +669,7 @@ static int send_data_packet(Lossless_UDP *ludp, int connection_id, uint32_t pack | |||
514 | { | 669 | { |
515 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 670 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
516 | 671 | ||
517 | uint32_t index = packet_num % MAX_QUEUE_NUM; | 672 | uint32_t index = packet_num % connection->sendbuffer_length; |
518 | uint32_t temp; | 673 | uint32_t temp; |
519 | uint8_t packet[1 + 4 + MAX_DATA_SIZE]; | 674 | uint8_t packet[1 + 4 + MAX_DATA_SIZE]; |
520 | packet[0] = NET_PACKET_DATA; | 675 | packet[0] = NET_PACKET_DATA; |
@@ -529,7 +684,7 @@ static int send_DATA(Lossless_UDP *ludp, int connection_id) | |||
529 | { | 684 | { |
530 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 685 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
531 | int ret; | 686 | int ret; |
532 | uint32_t buffer[BUFFER_PACKET_NUM]; | 687 | uint32_t buffer[MAX_REQUESTED_PACKETS]; |
533 | 688 | ||
534 | if (connection->num_req_paquets > 0) { | 689 | if (connection->num_req_paquets > 0) { |
535 | ret = send_data_packet(ludp, connection_id, connection->req_packets[0]); | 690 | ret = send_data_packet(ludp, connection_id, connection->req_packets[0]); |
@@ -609,7 +764,7 @@ static int SYNC_valid(uint32_t length) | |||
609 | if (length < 4 + 4 + 2) | 764 | if (length < 4 + 4 + 2) |
610 | return 0; | 765 | return 0; |
611 | 766 | ||
612 | if (length > (BUFFER_PACKET_NUM * 4 + 4 + 4 + 2) || | 767 | if (length > (MAX_REQUESTED_PACKETS * 4 + 4 + 4 + 2) || |
613 | ((length - 4 - 4 - 2) % 4) != 0) | 768 | ((length - 4 - 4 - 2) % 4) != 0) |
614 | return 0; | 769 | return 0; |
615 | 770 | ||
@@ -656,6 +811,35 @@ static int handle_SYNC2(Lossless_UDP *ludp, int connection_id, uint8_t counter, | |||
656 | 811 | ||
657 | return 1; | 812 | return 1; |
658 | } | 813 | } |
814 | |||
815 | /* | ||
816 | * Automatically adjusts send rates of data packets for optimal transmission. | ||
817 | * | ||
818 | * TODO: Impove this. | ||
819 | */ | ||
820 | static void adjust_datasendspeed(Connection *connection, uint32_t req_packets) | ||
821 | { | ||
822 | /* if there are no packets in send buffer */ | ||
823 | if (connection->sendbuff_packetnum - connection->successful_sent == 0) { | ||
824 | connection->data_rate -= connection->data_rate / 8; | ||
825 | |||
826 | if (connection->data_rate < DATA_SYNC_RATE) | ||
827 | connection->data_rate = DATA_SYNC_RATE; | ||
828 | |||
829 | return; | ||
830 | } | ||
831 | |||
832 | if (req_packets <= (connection->data_rate / connection->SYNC_rate) / 20 || req_packets <= 1) { | ||
833 | connection->data_rate += connection->data_rate / 8; | ||
834 | |||
835 | if (connection->data_rate > connection->sendbuffer_length * connection->SYNC_rate) | ||
836 | connection->data_rate = connection->sendbuffer_length * connection->SYNC_rate; | ||
837 | } else { | ||
838 | connection->data_rate -= connection->data_rate / 8; | ||
839 | } | ||
840 | } | ||
841 | |||
842 | |||
659 | /* case 3 in handle_SYNC: */ | 843 | /* case 3 in handle_SYNC: */ |
660 | static int handle_SYNC3(Lossless_UDP *ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, | 844 | static int handle_SYNC3(Lossless_UDP *ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, |
661 | uint32_t sent_packetnum, | 845 | uint32_t sent_packetnum, |
@@ -672,13 +856,14 @@ static int handle_SYNC3(Lossless_UDP *ludp, int connection_id, uint8_t counter, | |||
672 | uint32_t comp_2 = (sent_packetnum - connection->osent_packetnum); | 856 | uint32_t comp_2 = (sent_packetnum - connection->osent_packetnum); |
673 | 857 | ||
674 | /* Packet valid. */ | 858 | /* Packet valid. */ |
675 | if (comp_1 <= BUFFER_PACKET_NUM && | 859 | if (comp_1 <= connection->sendbuffer_length && |
676 | comp_2 <= BUFFER_PACKET_NUM && | 860 | comp_2 <= MAX_QUEUE_NUM && |
677 | comp_counter == 1) { | 861 | comp_counter != 0 && comp_counter < 4) { |
678 | connection->orecv_packetnum = recv_packetnum; | 862 | connection->orecv_packetnum = recv_packetnum; |
679 | connection->osent_packetnum = sent_packetnum; | 863 | connection->osent_packetnum = sent_packetnum; |
680 | connection->successful_sent = recv_packetnum; | 864 | connection->successful_sent = recv_packetnum; |
681 | connection->last_recvSYNC = current_time(); | 865 | connection->last_recvSYNC = current_time(); |
866 | |||
682 | connection->recv_counter = counter; | 867 | connection->recv_counter = counter; |
683 | 868 | ||
684 | ++connection->send_counter; | 869 | ++connection->send_counter; |
@@ -689,6 +874,7 @@ static int handle_SYNC3(Lossless_UDP *ludp, int connection_id, uint8_t counter, | |||
689 | } | 874 | } |
690 | 875 | ||
691 | connection->num_req_paquets = number; | 876 | connection->num_req_paquets = number; |
877 | adjust_datasendspeed(connection, number); | ||
692 | return 0; | 878 | return 0; |
693 | } | 879 | } |
694 | 880 | ||
@@ -705,8 +891,8 @@ static int handle_SYNC(void *object, IP_Port source, uint8_t *packet, uint32_t l | |||
705 | uint8_t counter; | 891 | uint8_t counter; |
706 | uint32_t temp; | 892 | uint32_t temp; |
707 | uint32_t recv_packetnum, sent_packetnum; | 893 | uint32_t recv_packetnum, sent_packetnum; |
708 | uint32_t req_packets[BUFFER_PACKET_NUM]; | ||
709 | uint16_t number = (length - 4 - 4 - 2) / 4; | 894 | uint16_t number = (length - 4 - 4 - 2) / 4; |
895 | uint32_t req_packets[number]; | ||
710 | 896 | ||
711 | memcpy(&counter, packet + 1, 1); | 897 | memcpy(&counter, packet + 1, 1); |
712 | memcpy(&temp, packet + 2, 4); | 898 | memcpy(&temp, packet + 2, 4); |
@@ -749,17 +935,35 @@ static int add_recv(Lossless_UDP *ludp, int connection_id, uint32_t data_num, ui | |||
749 | 935 | ||
750 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); | 936 | Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); |
751 | uint32_t i; | 937 | uint32_t i; |
752 | uint32_t maxnum = connection->successful_read + BUFFER_PACKET_NUM; | 938 | uint32_t test = data_num - connection->recv_packetnum; |
939 | |||
940 | if (test > MAX_QUEUE_NUM) | ||
941 | return 0; | ||
942 | |||
943 | if (test > connection->recvbuffer_length) { | ||
944 | if (connection->confirmed == 0) | ||
945 | return 0; | ||
946 | |||
947 | uint32_t len = resize_queue(&connection->recvbuffer, connection->recvbuffer_length, test * 2, | ||
948 | connection->successful_read, connection->successful_read + connection->recvbuffer_length); | ||
949 | |||
950 | if (len == (uint32_t)~0) | ||
951 | return 0; | ||
952 | |||
953 | connection->recvbuffer_length = len; | ||
954 | } | ||
955 | |||
956 | uint32_t maxnum = connection->successful_read + connection->recvbuffer_length; | ||
753 | uint32_t sent_packet = data_num - connection->osent_packetnum; | 957 | uint32_t sent_packet = data_num - connection->osent_packetnum; |
754 | 958 | ||
755 | for (i = connection->recv_packetnum; i != maxnum; ++i) { | 959 | for (i = connection->recv_packetnum; i != maxnum; ++i) { |
756 | if (i == data_num) { | 960 | if (i == data_num) { |
757 | memcpy(connection->recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 961 | memcpy(connection->recvbuffer[data_num % connection->recvbuffer_length].data, data, size); |
758 | 962 | ||
759 | connection->recvbuffer[i % MAX_QUEUE_NUM].size = size; | 963 | connection->recvbuffer[data_num % connection->recvbuffer_length].size = size; |
760 | connection->last_recvdata = current_time(); | 964 | connection->last_recvdata = current_time(); |
761 | 965 | ||
762 | if (sent_packet < BUFFER_PACKET_NUM) | 966 | if (sent_packet < connection->recvbuffer_length) |
763 | connection->osent_packetnum = data_num; | 967 | connection->osent_packetnum = data_num; |
764 | 968 | ||
765 | break; | 969 | break; |
@@ -767,7 +971,7 @@ static int add_recv(Lossless_UDP *ludp, int connection_id, uint32_t data_num, ui | |||
767 | } | 971 | } |
768 | 972 | ||
769 | for (i = connection->recv_packetnum; i != maxnum; ++i) { | 973 | for (i = connection->recv_packetnum; i != maxnum; ++i) { |
770 | if (connection->recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 974 | if (connection->recvbuffer[i % connection->recvbuffer_length].size != 0) |
771 | connection->recv_packetnum = i; | 975 | connection->recv_packetnum = i; |
772 | else | 976 | else |
773 | break; | 977 | break; |
@@ -871,7 +1075,8 @@ static void do_data(Lossless_UDP *ludp) | |||
871 | if (tmp->status == 3 && sendqueue(ludp, tmp_i) != 0 && | 1075 | if (tmp->status == 3 && sendqueue(ludp, tmp_i) != 0 && |
872 | (tmp->last_sent + (1000000UL / tmp->data_rate)) <= temp_time) { | 1076 | (tmp->last_sent + (1000000UL / tmp->data_rate)) <= temp_time) { |
873 | for (j = tmp->last_sent; j < temp_time; j += (1000000UL / tmp->data_rate)) | 1077 | for (j = tmp->last_sent; j < temp_time; j += (1000000UL / tmp->data_rate)) |
874 | send_DATA(ludp, tmp_i); | 1078 | if (send_DATA(ludp, tmp_i) <= 0) |
1079 | break; | ||
875 | 1080 | ||
876 | tmp->last_sent = temp_time; | 1081 | tmp->last_sent = temp_time; |
877 | 1082 | ||
@@ -879,7 +1084,7 @@ static void do_data(Lossless_UDP *ludp) | |||
879 | } | 1084 | } |
880 | } | 1085 | } |
881 | 1086 | ||
882 | #define MAX_SYNC_RATE 10 | 1087 | #define MAX_SYNC_RATE 20 |
883 | 1088 | ||
884 | /* | 1089 | /* |
885 | * Automatically adjusts send rates of packets for optimal transmission. | 1090 | * Automatically adjusts send rates of packets for optimal transmission. |
@@ -896,12 +1101,12 @@ static void adjust_rates(Lossless_UDP *ludp) | |||
896 | 1101 | ||
897 | if (tmp->status == 3) { | 1102 | if (tmp->status == 3) { |
898 | if (sendqueue(ludp, tmp_i) != 0) { | 1103 | if (sendqueue(ludp, tmp_i) != 0) { |
899 | tmp->data_rate = (BUFFER_PACKET_NUM - tmp->num_req_paquets) * MAX_SYNC_RATE; | ||
900 | tmp->SYNC_rate = MAX_SYNC_RATE; | 1104 | tmp->SYNC_rate = MAX_SYNC_RATE; |
901 | } else if (tmp->last_recvdata + 1000000UL > temp_time) | 1105 | } else if (tmp->last_recvdata + 200000UL > temp_time) { /* 200 ms */ |
902 | tmp->SYNC_rate = MAX_SYNC_RATE; | 1106 | tmp->SYNC_rate = MAX_SYNC_RATE; |
903 | else | 1107 | } else { |
904 | tmp->SYNC_rate = SYNC_RATE; | 1108 | tmp->SYNC_rate = SYNC_RATE; |
1109 | } | ||
905 | } | 1110 | } |
906 | } | 1111 | } |
907 | } | 1112 | } |
@@ -917,6 +1122,11 @@ void do_lossless_udp(Lossless_UDP *ludp) | |||
917 | 1122 | ||
918 | void kill_lossless_udp(Lossless_UDP *ludp) | 1123 | void kill_lossless_udp(Lossless_UDP *ludp) |
919 | { | 1124 | { |
1125 | uint32_t i; | ||
1126 | |||
1127 | for (i = 0; i < ludp->connections.len; ++i) | ||
1128 | kill_connection(ludp, i); | ||
1129 | |||
920 | tox_array_delete(&ludp->connections); | 1130 | tox_array_delete(&ludp->connections); |
921 | free(ludp); | 1131 | free(ludp); |
922 | } | 1132 | } |
diff --git a/toxcore/Lossless_UDP.h b/toxcore/Lossless_UDP.h index f0ce0e87..2ef6f4d9 100644 --- a/toxcore/Lossless_UDP.h +++ b/toxcore/Lossless_UDP.h | |||
@@ -32,10 +32,11 @@ | |||
32 | #define MAX_DATA_SIZE 1024 | 32 | #define MAX_DATA_SIZE 1024 |
33 | 33 | ||
34 | /* Maximum data packets in sent and receive queues. */ | 34 | /* Maximum data packets in sent and receive queues. */ |
35 | #define MAX_QUEUE_NUM 16 | 35 | #define MAX_QUEUE_NUM 1024 |
36 | #define DEFAULT_QUEUE_NUM 4 | ||
36 | 37 | ||
37 | /* Maximum number of data packets in the buffer. */ | 38 | /* Maximum number of data packets in the buffer. */ |
38 | #define BUFFER_PACKET_NUM (16-1) | 39 | #define MAX_REQUESTED_PACKETS 256 |
39 | 40 | ||
40 | /* Timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT. */ | 41 | /* Timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT. */ |
41 | #define CONNEXION_TIMEOUT 5 | 42 | #define CONNEXION_TIMEOUT 5 |
@@ -71,7 +72,7 @@ typedef struct { | |||
71 | uint8_t inbound; | 72 | uint8_t inbound; |
72 | 73 | ||
73 | uint16_t SYNC_rate; /* Current SYNC packet send rate packets per second. */ | 74 | uint16_t SYNC_rate; /* Current SYNC packet send rate packets per second. */ |
74 | uint16_t data_rate; /* Current data packet send rate packets per second. */ | 75 | uint32_t data_rate; /* Current data packet send rate packets per second. */ |
75 | 76 | ||
76 | uint64_t last_SYNC; /* Time our last SYNC packet was sent. */ | 77 | uint64_t last_SYNC; /* Time our last SYNC packet was sent. */ |
77 | uint64_t last_sent; /* Time our last data or handshake packet was sent. */ | 78 | uint64_t last_sent; /* Time our last data or handshake packet was sent. */ |
@@ -79,9 +80,10 @@ typedef struct { | |||
79 | uint64_t last_recvdata; /* Time we last received a DATA packet from the other. */ | 80 | uint64_t last_recvdata; /* Time we last received a DATA packet from the other. */ |
80 | uint64_t killat; /* Time to kill the connection. */ | 81 | uint64_t killat; /* Time to kill the connection. */ |
81 | 82 | ||
82 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | 83 | Data *sendbuffer; /* packet send buffer. */ |
83 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | 84 | uint32_t sendbuffer_length; |
84 | 85 | Data *recvbuffer; /* packet receive buffer. */ | |
86 | uint32_t recvbuffer_length; | ||
85 | uint32_t handshake_id1; | 87 | uint32_t handshake_id1; |
86 | uint32_t handshake_id2; | 88 | uint32_t handshake_id2; |
87 | 89 | ||
@@ -107,7 +109,7 @@ typedef struct { | |||
107 | uint32_t successful_read; | 109 | uint32_t successful_read; |
108 | 110 | ||
109 | /* List of currently requested packet numbers(by the other person). */ | 111 | /* List of currently requested packet numbers(by the other person). */ |
110 | uint32_t req_packets[BUFFER_PACKET_NUM]; | 112 | uint32_t req_packets[MAX_REQUESTED_PACKETS]; |
111 | 113 | ||
112 | /* Total number of currently requested packets(by the other person). */ | 114 | /* Total number of currently requested packets(by the other person). */ |
113 | uint16_t num_req_paquets; | 115 | uint16_t num_req_paquets; |
@@ -115,6 +117,9 @@ typedef struct { | |||
115 | uint8_t recv_counter; | 117 | uint8_t recv_counter; |
116 | uint8_t send_counter; | 118 | uint8_t send_counter; |
117 | uint8_t timeout; /* connection timeout in seconds. */ | 119 | uint8_t timeout; /* connection timeout in seconds. */ |
120 | |||
121 | /* is the connection confirmed or not 1 if yes, 0 if no */ | ||
122 | uint8_t confirmed; | ||
118 | } Connection; | 123 | } Connection; |
119 | 124 | ||
120 | typedef struct { | 125 | typedef struct { |
@@ -150,10 +155,11 @@ int new_connection(Lossless_UDP *ludp, IP_Port ip_port); | |||
150 | */ | 155 | */ |
151 | int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port); | 156 | int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port); |
152 | 157 | ||
153 | /* return an integer corresponding to the next connection in our imcoming connection list. | 158 | /* |
159 | * return an integer corresponding to the next connection in our incoming connection list with at least numpackets in the recieve queue. | ||
154 | * return -1 if there are no new incoming connections in the list. | 160 | * return -1 if there are no new incoming connections in the list. |
155 | */ | 161 | */ |
156 | int incoming_connection(Lossless_UDP *ludp); | 162 | int incoming_connection(Lossless_UDP *ludp, uint32_t numpackets); |
157 | 163 | ||
158 | /* return -1 if it could not kill the connection. | 164 | /* return -1 if it could not kill the connection. |
159 | * return 0 if killed successfully. | 165 | * return 0 if killed successfully. |
@@ -168,6 +174,22 @@ int kill_connection(Lossless_UDP *ludp, int connection_id); | |||
168 | */ | 174 | */ |
169 | int kill_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds); | 175 | int kill_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds); |
170 | 176 | ||
177 | |||
178 | /* Check if connection is confirmed. | ||
179 | * | ||
180 | * returns 1 if yes. | ||
181 | * returns 0 if no. | ||
182 | */ | ||
183 | int connection_confirmed(Lossless_UDP *ludp, int connection_id); | ||
184 | |||
185 | /* Confirm an incoming connection. | ||
186 | * Also disables the auto kill timeout on incomming connections. | ||
187 | * | ||
188 | * return 0 on success | ||
189 | * return -1 on failure. | ||
190 | */ | ||
191 | int confirm_connection(Lossless_UDP *ludp, int connection_id); | ||
192 | |||
171 | /* returns the ip_port of the corresponding connection. | 193 | /* returns the ip_port of the corresponding connection. |
172 | * return 0 if there is no such connection. | 194 | * return 0 if there is no such connection. |
173 | */ | 195 | */ |
@@ -183,6 +205,18 @@ char id_packet(Lossless_UDP *ludp, int connection_id); | |||
183 | */ | 205 | */ |
184 | int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data); | 206 | int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data); |
185 | 207 | ||
208 | /* Like read_packet() but does leaves the queue as is. | ||
209 | * return 0 if there is no received data in the buffer. | ||
210 | * return length of received packet if successful. | ||
211 | */ | ||
212 | int read_packet_silent(Lossless_UDP *ludp, int connection_id, uint8_t *data); | ||
213 | |||
214 | /* Discard the next packet to be read from the queue | ||
215 | * return 0 if success. | ||
216 | * return -1 if failure. | ||
217 | */ | ||
218 | int discard_packet(Lossless_UDP *ludp, int connection_id); | ||
219 | |||
186 | /* return 0 if data could not be put in packet queue. | 220 | /* return 0 if data could not be put in packet queue. |
187 | * return 1 if data was put into the queue. | 221 | * return 1 if data was put into the queue. |
188 | */ | 222 | */ |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index dbbfa58c..f22a8d57 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -352,13 +352,16 @@ static int m_sendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t le | |||
352 | * return 0 if success. | 352 | * return 0 if success. |
353 | * return -1 if failure. | 353 | * return -1 if failure. |
354 | */ | 354 | */ |
355 | static int setfriendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t len) | 355 | int setfriendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t length) |
356 | { | 356 | { |
357 | if (friend_not_valid(m, friendnumber)) | 357 | if (friend_not_valid(m, friendnumber)) |
358 | return -1; | 358 | return -1; |
359 | 359 | ||
360 | m->friendlist[friendnumber].name_length = len; | 360 | if (length > MAX_NAME_LENGTH || length == 0) |
361 | memcpy(m->friendlist[friendnumber].name, name, len); | 361 | return -1; |
362 | |||
363 | m->friendlist[friendnumber].name_length = length; | ||
364 | memcpy(m->friendlist[friendnumber].name, name, length); | ||
362 | return 0; | 365 | return 0; |
363 | } | 366 | } |
364 | 367 | ||
@@ -513,8 +516,10 @@ static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status) | |||
513 | 516 | ||
514 | static int send_ping(Messenger *m, int friendnumber) | 517 | static int send_ping(Messenger *m, int friendnumber) |
515 | { | 518 | { |
516 | m->friendlist[friendnumber].ping_lastsent = unix_time(); | 519 | int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0); |
517 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0); | 520 | if (ret == 1) |
521 | m->friendlist[friendnumber].ping_lastsent = unix_time(); | ||
522 | return ret; | ||
518 | } | 523 | } |
519 | 524 | ||
520 | static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length) | 525 | static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length) |
@@ -538,7 +543,7 @@ static void set_friend_userstatus(Messenger *m, int friendnumber, USERSTATUS sta | |||
538 | /* Sets whether we send read receipts for friendnumber. */ | 543 | /* Sets whether we send read receipts for friendnumber. */ |
539 | void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno) | 544 | void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno) |
540 | { | 545 | { |
541 | if (yesno != 0 || yesno != 1) | 546 | if (yesno != 0 && yesno != 1) |
542 | return; | 547 | return; |
543 | 548 | ||
544 | if (friend_not_valid(m, friendnumber)) | 549 | if (friend_not_valid(m, friendnumber)) |
@@ -705,7 +710,7 @@ static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *m | |||
705 | } | 710 | } |
706 | 711 | ||
707 | if (m->group_message) | 712 | if (m->group_message) |
708 | (*m->group_message)(m, i, peer_number, message, length, m->group_invite_userdata); | 713 | (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata); |
709 | } | 714 | } |
710 | 715 | ||
711 | /* Creates a new groupchat and puts it in the chats array. | 716 | /* Creates a new groupchat and puts it in the chats array. |
@@ -1182,6 +1187,8 @@ void doFriends(Messenger *m) | |||
1182 | 1187 | ||
1183 | if (m->group_invite) | 1188 | if (m->group_invite) |
1184 | (*m->group_invite)(m, i, data, m->group_invite_userdata); | 1189 | (*m->group_invite)(m, i, data, m->group_invite_userdata); |
1190 | |||
1191 | break; | ||
1185 | } | 1192 | } |
1186 | 1193 | ||
1187 | case PACKET_ID_JOIN_GROUPCHAT: { | 1194 | case PACKET_ID_JOIN_GROUPCHAT: { |
@@ -1197,6 +1204,12 @@ void doFriends(Messenger *m) | |||
1197 | break; | 1204 | break; |
1198 | 1205 | ||
1199 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); | 1206 | group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); |
1207 | |||
1208 | break; | ||
1209 | } | ||
1210 | |||
1211 | default: { | ||
1212 | break; | ||
1200 | } | 1213 | } |
1201 | } | 1214 | } |
1202 | } else { | 1215 | } else { |
@@ -1231,6 +1244,11 @@ void doInbound(Messenger *m) | |||
1231 | int friend_id = getfriend_id(m, public_key); | 1244 | int friend_id = getfriend_id(m, public_key); |
1232 | 1245 | ||
1233 | if (friend_id != -1) { | 1246 | if (friend_id != -1) { |
1247 | if (m_get_friend_connectionstatus(m, friend_id) == 1) { | ||
1248 | kill_connection(m->net_crypto->lossless_udp, inconnection); | ||
1249 | return; | ||
1250 | } | ||
1251 | |||
1234 | crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id); | 1252 | crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id); |
1235 | m->friendlist[friend_id].crypt_connection_id = | 1253 | m->friendlist[friend_id].crypt_connection_id = |
1236 | accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key); | 1254 | accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key); |
@@ -1263,8 +1281,8 @@ void doMessenger(Messenger *m) | |||
1263 | 1281 | ||
1264 | do_DHT(m->dht); | 1282 | do_DHT(m->dht); |
1265 | do_net_crypto(m->net_crypto); | 1283 | do_net_crypto(m->net_crypto); |
1266 | doInbound(m); | ||
1267 | doFriends(m); | 1284 | doFriends(m); |
1285 | doInbound(m); | ||
1268 | do_allgroupchats(m); | 1286 | do_allgroupchats(m); |
1269 | LANdiscovery(m); | 1287 | LANdiscovery(m); |
1270 | 1288 | ||
@@ -1425,12 +1443,12 @@ static int Messenger_load_old(Messenger *m, uint8_t *data, uint32_t length) | |||
1425 | if (length < size) | 1443 | if (length < size) |
1426 | return -1; | 1444 | return -1; |
1427 | 1445 | ||
1428 | if (DHT_load_old(m->dht, data, size) == -1) | 1446 | if (DHT_load_old(m->dht, data, size) == -1) { |
1429 | #ifdef DEBUG | 1447 | #ifdef DEBUG |
1430 | fprintf(stderr, "Data file: Something wicked happened to the stored connections...\n"); | 1448 | fprintf(stderr, "Data file: Something wicked happened to the stored connections...\n"); |
1431 | 1449 | /* DO go on, friends/name still might be intact */ | |
1432 | #endif | 1450 | #endif |
1433 | /* DO go on, friends/name still might be intact */ | 1451 | } |
1434 | 1452 | ||
1435 | data += size; | 1453 | data += size; |
1436 | length -= size; | 1454 | length -= size; |
@@ -1640,6 +1658,54 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
1640 | return Messenger_load_old(m, data, length); | 1658 | return Messenger_load_old(m, data, length); |
1641 | } | 1659 | } |
1642 | 1660 | ||
1661 | /* Return the number of friends in the instance m. | ||
1662 | * You should use this to determine how much memory to allocate | ||
1663 | * for copy_friendlist. */ | ||
1664 | uint32_t count_friendlist(Messenger *m) | ||
1665 | { | ||
1666 | uint32_t ret = 0; | ||
1667 | uint32_t i; | ||
1668 | |||
1669 | for (i = 0; i < m->numfriends; i++) { | ||
1670 | if (m->friendlist[i].status > 0) { | ||
1671 | ret++; | ||
1672 | } | ||
1673 | } | ||
1674 | |||
1675 | return ret; | ||
1676 | } | ||
1677 | |||
1678 | /* Copy a list of valid friend IDs into the array out_list. | ||
1679 | * If out_list is NULL, returns 0. | ||
1680 | * Otherwise, returns the number of elements copied. | ||
1681 | * If the array was too small, the contents | ||
1682 | * of out_list will be truncated to list_size. */ | ||
1683 | uint32_t copy_friendlist(Messenger *m, int *out_list, uint32_t list_size) | ||
1684 | { | ||
1685 | if (!out_list) | ||
1686 | return 0; | ||
1687 | |||
1688 | if (m->numfriends == 0) { | ||
1689 | return 0; | ||
1690 | } | ||
1691 | |||
1692 | uint32_t i; | ||
1693 | uint32_t ret = 0; | ||
1694 | |||
1695 | for (i = 0; i < m->numfriends; i++) { | ||
1696 | if (i >= list_size) { | ||
1697 | break; /* Abandon ship */ | ||
1698 | } | ||
1699 | |||
1700 | if (m->friendlist[i].status > 0) { | ||
1701 | out_list[i] = i; | ||
1702 | ret++; | ||
1703 | } | ||
1704 | } | ||
1705 | |||
1706 | return ret; | ||
1707 | } | ||
1708 | |||
1643 | /* Allocate and return a list of valid friend id's. List must be freed by the | 1709 | /* Allocate and return a list of valid friend id's. List must be freed by the |
1644 | * caller. | 1710 | * caller. |
1645 | * | 1711 | * |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 78580dc0..0ff14de4 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -246,6 +246,16 @@ uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, ui | |||
246 | */ | 246 | */ |
247 | int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t length); | 247 | int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t length); |
248 | 248 | ||
249 | /* Set the name and name_length of a friend. | ||
250 | * name must be a string of maximum MAX_NAME_LENGTH length. | ||
251 | * length must be at least 1 byte. | ||
252 | * length is the length of name with the NULL terminator. | ||
253 | * | ||
254 | * return 0 if success. | ||
255 | * return -1 if failure. | ||
256 | */ | ||
257 | int setfriendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t length); | ||
258 | |||
249 | /* Set our nickname. | 259 | /* Set our nickname. |
250 | * name must be a string of maximum MAX_NAME_LENGTH length. | 260 | * name must be a string of maximum MAX_NAME_LENGTH length. |
251 | * length must be at least 1 byte. | 261 | * length must be at least 1 byte. |
@@ -456,6 +466,18 @@ void Messenger_save(Messenger *m, uint8_t *data); | |||
456 | /* Load the messenger from data of size length. */ | 466 | /* Load the messenger from data of size length. */ |
457 | int Messenger_load(Messenger *m, uint8_t *data, uint32_t length); | 467 | int Messenger_load(Messenger *m, uint8_t *data, uint32_t length); |
458 | 468 | ||
469 | /* Return the number of friends in the instance m. | ||
470 | * You should use this to determine how much memory to allocate | ||
471 | * for copy_friendlist. */ | ||
472 | uint32_t count_friendlist(Messenger *m); | ||
473 | |||
474 | /* Copy a list of valid friend IDs into the array out_list. | ||
475 | * If out_list is NULL, returns 0. | ||
476 | * Otherwise, returns the number of elements copied. | ||
477 | * If the array was too small, the contents | ||
478 | * of out_list will be truncated to list_size. */ | ||
479 | uint32_t copy_friendlist(Messenger *m, int *out_list, uint32_t list_size); | ||
480 | |||
459 | /* Allocate and return a list of valid friend id's. List must be freed by the | 481 | /* Allocate and return a list of valid friend id's. List must be freed by the |
460 | * caller. | 482 | * caller. |
461 | * | 483 | * |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a2e42557..98571ce7 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -503,27 +503,26 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) | |||
503 | */ | 503 | */ |
504 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 504 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) |
505 | { | 505 | { |
506 | uint32_t i; | 506 | while (1) { |
507 | int incoming_con = incoming_connection(c->lossless_udp, 1); | ||
507 | 508 | ||
508 | for (i = 0; i < MAX_INCOMING; ++i) { | 509 | if (incoming_con != -1) { |
509 | if (c->incoming_connections[i] != -1) { | 510 | if (is_connected(c->lossless_udp, incoming_con) == 4 |
510 | if (is_connected(c->lossless_udp, c->incoming_connections[i]) == 4 | 511 | || is_connected(c->lossless_udp, incoming_con) == 0) { |
511 | || is_connected(c->lossless_udp, c->incoming_connections[i]) == 0) { | 512 | kill_connection(c->lossless_udp, incoming_con); |
512 | kill_connection(c->lossless_udp, c->incoming_connections[i]); | ||
513 | c->incoming_connections[i] = -1; | ||
514 | continue; | 513 | continue; |
515 | } | 514 | } |
516 | 515 | ||
517 | if (id_packet(c->lossless_udp, c->incoming_connections[i]) == 2) { | 516 | if (id_packet(c->lossless_udp, incoming_con) == 2) { |
518 | uint8_t temp_data[MAX_DATA_SIZE]; | 517 | uint8_t temp_data[MAX_DATA_SIZE]; |
519 | uint16_t len = read_packet(c->lossless_udp, c->incoming_connections[i], temp_data); | 518 | uint16_t len = read_packet_silent(c->lossless_udp, incoming_con, temp_data); |
520 | 519 | ||
521 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { | 520 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { |
522 | int connection_id = c->incoming_connections[i]; | 521 | return incoming_con; |
523 | c->incoming_connections[i] = -1; /* Remove this connection from the incoming connection list. */ | ||
524 | return connection_id; | ||
525 | } | 522 | } |
526 | } | 523 | } |
524 | } else { | ||
525 | break; | ||
527 | } | 526 | } |
528 | } | 527 | } |
529 | 528 | ||
@@ -570,7 +569,7 @@ int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, | |||
570 | { | 569 | { |
571 | uint32_t i; | 570 | uint32_t i; |
572 | 571 | ||
573 | if (connection_id == -1) | 572 | if (discard_packet(c->lossless_udp, connection_id) == -1) |
574 | return -1; | 573 | return -1; |
575 | 574 | ||
576 | /* | 575 | /* |
@@ -579,6 +578,10 @@ int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, | |||
579 | * return -1; | 578 | * return -1; |
580 | * } | 579 | * } |
581 | */ | 580 | */ |
581 | |||
582 | /* Connection is accepted. */ | ||
583 | confirm_connection(c->lossless_udp, connection_id); | ||
584 | |||
582 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 | 585 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 |
583 | || c->crypto_connections == NULL) | 586 | || c->crypto_connections == NULL) |
584 | return -1; | 587 | return -1; |
@@ -659,41 +662,6 @@ void load_keys(Net_Crypto *c, uint8_t *keys) | |||
659 | memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); | 662 | memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); |
660 | } | 663 | } |
661 | 664 | ||
662 | /* Adds an incoming connection to the incoming_connection list. | ||
663 | * TODO: Optimize this. | ||
664 | * | ||
665 | * returns 0 if successful | ||
666 | * returns 1 if failure. | ||
667 | */ | ||
668 | static int new_incoming(Net_Crypto *c, int id) | ||
669 | { | ||
670 | uint32_t i; | ||
671 | |||
672 | for (i = 0; i < MAX_INCOMING; ++i) { | ||
673 | if (c->incoming_connections[i] == -1) { | ||
674 | c->incoming_connections[i] = id; | ||
675 | return 0; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | return 1; | ||
680 | } | ||
681 | |||
682 | /* Handle all new incoming connections. | ||
683 | * TODO: Optimize this. | ||
684 | */ | ||
685 | static void handle_incomings(Net_Crypto *c) | ||
686 | { | ||
687 | int income; | ||
688 | |||
689 | while (1) { | ||
690 | income = incoming_connection(c->lossless_udp); | ||
691 | |||
692 | if (income == -1 || new_incoming(c, income) ) | ||
693 | break; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /* Handle received packets for not yet established crypto connections. */ | 665 | /* Handle received packets for not yet established crypto connections. */ |
698 | static void receive_crypto(Net_Crypto *c) | 666 | static void receive_crypto(Net_Crypto *c) |
699 | { | 667 | { |
@@ -748,9 +716,6 @@ static void receive_crypto(Net_Crypto *c) | |||
748 | c->crypto_connections[i].sessionsecret_key, | 716 | c->crypto_connections[i].sessionsecret_key, |
749 | c->crypto_connections[i].shared_key); | 717 | c->crypto_connections[i].shared_key); |
750 | c->crypto_connections[i].status = CONN_ESTABLISHED; | 718 | c->crypto_connections[i].status = CONN_ESTABLISHED; |
751 | |||
752 | /* Connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ | ||
753 | kill_connection_in(c->lossless_udp, c->crypto_connections[i].number, 3000000); | ||
754 | } else { | 719 | } else { |
755 | /* This should not happen, kill the connection if it does. */ | 720 | /* This should not happen, kill the connection if it does. */ |
756 | crypto_kill(c, i); | 721 | crypto_kill(c, i); |
@@ -785,7 +750,6 @@ Net_Crypto *new_net_crypto(Networking_Core *net) | |||
785 | return NULL; | 750 | return NULL; |
786 | } | 751 | } |
787 | 752 | ||
788 | memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); | ||
789 | return temp; | 753 | return temp; |
790 | } | 754 | } |
791 | 755 | ||
@@ -810,7 +774,6 @@ static void kill_timedout(Net_Crypto *c) | |||
810 | void do_net_crypto(Net_Crypto *c) | 774 | void do_net_crypto(Net_Crypto *c) |
811 | { | 775 | { |
812 | do_lossless_udp(c->lossless_udp); | 776 | do_lossless_udp(c->lossless_udp); |
813 | handle_incomings(c); | ||
814 | kill_timedout(c); | 777 | kill_timedout(c); |
815 | receive_crypto(c); | 778 | receive_crypto(c); |
816 | } | 779 | } |
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 55c1e3e3..f8eeb424 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h | |||
@@ -26,8 +26,6 @@ | |||
26 | 26 | ||
27 | #include "Lossless_UDP.h" | 27 | #include "Lossless_UDP.h" |
28 | 28 | ||
29 | #define MAX_INCOMING 64 | ||
30 | |||
31 | #define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ | 29 | #define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ |
32 | #define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ | 30 | #define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ |
33 | 31 | ||
@@ -66,9 +64,6 @@ typedef struct { | |||
66 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 64 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; |
67 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | 65 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; |
68 | 66 | ||
69 | /* keeps track of the connection numbers for friends request so we can check later if they were sent. */ | ||
70 | int incoming_connections[MAX_INCOMING]; | ||
71 | |||
72 | Cryptopacket_Handles cryptopackethandlers[256]; | 67 | Cryptopacket_Handles cryptopackethandlers[256]; |
73 | } Net_Crypto; | 68 | } Net_Crypto; |
74 | 69 | ||
diff --git a/toxcore/network.c b/toxcore/network.c index 49e1726c..619248d8 100644 --- a/toxcore/network.c +++ b/toxcore/network.c | |||
@@ -28,6 +28,72 @@ | |||
28 | #include "network.h" | 28 | #include "network.h" |
29 | #include "util.h" | 29 | #include "util.h" |
30 | 30 | ||
31 | #ifndef IPV6_V6ONLY | ||
32 | #define IPV6_V6ONLY 27 | ||
33 | #endif | ||
34 | |||
35 | #ifdef WIN32 | ||
36 | |||
37 | static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t bufsize) | ||
38 | { | ||
39 | if (family == AF_INET) { | ||
40 | struct sockaddr_in saddr = { 0 }; | ||
41 | saddr.sin_family = AF_INET; | ||
42 | saddr.sin_addr = *(struct in_addr *)addr; | ||
43 | |||
44 | DWORD len = bufsize; | ||
45 | |||
46 | if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), NULL, buf, &len)) | ||
47 | return NULL; | ||
48 | |||
49 | return buf; | ||
50 | } else if (family == AF_INET6) { | ||
51 | struct sockaddr_in6 saddr = { 0 }; | ||
52 | saddr.sin6_family = AF_INET6; | ||
53 | saddr.sin6_addr = *(struct in6_addr *)addr; | ||
54 | |||
55 | DWORD len = bufsize; | ||
56 | |||
57 | if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), NULL, buf, &len)) | ||
58 | return NULL; | ||
59 | |||
60 | return buf; | ||
61 | } | ||
62 | |||
63 | return NULL; | ||
64 | } | ||
65 | |||
66 | static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf) | ||
67 | { | ||
68 | if (family == AF_INET) { | ||
69 | struct sockaddr_in saddr = { 0 }; | ||
70 | |||
71 | INT len = sizeof(saddr); | ||
72 | |||
73 | if (WSAStringToAddress((LPTSTR)addrString, AF_INET, NULL, (LPSOCKADDR)&saddr, &len)) | ||
74 | return 0; | ||
75 | |||
76 | *(struct in_addr *)addrbuf = saddr.sin_addr; | ||
77 | |||
78 | return 1; | ||
79 | } else if (family == AF_INET6) { | ||
80 | struct sockaddr_in6 saddr = { 0 }; | ||
81 | |||
82 | INT len = sizeof(saddr); | ||
83 | |||
84 | if (WSAStringToAddress((LPTSTR)addrString, AF_INET6, NULL, (LPSOCKADDR)&saddr, &len)) | ||
85 | return 0; | ||
86 | |||
87 | *(struct in6_addr *)addrbuf = saddr.sin6_addr; | ||
88 | |||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | #endif | ||
96 | |||
31 | /* return current UNIX time in microseconds (us). */ | 97 | /* return current UNIX time in microseconds (us). */ |
32 | uint64_t current_time(void) | 98 | uint64_t current_time(void) |
33 | { | 99 | { |
@@ -407,7 +473,7 @@ Networking_Core *new_networking(IP ip, uint16_t port) | |||
407 | #ifdef LOGGING | 473 | #ifdef LOGGING |
408 | res = | 474 | res = |
409 | #endif | 475 | #endif |
410 | setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); | 476 | setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); |
411 | #ifdef LOGGING | 477 | #ifdef LOGGING |
412 | 478 | ||
413 | if (res < 0) { | 479 | if (res < 0) { |
diff --git a/toxcore/network.h b/toxcore/network.h index 4432baed..0d2b5786 100644 --- a/toxcore/network.h +++ b/toxcore/network.h | |||
@@ -40,6 +40,15 @@ | |||
40 | #include <ws2tcpip.h> | 40 | #include <ws2tcpip.h> |
41 | 41 | ||
42 | typedef unsigned int sock_t; | 42 | typedef unsigned int sock_t; |
43 | typedef INT sa_family_t; | ||
44 | |||
45 | #ifndef IN6_ARE_ADDR_EQUAL | ||
46 | #define IN6_ARE_ADDR_EQUAL(a,b) \ | ||
47 | ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0]) \ | ||
48 | && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1]) \ | ||
49 | && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2]) \ | ||
50 | && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3])) | ||
51 | #endif | ||
43 | 52 | ||
44 | #else // Linux includes | 53 | #else // Linux includes |
45 | 54 | ||
diff --git a/toxcore/tox.c b/toxcore/tox.c index 4fba360b..1d7118be 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -153,6 +153,20 @@ int tox_sendaction(void *tox, int friendnumber, uint8_t *action, uint32_t length | |||
153 | return m_sendaction(m, friendnumber, action, length); | 153 | return m_sendaction(m, friendnumber, action, length); |
154 | } | 154 | } |
155 | 155 | ||
156 | /* Set friendnumber's nickname. | ||
157 | * name must be a string of maximum MAX_NAME_LENGTH length. | ||
158 | * length must be at least 1 byte. | ||
159 | * length is the length of name with the NULL terminator. | ||
160 | * | ||
161 | * return 0 if success. | ||
162 | * return -1 if failure. | ||
163 | */ | ||
164 | int tox_setfriendname(void *tox, int friendnumber, uint8_t *name, uint16_t length) | ||
165 | { | ||
166 | Messenger *m = tox; | ||
167 | return setfriendname(m, friendnumber, name, length); | ||
168 | } | ||
169 | |||
156 | /* Set our nickname. | 170 | /* Set our nickname. |
157 | * name must be a string of maximum MAX_NAME_LENGTH length. | 171 | * name must be a string of maximum MAX_NAME_LENGTH length. |
158 | * length must be at least 1 byte. | 172 | * length must be at least 1 byte. |
@@ -262,16 +276,24 @@ void tox_set_sends_receipts(void *tox, int friendnumber, int yesno) | |||
262 | m_set_sends_receipts(m, friendnumber, yesno); | 276 | m_set_sends_receipts(m, friendnumber, yesno); |
263 | } | 277 | } |
264 | 278 | ||
265 | /* Allocate and return a list of valid friend id's. List must be freed by the | 279 | /* Return the number of friends in the instance m. |
266 | * caller. | 280 | * You should use this to determine how much memory to allocate |
267 | * | 281 | * for copy_friendlist. */ |
268 | * retun 0 if success. | 282 | uint32_t tox_count_friendlist(void *tox) |
269 | * return -1 if failure. | 283 | { |
270 | */ | 284 | Messenger *m = tox; |
271 | int tox_get_friendlist(void *tox, int **out_list, uint32_t *out_list_length) | 285 | return count_friendlist(m); |
286 | } | ||
287 | |||
288 | /* Copy a list of valid friend IDs into the array out_list. | ||
289 | * If out_list is NULL, returns 0. | ||
290 | * Otherwise, returns the number of elements copied. | ||
291 | * If the array was too small, the contents | ||
292 | * of out_list will be truncated to list_size. */ | ||
293 | uint32_t tox_copy_friendlist(void *tox, int *out_list, uint32_t list_size) | ||
272 | { | 294 | { |
273 | Messenger *m = tox; | 295 | Messenger *m = tox; |
274 | return get_friendlist(m, out_list, out_list_length); | 296 | return copy_friendlist(m, out_list, list_size); |
275 | } | 297 | } |
276 | 298 | ||
277 | /* Set the function that will be executed when a friend request is received. | 299 | /* Set the function that will be executed when a friend request is received. |
diff --git a/toxcore/tox.h b/toxcore/tox.h index b39008fe..eabbb1af 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -36,6 +36,13 @@ | |||
36 | #include <windows.h> | 36 | #include <windows.h> |
37 | #include <ws2tcpip.h> | 37 | #include <ws2tcpip.h> |
38 | 38 | ||
39 | typedef INT sa_family_t; | ||
40 | #ifndef true | ||
41 | #define true 1 | ||
42 | #endif | ||
43 | #ifndef false | ||
44 | #define false 0 | ||
45 | #endif | ||
39 | #else | 46 | #else |
40 | 47 | ||
41 | #include <netinet/ip.h> | 48 | #include <netinet/ip.h> |
@@ -214,6 +221,16 @@ uint32_t tox_sendmessage_withid(Tox *tox, int friendnumber, uint32_t theid, uint | |||
214 | */ | 221 | */ |
215 | int tox_sendaction(Tox *tox, int friendnumber, uint8_t *action, uint32_t length); | 222 | int tox_sendaction(Tox *tox, int friendnumber, uint8_t *action, uint32_t length); |
216 | 223 | ||
224 | /* Set friendnumber's nickname. | ||
225 | * name must be a string of maximum MAX_NAME_LENGTH length. | ||
226 | * length must be at least 1 byte. | ||
227 | * length is the length of name with the NULL terminator. | ||
228 | * | ||
229 | * return 0 if success. | ||
230 | * return -1 if failure. | ||
231 | */ | ||
232 | int tox_setfriendname(void *tox, int friendnumber, uint8_t *name, uint16_t length); | ||
233 | |||
217 | /* Set our nickname. | 234 | /* Set our nickname. |
218 | * name must be a string of maximum MAX_NAME_LENGTH length. | 235 | * name must be a string of maximum MAX_NAME_LENGTH length. |
219 | * length must be at least 1 byte. | 236 | * length must be at least 1 byte. |
@@ -280,13 +297,17 @@ TOX_USERSTATUS tox_get_selfuserstatus(Tox *tox); | |||
280 | */ | 297 | */ |
281 | void tox_set_sends_receipts(Tox *tox, int friendnumber, int yesno); | 298 | void tox_set_sends_receipts(Tox *tox, int friendnumber, int yesno); |
282 | 299 | ||
283 | /* Allocate and return a list of valid friend id's. List must be freed by the | 300 | /* Return the number of friends in the instance m. |
284 | * caller. | 301 | * You should use this to determine how much memory to allocate |
285 | * | 302 | * for copy_friendlist. */ |
286 | * retun 0 if success. | 303 | uint32_t tox_count_friendlist(void *tox); |
287 | * return -1 if failure. | 304 | |
288 | */ | 305 | /* Copy a list of valid friend IDs into the array out_list. |
289 | int tox_get_friendlist(void *tox, int **out_list, uint32_t *out_list_length); | 306 | * If out_list is NULL, returns 0. |
307 | * Otherwise, returns the number of elements copied. | ||
308 | * If the array was too small, the contents | ||
309 | * of out_list will be truncated to list_size. */ | ||
310 | uint32_t tox_copy_friendlist(void *tox, int *out_list, uint32_t list_size); | ||
290 | 311 | ||
291 | /* Set the function that will be executed when a friend request is received. | 312 | /* Set the function that will be executed when a friend request is received. |
292 | * Function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) | 313 | * Function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) |