diff options
Diffstat (limited to 'core/ping.c')
-rw-r--r-- | core/ping.c | 179 |
1 files changed, 95 insertions, 84 deletions
diff --git a/core/ping.c b/core/ping.c index 646b0839..37f1b7ae 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -31,124 +31,135 @@ static clientid_t* self_id = (clientid_t*) &self_public_key; | |||
31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c |
32 | 32 | ||
33 | 33 | ||
34 | void init_ping() { | 34 | void init_ping() |
35 | num_pings = 0; | 35 | { |
36 | pos_pings = 0; | 36 | num_pings = 0; |
37 | pos_pings = 0; | ||
37 | } | 38 | } |
38 | 39 | ||
39 | static bool is_timeout(uint64_t time) { | 40 | static bool is_timeout(uint64_t time) |
40 | return (time + PING_TIMEOUT) < now(); | 41 | { |
42 | return (time + PING_TIMEOUT) < now(); | ||
41 | } | 43 | } |
42 | 44 | ||
43 | static void remove_timeouts() { // O(n) | 45 | static void remove_timeouts() // O(n) |
44 | size_t i, id; | 46 | { |
45 | size_t new_pos = pos_pings; | 47 | size_t i, id; |
46 | size_t new_num = num_pings; | 48 | size_t new_pos = pos_pings; |
47 | 49 | size_t new_num = num_pings; | |
48 | // Loop through buffer, oldest first | 50 | |
49 | for(i=0; i<num_pings; i++) { | 51 | // Loop through buffer, oldest first |
50 | id = (pos_pings + i) % PING_NUM_MAX; | 52 | for (i=0; i<num_pings; i++) { |
51 | 53 | id = (pos_pings + i) % PING_NUM_MAX; | |
52 | if(is_timeout(pings[id].timestamp)) { | 54 | |
53 | new_pos++; | 55 | if(is_timeout(pings[id].timestamp)) { |
54 | new_num--; | 56 | new_pos++; |
57 | new_num--; | ||
58 | } | ||
59 | // Break here because list is sorted. | ||
60 | else { | ||
61 | break; | ||
62 | } | ||
55 | } | 63 | } |
56 | // Break here because list is sorted. | ||
57 | else | ||
58 | break; | ||
59 | } | ||
60 | 64 | ||
61 | num_pings = new_num; | 65 | num_pings = new_num; |
62 | pos_pings = new_pos % PING_NUM_MAX; | 66 | pos_pings = new_pos % PING_NUM_MAX; |
63 | } | 67 | } |
64 | 68 | ||
65 | uint64_t add_ping(IP_Port ipp) { // O(n) | 69 | uint64_t add_ping(IP_Port ipp) // O(n) |
66 | size_t p; | 70 | { |
67 | 71 | size_t p; | |
68 | remove_timeouts(); | ||
69 | 72 | ||
70 | // Remove oldest ping if full buffer | 73 | remove_timeouts(); |
71 | if(num_pings == PING_NUM_MAX) { | ||
72 | num_pings--; | ||
73 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | ||
74 | } | ||
75 | 74 | ||
76 | // Insert new ping at end of list | 75 | // Remove oldest ping if full buffer |
77 | p = (pos_pings + num_pings) % PING_NUM_MAX; | 76 | if (num_pings == PING_NUM_MAX) { |
77 | num_pings--; | ||
78 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | ||
79 | } | ||
78 | 80 | ||
79 | pings[p].ipp = ipp; | 81 | // Insert new ping at end of list |
80 | pings[p].timestamp = now(); | 82 | p = (pos_pings + num_pings) % PING_NUM_MAX; |
81 | pings[p].id = random_64b(); | ||
82 | 83 | ||
83 | num_pings++; | 84 | pings[p].ipp = ipp; |
84 | return pings[p].id; | 85 | pings[p].timestamp = now(); |
86 | pings[p].id = random_64b(); | ||
87 | |||
88 | num_pings++; | ||
89 | return pings[p].id; | ||
85 | } | 90 | } |
86 | 91 | ||
87 | bool is_pinging(IP_Port ipp, uint64_t ping_id) { // O(n) | 92 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) |
88 | size_t i, id; | 93 | { |
94 | size_t i, id; | ||
95 | |||
96 | if (ipp.ip.i == 0 && ping_id == 0) | ||
97 | return false; | ||
89 | 98 | ||
90 | remove_timeouts(); | 99 | remove_timeouts(); |
91 | 100 | ||
92 | for(i=0; i<num_pings; i++) { | 101 | for (i=0; i<num_pings; i++) { |
93 | id = (pos_pings + i) % PING_NUM_MAX; | 102 | id = (pos_pings + i) % PING_NUM_MAX; |
94 | 103 | ||
95 | // ping_id = 0 means match any id | 104 | // ping_id = 0 means match any id |
96 | if(ipp_eq(pings[id].ipp, ipp) && (ping_id == 0 || pings[id].id == ping_id)) { | 105 | if(ipp_eq(pings[id].ipp, ipp) && (ping_id == 0 || pings[id].id == ping_id)) { |
97 | return true; | 106 | return true; |
107 | } | ||
98 | } | 108 | } |
99 | } | ||
100 | 109 | ||
101 | return false; | 110 | return false; |
102 | } | 111 | } |
103 | 112 | ||
104 | int send_ping_request(IP_Port ipp, clientid_t* client_id) { | 113 | int send_ping_request(IP_Port ipp, clientid_t* client_id) |
105 | pingreq_t pk; | 114 | { |
106 | int rc; | 115 | pingreq_t pk; |
107 | uint64_t ping_id; | 116 | int rc; |
117 | uint64_t ping_id; | ||
108 | 118 | ||
109 | if(is_pinging(ipp, 0) || id_eq(client_id, self_id)) | 119 | if (is_pinging(ipp, 0) || id_eq(client_id, self_id)) |
110 | return 1; | 120 | return 1; |
111 | 121 | ||
112 | // Generate random ping_id | 122 | // Generate random ping_id |
113 | ping_id = add_ping(ipp); | 123 | ping_id = add_ping(ipp); |
114 | 124 | ||
115 | pk.magic = PACKET_PING_REQ; | 125 | pk.magic = PACKET_PING_REQ; |
116 | id_cpy(&pk.client_id, self_id); // Our pubkey | 126 | id_cpy(&pk.client_id, self_id); // Our pubkey |
117 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce | 127 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce |
118 | 128 | ||
119 | // Encrypt ping_id using recipient privkey | 129 | // Encrypt ping_id using recipient privkey |
120 | rc = encrypt_data((uint8_t*) client_id, | 130 | rc = encrypt_data((uint8_t*) client_id, |
121 | self_secret_key, | 131 | self_secret_key, |
122 | (uint8_t*) &pk.nonce, | 132 | (uint8_t*) &pk.nonce, |
123 | (uint8_t*) &ping_id, sizeof(ping_id), | 133 | (uint8_t*) &ping_id, sizeof(ping_id), |
124 | (uint8_t*) &pk.ping_id); | 134 | (uint8_t*) &pk.ping_id); |
125 | 135 | ||
126 | if(rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 136 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
127 | return 1; | 137 | return 1; |
128 | 138 | ||
129 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | 139 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); |
130 | } | 140 | } |
131 | 141 | ||
132 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) { | 142 | int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) |
133 | pingres_t pk; | 143 | { |
134 | int rc; | 144 | pingres_t pk; |
145 | int rc; | ||
135 | 146 | ||
136 | if(id_eq(client_id, self_id)) | 147 | if (id_eq(client_id, self_id)) |
137 | return 1; | 148 | return 1; |
138 | 149 | ||
139 | pk.magic = PACKET_PING_RES; | 150 | pk.magic = PACKET_PING_RES; |
140 | id_cpy(&pk.client_id, self_id); // Our pubkey | 151 | id_cpy(&pk.client_id, self_id); // Our pubkey |
141 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce | 152 | random_nonce((uint8_t*) &pk.nonce); // Generate random nonce |
142 | 153 | ||
143 | // Encrypt ping_id using recipient privkey | 154 | // Encrypt ping_id using recipient privkey |
144 | rc = encrypt_data((uint8_t*) client_id, | 155 | rc = encrypt_data((uint8_t*) client_id, |
145 | self_secret_key, | 156 | self_secret_key, |
146 | (uint8_t*) &pk.nonce, | 157 | (uint8_t*) &pk.nonce, |
147 | (uint8_t*) &ping_id, sizeof(ping_id), | 158 | (uint8_t*) &ping_id, sizeof(ping_id), |
148 | (uint8_t*) &pk.ping_id); | 159 | (uint8_t*) &pk.ping_id); |
149 | 160 | ||
150 | if(rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 161 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
151 | return 1; | 162 | return 1; |
152 | 163 | ||
153 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); | 164 | return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); |
154 | } | 165 | } |