diff options
Diffstat (limited to 'core/ping.c')
-rw-r--r-- | core/ping.c | 95 |
1 files changed, 51 insertions, 44 deletions
diff --git a/core/ping.c b/core/ping.c index 10b9b19f..5da3c0ca 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -23,16 +23,20 @@ typedef struct { | |||
23 | uint64_t timestamp; | 23 | uint64_t timestamp; |
24 | } pinged_t; | 24 | } pinged_t; |
25 | 25 | ||
26 | static pinged_t pings[PING_NUM_MAX]; | 26 | typedef struct { |
27 | static size_t num_pings; | 27 | pinged_t pings[PING_NUM_MAX]; |
28 | static size_t pos_pings; | 28 | size_t num_pings; |
29 | size_t pos_pings; | ||
30 | } PING; | ||
29 | 31 | ||
30 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 32 | void * new_ping(void) |
33 | { | ||
34 | return calloc(1, sizeof(PING)); | ||
35 | } | ||
31 | 36 | ||
32 | void init_ping() | 37 | void kill_ping(void * ping) |
33 | { | 38 | { |
34 | num_pings = 0; | 39 | free(ping); |
35 | pos_pings = 0; | ||
36 | } | 40 | } |
37 | 41 | ||
38 | static bool is_timeout(uint64_t time) | 42 | static bool is_timeout(uint64_t time) |
@@ -40,17 +44,18 @@ static bool is_timeout(uint64_t time) | |||
40 | return (time + PING_TIMEOUT) < now(); | 44 | return (time + PING_TIMEOUT) < now(); |
41 | } | 45 | } |
42 | 46 | ||
43 | static void remove_timeouts() // O(n) | 47 | static void remove_timeouts(void * ping) // O(n) |
44 | { | 48 | { |
49 | PING * png = ping; | ||
45 | size_t i, id; | 50 | size_t i, id; |
46 | size_t new_pos = pos_pings; | 51 | size_t new_pos = png->pos_pings; |
47 | size_t new_num = num_pings; | 52 | size_t new_num = png->num_pings; |
48 | 53 | ||
49 | // Loop through buffer, oldest first | 54 | // Loop through buffer, oldest first |
50 | for (i = 0; i < num_pings; i++) { | 55 | for (i = 0; i < png->num_pings; i++) { |
51 | id = (pos_pings + i) % PING_NUM_MAX; | 56 | id = (png->pos_pings + i) % PING_NUM_MAX; |
52 | 57 | ||
53 | if (is_timeout(pings[id].timestamp)) { | 58 | if (is_timeout(png->pings[id].timestamp)) { |
54 | new_pos++; | 59 | new_pos++; |
55 | new_num--; | 60 | new_num--; |
56 | } | 61 | } |
@@ -60,47 +65,49 @@ static void remove_timeouts() // O(n) | |||
60 | } | 65 | } |
61 | } | 66 | } |
62 | 67 | ||
63 | num_pings = new_num; | 68 | png->num_pings = new_num; |
64 | pos_pings = new_pos % PING_NUM_MAX; | 69 | png->pos_pings = new_pos % PING_NUM_MAX; |
65 | } | 70 | } |
66 | 71 | ||
67 | uint64_t add_ping(IP_Port ipp) // O(n) | 72 | uint64_t add_ping(void * ping, IP_Port ipp) // O(n) |
68 | { | 73 | { |
74 | PING * png = ping; | ||
69 | size_t p; | 75 | size_t p; |
70 | 76 | ||
71 | remove_timeouts(); | 77 | remove_timeouts(ping); |
72 | 78 | ||
73 | // Remove oldest ping if full buffer | 79 | // Remove oldest ping if full buffer |
74 | if (num_pings == PING_NUM_MAX) { | 80 | if (png->num_pings == PING_NUM_MAX) { |
75 | num_pings--; | 81 | png->num_pings--; |
76 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | 82 | png->pos_pings = (png->pos_pings + 1) % PING_NUM_MAX; |
77 | } | 83 | } |
78 | 84 | ||
79 | // Insert new ping at end of list | 85 | // Insert new ping at end of list |
80 | p = (pos_pings + num_pings) % PING_NUM_MAX; | 86 | p = (png->pos_pings + png->num_pings) % PING_NUM_MAX; |
81 | 87 | ||
82 | pings[p].ipp = ipp; | 88 | png->pings[p].ipp = ipp; |
83 | pings[p].timestamp = now(); | 89 | png->pings[p].timestamp = now(); |
84 | pings[p].id = random_64b(); | 90 | png->pings[p].id = random_64b(); |
85 | 91 | ||
86 | num_pings++; | 92 | png->num_pings++; |
87 | return pings[p].id; | 93 | return png->pings[p].id; |
88 | } | 94 | } |
89 | 95 | ||
90 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. | 96 | bool is_pinging(void * ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. |
91 | { | 97 | { |
98 | PING * png = ping; | ||
92 | if (ipp.ip.i == 0 && ping_id == 0) | 99 | if (ipp.ip.i == 0 && ping_id == 0) |
93 | return false; | 100 | return false; |
94 | 101 | ||
95 | size_t i, id; | 102 | size_t i, id; |
96 | 103 | ||
97 | remove_timeouts(); | 104 | remove_timeouts(ping); |
98 | 105 | ||
99 | for (i = 0; i < num_pings; i++) { | 106 | for (i = 0; i < png->num_pings; i++) { |
100 | id = (pos_pings + i) % PING_NUM_MAX; | 107 | id = (png->pos_pings + i) % PING_NUM_MAX; |
101 | 108 | ||
102 | // ping_id = 0 means match any id | 109 | // ping_id = 0 means match any id |
103 | if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { | 110 | if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.i == 0) && (png->pings[id].id == ping_id || ping_id == 0)) { |
104 | return true; | 111 | return true; |
105 | } | 112 | } |
106 | } | 113 | } |
@@ -108,25 +115,25 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with | |||
108 | return false; | 115 | return false; |
109 | } | 116 | } |
110 | 117 | ||
111 | int send_ping_request(IP_Port ipp, clientid_t *client_id) | 118 | int send_ping_request(void * ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id) |
112 | { | 119 | { |
113 | pingreq_t pk; | 120 | pingreq_t pk; |
114 | int rc; | 121 | int rc; |
115 | uint64_t ping_id; | 122 | uint64_t ping_id; |
116 | 123 | ||
117 | if (is_pinging(ipp, 0) || id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) | 124 | if (is_pinging(ping, ipp, 0) || id_eq(client_id, (clientid_t *)c->self_public_key)) |
118 | return 1; | 125 | return 1; |
119 | 126 | ||
120 | // Generate random ping_id | 127 | // Generate random ping_id |
121 | ping_id = add_ping(ipp); | 128 | ping_id = add_ping(ping, ipp); |
122 | 129 | ||
123 | pk.magic = PACKET_PING_REQ; | 130 | pk.magic = PACKET_PING_REQ; |
124 | id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey | 131 | id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey |
125 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce | 132 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce |
126 | 133 | ||
127 | // Encrypt ping_id using recipient privkey | 134 | // Encrypt ping_id using recipient privkey |
128 | rc = encrypt_data((uint8_t *) client_id, | 135 | rc = encrypt_data((uint8_t *) client_id, |
129 | temp_net_crypto->self_secret_key, | 136 | c->self_secret_key, |
130 | (uint8_t *) &pk.nonce, | 137 | (uint8_t *) &pk.nonce, |
131 | (uint8_t *) &ping_id, sizeof(ping_id), | 138 | (uint8_t *) &ping_id, sizeof(ping_id), |
132 | (uint8_t *) &pk.ping_id); | 139 | (uint8_t *) &pk.ping_id); |
@@ -134,24 +141,24 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id) | |||
134 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 141 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
135 | return 1; | 142 | return 1; |
136 | 143 | ||
137 | return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); | 144 | return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
138 | } | 145 | } |
139 | 146 | ||
140 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | 147 | int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id) |
141 | { | 148 | { |
142 | pingres_t pk; | 149 | pingres_t pk; |
143 | int rc; | 150 | int rc; |
144 | 151 | ||
145 | if (id_eq(client_id, (clientid_t *)temp_net_crypto->self_public_key)) | 152 | if (id_eq(client_id, (clientid_t *)c->self_public_key)) |
146 | return 1; | 153 | return 1; |
147 | 154 | ||
148 | pk.magic = PACKET_PING_RES; | 155 | pk.magic = PACKET_PING_RES; |
149 | id_cpy(&pk.client_id, (clientid_t *)temp_net_crypto->self_public_key); // Our pubkey | 156 | id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey |
150 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce | 157 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce |
151 | 158 | ||
152 | // Encrypt ping_id using recipient privkey | 159 | // Encrypt ping_id using recipient privkey |
153 | rc = encrypt_data((uint8_t *) client_id, | 160 | rc = encrypt_data((uint8_t *) client_id, |
154 | temp_net_crypto->self_secret_key, | 161 | c->self_secret_key, |
155 | (uint8_t *) &pk.nonce, | 162 | (uint8_t *) &pk.nonce, |
156 | (uint8_t *) &ping_id, sizeof(ping_id), | 163 | (uint8_t *) &ping_id, sizeof(ping_id), |
157 | (uint8_t *) &pk.ping_id); | 164 | (uint8_t *) &pk.ping_id); |
@@ -159,7 +166,7 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | |||
159 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 166 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
160 | return 1; | 167 | return 1; |
161 | 168 | ||
162 | return sendpacket(temp_net_crypto->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); | 169 | return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
163 | } | 170 | } |
164 | 171 | ||
165 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) | 172 | int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t length) |
@@ -184,7 +191,7 @@ int handle_ping_request(void * object, IP_Port source, uint8_t *packet, uint32_t | |||
184 | return 1; | 191 | return 1; |
185 | 192 | ||
186 | // Send response | 193 | // Send response |
187 | send_ping_response(source, &p->client_id, ping_id); | 194 | send_ping_response(dht->c, source, &p->client_id, ping_id); |
188 | add_toping(dht, (uint8_t *) &p->client_id, source); | 195 | add_toping(dht, (uint8_t *) &p->client_id, source); |
189 | 196 | ||
190 | return 0; | 197 | return 0; |
@@ -212,7 +219,7 @@ int handle_ping_response(void * object, IP_Port source, uint8_t *packet, uint32_ | |||
212 | return 1; | 219 | return 1; |
213 | 220 | ||
214 | // Make sure ping_id is correct | 221 | // Make sure ping_id is correct |
215 | if (!is_pinging(source, ping_id)) | 222 | if (!is_pinging(dht->ping, source, ping_id)) |
216 | return 1; | 223 | return 1; |
217 | 224 | ||
218 | // Associate source ip with client_id | 225 | // Associate source ip with client_id |