diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/CMakeLists.txt | 4 | ||||
-rw-r--r-- | core/DHT.c | 61 | ||||
-rw-r--r-- | core/ping.c | 95 | ||||
-rw-r--r-- | core/ping.h | 13 | ||||
-rw-r--r-- | core/util.c | 31 | ||||
-rw-r--r-- | core/util.h | 10 |
6 files changed, 156 insertions, 58 deletions
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index eacb772c..55a41912 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt | |||
@@ -8,7 +8,9 @@ set(core_sources | |||
8 | net_crypto.c | 8 | net_crypto.c |
9 | friend_requests.c | 9 | friend_requests.c |
10 | LAN_discovery.c | 10 | LAN_discovery.c |
11 | Messenger.c) | 11 | Messenger.c |
12 | util.c | ||
13 | ping.c) | ||
12 | 14 | ||
13 | if(SHARED_TOXCORE) | 15 | if(SHARED_TOXCORE) |
14 | add_library(toxcore SHARED ${core_sources}) | 16 | add_library(toxcore SHARED ${core_sources}) |
@@ -24,6 +24,7 @@ | |||
24 | /*----------------------------------------------------------------------------------*/ | 24 | /*----------------------------------------------------------------------------------*/ |
25 | 25 | ||
26 | #include "DHT.h" | 26 | #include "DHT.h" |
27 | #include "ping.h" | ||
27 | 28 | ||
28 | /* maximum number of clients stored per friend. */ | 29 | /* maximum number of clients stored per friend. */ |
29 | #define MAX_FRIEND_CLIENTS 8 | 30 | #define MAX_FRIEND_CLIENTS 8 |
@@ -109,7 +110,6 @@ uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | |||
109 | static Client_data close_clientlist[LCLIENT_LIST]; | 110 | static Client_data close_clientlist[LCLIENT_LIST]; |
110 | static Friend * friends_list; | 111 | static Friend * friends_list; |
111 | static uint16_t num_friends; | 112 | static uint16_t num_friends; |
112 | static Pinged pings[LPING_ARRAY]; | ||
113 | static Pinged send_nodes[LSEND_NODES_ARRAY]; | 113 | static Pinged send_nodes[LSEND_NODES_ARRAY]; |
114 | 114 | ||
115 | /*----------------------------------------------------------------------------------*/ | 115 | /*----------------------------------------------------------------------------------*/ |
@@ -426,35 +426,6 @@ static void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nod | |||
426 | } | 426 | } |
427 | } | 427 | } |
428 | 428 | ||
429 | /* check if we are currently pinging an ip_port and/or a ping_id variables with | ||
430 | * values of zero will not be checked. If we are already, return 1 else return 0 | ||
431 | * | ||
432 | * TODO: optimize this | ||
433 | */ | ||
434 | static int is_pinging(IP_Port ip_port, uint64_t ping_id) | ||
435 | { | ||
436 | uint32_t i; | ||
437 | uint8_t pinging; | ||
438 | uint64_t temp_time = unix_time(); | ||
439 | |||
440 | for (i = 0; i < LPING_ARRAY; ++i ) { | ||
441 | if (!is_timeout(temp_time, pings[i].timestamp, PING_TIMEOUT)) { | ||
442 | pinging = 0; | ||
443 | |||
444 | if (ip_port.ip.i != 0 && ipport_equal(pings[i].ip_port, ip_port)) | ||
445 | ++pinging; | ||
446 | |||
447 | if (ping_id != 0 && pings[i].ping_id == ping_id) | ||
448 | ++pinging; | ||
449 | |||
450 | if (pinging == ((ping_id != 0) + (ip_port.ip.i != 0))) | ||
451 | return 1; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | /* Same as last function but for get_node requests. */ | 429 | /* Same as last function but for get_node requests. */ |
459 | static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | 430 | static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) |
460 | { | 431 | { |
@@ -480,32 +451,6 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
480 | return 0; | 451 | return 0; |
481 | } | 452 | } |
482 | 453 | ||
483 | /* Add a new ping request to the list of ping requests | ||
484 | * returns the ping_id to put in the ping request | ||
485 | * returns 0 if problem. | ||
486 | * | ||
487 | * TODO: optimize this | ||
488 | */ | ||
489 | static uint64_t add_pinging(IP_Port ip_port) | ||
490 | { | ||
491 | uint32_t i, j; | ||
492 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | ||
493 | uint64_t temp_time = unix_time(); | ||
494 | |||
495 | for(i = 0; i < PING_TIMEOUT; ++i ) { | ||
496 | for(j = 0; j < LPING_ARRAY; ++j ) { | ||
497 | if(is_timeout(temp_time, pings[j].timestamp, PING_TIMEOUT - i)) { | ||
498 | pings[j].timestamp = temp_time; | ||
499 | pings[j].ip_port = ip_port; | ||
500 | pings[j].ping_id = ping_id; | ||
501 | return ping_id; | ||
502 | } | ||
503 | } | ||
504 | } | ||
505 | |||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | /* Same but for get node requests */ | 454 | /* Same but for get node requests */ |
510 | static uint64_t add_gettingnodes(IP_Port ip_port) | 455 | static uint64_t add_gettingnodes(IP_Port ip_port) |
511 | { | 456 | { |
@@ -536,7 +481,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key) | |||
536 | if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0)) | 481 | if(id_equal(public_key, self_public_key) || is_pinging(ip_port, 0)) |
537 | return 1; | 482 | return 1; |
538 | 483 | ||
539 | uint64_t ping_id = add_pinging(ip_port); | 484 | uint64_t ping_id = add_ping(ip_port); |
540 | if(ping_id == 0) | 485 | if(ping_id == 0) |
541 | return 1; | 486 | return 1; |
542 | 487 | ||
@@ -1301,6 +1246,8 @@ void DHT_save(uint8_t * data) | |||
1301 | */ | 1246 | */ |
1302 | int DHT_load(uint8_t * data, uint32_t size) | 1247 | int DHT_load(uint8_t * data, uint32_t size) |
1303 | { | 1248 | { |
1249 | init_ping(); | ||
1250 | |||
1304 | if(size < sizeof(close_clientlist)) | 1251 | if(size < sizeof(close_clientlist)) |
1305 | return -1; | 1252 | return -1; |
1306 | 1253 | ||
diff --git a/core/ping.c b/core/ping.c new file mode 100644 index 00000000..8a7d534f --- /dev/null +++ b/core/ping.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * ping.c -- Buffered pinging using cyclic arrays. | ||
3 | * | ||
4 | * This file is donated to the Tox Project. | ||
5 | * Copyright 2013 plutooo | ||
6 | */ | ||
7 | |||
8 | #include <stdbool.h> | ||
9 | #include <stdint.h> | ||
10 | |||
11 | #include "network.h" | ||
12 | #include "util.h" | ||
13 | |||
14 | #define PING_NUM_MAX 256 | ||
15 | #define PING_TIMEOUT 5 // 5s | ||
16 | |||
17 | typedef struct { | ||
18 | IP_Port ipp; | ||
19 | uint64_t id; | ||
20 | uint64_t timestamp; | ||
21 | } pinged_t; | ||
22 | |||
23 | static pinged_t pings[PING_NUM_MAX]; | ||
24 | static size_t num_pings; | ||
25 | static size_t pos_pings; | ||
26 | |||
27 | |||
28 | void init_ping() { | ||
29 | num_pings = 0; | ||
30 | pos_pings = 0; | ||
31 | } | ||
32 | |||
33 | static bool is_timeout(uint64_t time) { | ||
34 | return (time + PING_TIMEOUT) < now(); | ||
35 | } | ||
36 | |||
37 | static void remove_timeouts() { // O(n) | ||
38 | size_t i, id; | ||
39 | size_t new_pos = pos_pings; | ||
40 | size_t new_num = num_pings; | ||
41 | |||
42 | // Loop through buffer, oldest first | ||
43 | for(i=0; i<num_pings; i++) { | ||
44 | id = (pos_pings + i) % PING_NUM_MAX; | ||
45 | |||
46 | if(is_timeout(pings[id].timestamp)) { | ||
47 | new_pos++; | ||
48 | new_num--; | ||
49 | } | ||
50 | // Break here because list is sorted. | ||
51 | else | ||
52 | break; | ||
53 | } | ||
54 | |||
55 | num_pings = new_num; | ||
56 | pos_pings = new_pos % PING_NUM_MAX; | ||
57 | } | ||
58 | |||
59 | uint64_t add_ping(IP_Port ipp) { // O(n) | ||
60 | size_t p; | ||
61 | |||
62 | remove_timeouts(); | ||
63 | |||
64 | // Remove oldest ping if full buffer | ||
65 | if(num_pings == PING_NUM_MAX) { | ||
66 | num_pings--; | ||
67 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | ||
68 | } | ||
69 | |||
70 | // Insert new ping at end of list | ||
71 | p = (pos_pings + num_pings) % PING_NUM_MAX; | ||
72 | |||
73 | pings[p].ipp = ipp; | ||
74 | pings[p].timestamp = now(); | ||
75 | pings[p].id = random_64b(); | ||
76 | |||
77 | num_pings++; | ||
78 | return pings[p].id; | ||
79 | } | ||
80 | |||
81 | bool is_pinging(IP_Port ipp, uint64_t ping_id) { // O(n) | ||
82 | size_t i, id; | ||
83 | |||
84 | remove_timeouts(); | ||
85 | |||
86 | for(i=0; i<num_pings; i++) { | ||
87 | id = (pos_pings + i) % PING_NUM_MAX; | ||
88 | |||
89 | if(ipp_eq(pings[id].ipp, ipp) && pings[id].id == ping_id) { | ||
90 | return true; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | return false; | ||
95 | } | ||
diff --git a/core/ping.h b/core/ping.h new file mode 100644 index 00000000..1d23df97 --- /dev/null +++ b/core/ping.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * ping.h -- Buffered pinging using cyclic arrays. | ||
3 | * | ||
4 | * This file is donated to the Tox Project. | ||
5 | * Copyright 2013 plutooo | ||
6 | */ | ||
7 | |||
8 | #include <stdbool.h> | ||
9 | |||
10 | void init_ping(); | ||
11 | uint64_t add_ping(IP_Port ipp); | ||
12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); | ||
13 | |||
diff --git a/core/util.c b/core/util.c new file mode 100644 index 00000000..6b40dad7 --- /dev/null +++ b/core/util.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * util.c -- Utilities. | ||
3 | * | ||
4 | * This file is donated to the Tox Project. | ||
5 | * Copyright 2013 plutooo | ||
6 | */ | ||
7 | |||
8 | #include <time.h> | ||
9 | #include <stdint.h> | ||
10 | #include <stdbool.h> | ||
11 | |||
12 | #include "network.h" | ||
13 | |||
14 | uint64_t now() { | ||
15 | return time(NULL); | ||
16 | } | ||
17 | |||
18 | uint64_t random_64b() { | ||
19 | uint64_t r; | ||
20 | |||
21 | // This is probably not random enough? | ||
22 | r = random_int(); | ||
23 | r <<= 32; | ||
24 | r |= random_int(); | ||
25 | |||
26 | return r; | ||
27 | } | ||
28 | |||
29 | bool ipp_eq(IP_Port a, IP_Port b) { | ||
30 | return (a.ip.i == b.ip.i) && (a.port == b.port); | ||
31 | } | ||
diff --git a/core/util.h b/core/util.h new file mode 100644 index 00000000..aab2ead9 --- /dev/null +++ b/core/util.h | |||
@@ -0,0 +1,10 @@ | |||
1 | /* | ||
2 | * util.h -- Utilities. | ||
3 | * | ||
4 | * This file is donated to the Tox Project. | ||
5 | * Copyright 2013 plutooo | ||
6 | */ | ||
7 | |||
8 | uint64_t now(); | ||
9 | uint64_t random_64b(); | ||
10 | bool ipp_eq(IP_Port a, IP_Port b); | ||