diff options
author | irungentoo <irungentoo@gmail.com> | 2013-08-05 20:36:20 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-08-05 20:36:20 -0400 |
commit | 1daf06462150a793c171b6d6417152f82cfed128 (patch) | |
tree | 2efc043df4a8cb37d973bc355c39c47f6acbf64c /core/ping.c | |
parent | 5d1657432ad5b26a62b1082e8c5194b55cd01851 (diff) | |
parent | 524cf1895413026f528d9c59d16755a066c56f1c (diff) |
Merge branch 'plutooo-master'
Diffstat (limited to 'core/ping.c')
-rw-r--r-- | core/ping.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/core/ping.c b/core/ping.c new file mode 100644 index 00000000..ffabe221 --- /dev/null +++ b/core/ping.c | |||
@@ -0,0 +1,103 @@ | |||
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 | { | ||
30 | num_pings = 0; | ||
31 | pos_pings = 0; | ||
32 | } | ||
33 | |||
34 | static bool is_timeout(uint64_t time) | ||
35 | { | ||
36 | return (time + PING_TIMEOUT) < now(); | ||
37 | } | ||
38 | |||
39 | static void remove_timeouts() // O(n) | ||
40 | { | ||
41 | size_t i, id; | ||
42 | size_t new_pos = pos_pings; | ||
43 | size_t new_num = num_pings; | ||
44 | |||
45 | // Loop through buffer, oldest first | ||
46 | for (i=0; i<num_pings; i++) { | ||
47 | id = (pos_pings + i) % PING_NUM_MAX; | ||
48 | |||
49 | if(is_timeout(pings[id].timestamp)) { | ||
50 | new_pos++; | ||
51 | new_num--; | ||
52 | } | ||
53 | // Break here because list is sorted. | ||
54 | else | ||
55 | break; | ||
56 | } | ||
57 | |||
58 | num_pings = new_num; | ||
59 | pos_pings = new_pos % PING_NUM_MAX; | ||
60 | } | ||
61 | |||
62 | uint64_t add_ping(IP_Port ipp) // O(n) | ||
63 | { | ||
64 | size_t p; | ||
65 | |||
66 | remove_timeouts(); | ||
67 | |||
68 | // Remove oldest ping if full buffer | ||
69 | if (num_pings == PING_NUM_MAX) { | ||
70 | num_pings--; | ||
71 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | ||
72 | } | ||
73 | |||
74 | // Insert new ping at end of list | ||
75 | p = (pos_pings + num_pings) % PING_NUM_MAX; | ||
76 | |||
77 | pings[p].ipp = ipp; | ||
78 | pings[p].timestamp = now(); | ||
79 | pings[p].id = random_64b(); | ||
80 | |||
81 | num_pings++; | ||
82 | return pings[p].id; | ||
83 | } | ||
84 | |||
85 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. | ||
86 | { | ||
87 | if (ipp.ip.i == 0 && ping_id == 0) | ||
88 | return false; | ||
89 | |||
90 | size_t i, id; | ||
91 | |||
92 | remove_timeouts(); | ||
93 | |||
94 | for (i=0; i<num_pings; i++) { | ||
95 | id = (pos_pings + i) % PING_NUM_MAX; | ||
96 | |||
97 | if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { | ||
98 | return true; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | return false; | ||
103 | } | ||