diff options
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r-- | toxcore/net_crypto.c | 2531 |
1 files changed, 2029 insertions, 502 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 17d2e8ff..875c639f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -35,439 +35,1159 @@ static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection | |||
35 | return (uint32_t)crypt_connection_id >= c->crypto_connections_length; | 35 | return (uint32_t)crypt_connection_id >= c->crypto_connections_length; |
36 | } | 36 | } |
37 | 37 | ||
38 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ | 38 | /* return 0 if connection is dead. |
39 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) | 39 | * return 1 if connection is alive. |
40 | */ | ||
41 | static int is_alive(uint8_t status) | ||
40 | { | 42 | { |
41 | uint8_t check = 0; | 43 | if (status == CRYPTO_CONN_COOKIE_REQUESTING || |
42 | uint32_t i; | 44 | status == CRYPTO_CONN_HANDSHAKE_SENT || |
43 | 45 | status == CRYPTO_CONN_NOT_CONFIRMED || | |
44 | for (i = 0; i < length; ++i) { | 46 | status == CRYPTO_CONN_ESTABLISHED) { |
45 | check |= mem[i]; | 47 | return 1; |
46 | } | 48 | } |
47 | 49 | ||
48 | return check; // We return zero if mem is made out of zeroes. | 50 | return 0; |
49 | } | 51 | } |
50 | 52 | ||
51 | /* Precomputes the shared key from their public_key and our secret_key. | 53 | /* cookie timeout in seconds */ |
52 | * This way we can avoid an expensive elliptic curve scalar multiply for each | 54 | #define COOKIE_TIMEOUT 10 |
53 | * encrypt/decrypt operation. | 55 | #define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2) |
54 | * enc_key has to be crypto_box_BEFORENMBYTES bytes long. | 56 | #define COOKIE_CONTENTS_LENGTH (sizeof(uint64_t) + COOKIE_DATA_LENGTH) |
57 | #define COOKIE_LENGTH (crypto_box_NONCEBYTES + COOKIE_CONTENTS_LENGTH + crypto_box_MACBYTES) | ||
58 | |||
59 | #define COOKIE_REQUEST_PLAIN_LENGTH (COOKIE_DATA_LENGTH + sizeof(uint64_t)) | ||
60 | #define COOKIE_REQUEST_LENGTH (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES) | ||
61 | #define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + sizeof(uint64_t) + crypto_box_MACBYTES) | ||
62 | |||
63 | /* Create a cookie request packet and put it in packet. | ||
64 | * dht_public_key is the dht public key of the other | ||
65 | * | ||
66 | * packet must be of size COOKIE_REQUEST_LENGTH or bigger. | ||
67 | * | ||
68 | * return -1 on failure. | ||
69 | * return COOKIE_REQUEST_LENGTH on success. | ||
55 | */ | 70 | */ |
56 | void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key) | 71 | static int create_cookie_request(Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number, |
72 | uint8_t *shared_key) | ||
57 | { | 73 | { |
58 | crypto_box_beforenm(enc_key, public_key, secret_key); | 74 | uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; |
75 | uint8_t padding[crypto_box_PUBLICKEYBYTES] = {0}; | ||
76 | |||
77 | memcpy(plain, c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
78 | memcpy(plain + crypto_box_PUBLICKEYBYTES, padding, crypto_box_PUBLICKEYBYTES); | ||
79 | memcpy(plain + (crypto_box_PUBLICKEYBYTES * 2), &number, sizeof(uint64_t)); | ||
80 | |||
81 | DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key); | ||
82 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
83 | new_nonce(nonce); | ||
84 | packet[0] = NET_PACKET_COOKIE_REQUEST; | ||
85 | memcpy(packet + 1, c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
86 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | ||
87 | int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain), | ||
88 | packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | ||
89 | |||
90 | if (len != COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES) | ||
91 | return -1; | ||
92 | |||
93 | return (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + len); | ||
59 | } | 94 | } |
60 | 95 | ||
61 | /* Fast encrypt. Depends on enc_key from encrypt_precompute. */ | 96 | /* Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key |
62 | int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | 97 | * |
63 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | 98 | * return -1 on failure. |
99 | * return 0 on success. | ||
100 | */ | ||
101 | static int create_cookie(uint8_t *cookie, uint8_t *bytes, uint8_t *encryption_key) | ||
64 | { | 102 | { |
65 | if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) | 103 | uint8_t contents[COOKIE_CONTENTS_LENGTH]; |
104 | uint64_t temp_time = unix_time(); | ||
105 | memcpy(contents, &temp_time, sizeof(temp_time)); | ||
106 | memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH); | ||
107 | new_nonce(cookie); | ||
108 | int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + crypto_box_NONCEBYTES); | ||
109 | |||
110 | if (len != COOKIE_LENGTH - crypto_box_NONCEBYTES) | ||
66 | return -1; | 111 | return -1; |
67 | 112 | ||
68 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; | 113 | return 0; |
69 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES]; | 114 | } |
115 | |||
116 | /* Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key | ||
117 | * | ||
118 | * return -1 on failure. | ||
119 | * return 0 on success. | ||
120 | */ | ||
121 | static int open_cookie(uint8_t *bytes, uint8_t *cookie, uint8_t *encryption_key) | ||
122 | { | ||
123 | uint8_t contents[COOKIE_CONTENTS_LENGTH]; | ||
124 | int len = decrypt_data_symmetric(encryption_key, cookie, cookie + crypto_box_NONCEBYTES, | ||
125 | COOKIE_LENGTH - crypto_box_NONCEBYTES, contents); | ||
70 | 126 | ||
71 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. | 127 | if (len != sizeof(contents)) |
128 | return -1; | ||
72 | 129 | ||
73 | crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key); | 130 | uint64_t cookie_time; |
131 | memcpy(&cookie_time, contents, sizeof(cookie_time)); | ||
132 | uint64_t temp_time = unix_time(); | ||
74 | 133 | ||
75 | if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) | 134 | if (cookie_time + COOKIE_TIMEOUT < temp_time || temp_time < cookie_time) |
76 | return -1; | 135 | return -1; |
77 | 136 | ||
78 | /* Unpad the encrypted message. */ | 137 | memcpy(bytes, contents + sizeof(cookie_time), COOKIE_DATA_LENGTH); |
79 | memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); | 138 | return 0; |
80 | return length + crypto_box_MACBYTES; | ||
81 | } | 139 | } |
82 | 140 | ||
83 | /* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ | 141 | |
84 | int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | 142 | /* Create a cookie response packet and put it in packet. |
85 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | 143 | * request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes. |
144 | * packet must be of size COOKIE_RESPONSE_LENGTH or bigger. | ||
145 | * | ||
146 | * return -1 on failure. | ||
147 | * return COOKIE_RESPONSE_LENGTH on success. | ||
148 | */ | ||
149 | static int create_cookie_response(Net_Crypto *c, uint8_t *packet, uint8_t *request_plain, uint8_t *shared_key, | ||
150 | uint8_t *dht_public_key) | ||
86 | { | 151 | { |
87 | if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) | 152 | uint8_t cookie_plain[COOKIE_DATA_LENGTH]; |
153 | memcpy(cookie_plain, request_plain, crypto_box_PUBLICKEYBYTES); | ||
154 | memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, dht_public_key, crypto_box_PUBLICKEYBYTES); | ||
155 | uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; | ||
156 | |||
157 | if (create_cookie(plain, cookie_plain, c->secret_symmetric_key) != 0) | ||
88 | return -1; | 158 | return -1; |
89 | 159 | ||
90 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; | 160 | memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t)); |
91 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0}; | 161 | packet[0] = NET_PACKET_COOKIE_RESPONSE; |
162 | new_nonce(packet + 1); | ||
163 | int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + crypto_box_NONCEBYTES); | ||
164 | |||
165 | if (len != COOKIE_RESPONSE_LENGTH - (1 + crypto_box_NONCEBYTES)) | ||
166 | return -1; | ||
92 | 167 | ||
93 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes. | 168 | return COOKIE_RESPONSE_LENGTH; |
169 | } | ||
94 | 170 | ||
95 | if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, | 171 | /* Handle the cookie request packet of length length. |
96 | nonce, enc_key) == -1) | 172 | * Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH) |
173 | * Put the key used to decrypt the request into shared_key (of size crypto_box_BEFORENMBYTES) for use in the response. | ||
174 | * | ||
175 | * return -1 on failure. | ||
176 | * return 0 on success. | ||
177 | */ | ||
178 | static int handle_cookie_request(Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, | ||
179 | uint8_t *packet, uint16_t length) | ||
180 | { | ||
181 | if (length != COOKIE_REQUEST_LENGTH) | ||
97 | return -1; | 182 | return -1; |
98 | 183 | ||
99 | /* If decryption is successful the first crypto_box_ZEROBYTES of the message will be zero. | 184 | memcpy(dht_public_key, packet + 1, crypto_box_PUBLICKEYBYTES); |
100 | * Apparently memcmp should not be used so we do this instead: | 185 | DHT_get_shared_key_sent(c->dht, shared_key, dht_public_key); |
101 | */ | 186 | int len = decrypt_data_symmetric(shared_key, packet + 1 + crypto_box_PUBLICKEYBYTES, |
102 | if (crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) | 187 | packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, COOKIE_REQUEST_PLAIN_LENGTH + crypto_box_MACBYTES, |
188 | request_plain); | ||
189 | |||
190 | if (len != COOKIE_REQUEST_PLAIN_LENGTH) | ||
103 | return -1; | 191 | return -1; |
104 | 192 | ||
105 | /* Unpad the plain message. */ | 193 | return 0; |
106 | memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); | ||
107 | return length - crypto_box_MACBYTES; | ||
108 | } | 194 | } |
109 | 195 | ||
110 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 196 | /* Handle the cookie request packet (for raw UDP) |
111 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | 197 | */ |
198 | static int udp_handle_cookie_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) | ||
112 | { | 199 | { |
113 | uint8_t k[crypto_box_BEFORENMBYTES]; | 200 | Net_Crypto *c = object; |
114 | encrypt_precompute(public_key, secret_key, k); | 201 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; |
115 | return encrypt_data_fast(k, nonce, plain, length, encrypted); | 202 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
203 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; | ||
204 | |||
205 | if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0) | ||
206 | return 1; | ||
207 | |||
208 | uint8_t data[COOKIE_RESPONSE_LENGTH]; | ||
209 | |||
210 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) | ||
211 | return 1; | ||
212 | |||
213 | if ((uint32_t)sendpacket(c->dht->net, source, data, sizeof(data)) != sizeof(data)) | ||
214 | return 1; | ||
215 | |||
216 | return 0; | ||
116 | } | 217 | } |
117 | 218 | ||
118 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 219 | /* Handle the cookie request packet (for TCP) |
119 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | 220 | */ |
221 | static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, uint8_t *packet, | ||
222 | uint32_t length) | ||
120 | { | 223 | { |
121 | uint8_t k[crypto_box_BEFORENMBYTES]; | 224 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; |
122 | encrypt_precompute(public_key, secret_key, k); | 225 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
123 | return decrypt_data_fast(k, nonce, encrypted, length, plain); | 226 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; |
227 | |||
228 | if (handle_cookie_request(c, request_plain, shared_key, dht_public_key, packet, length) != 0) | ||
229 | return -1; | ||
230 | |||
231 | uint8_t data[COOKIE_RESPONSE_LENGTH]; | ||
232 | |||
233 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) | ||
234 | return -1; | ||
235 | |||
236 | if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1) | ||
237 | return -1; | ||
238 | |||
239 | return 0; | ||
124 | } | 240 | } |
125 | 241 | ||
126 | int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted) | 242 | /* Handle the cookie request packet (for TCP oob packets) |
243 | */ | ||
244 | static int tcp_oob_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t *dht_public_key, | ||
245 | uint8_t *packet, uint32_t length) | ||
127 | { | 246 | { |
128 | if (length == 0) | 247 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; |
248 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; | ||
249 | uint8_t dht_public_key_temp[crypto_box_PUBLICKEYBYTES]; | ||
250 | |||
251 | if (handle_cookie_request(c, request_plain, shared_key, dht_public_key_temp, packet, length) != 0) | ||
252 | return -1; | ||
253 | |||
254 | if (memcmp(dht_public_key, dht_public_key_temp, crypto_box_PUBLICKEYBYTES) != 0) | ||
129 | return -1; | 255 | return -1; |
130 | 256 | ||
131 | uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES]; | 257 | uint8_t data[COOKIE_RESPONSE_LENGTH]; |
132 | uint8_t temp_encrypted[length + crypto_secretbox_MACBYTES + crypto_secretbox_BOXZEROBYTES]; | 258 | |
259 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) | ||
260 | return -1; | ||
133 | 261 | ||
134 | memset(temp_plain, 0, crypto_secretbox_ZEROBYTES); | 262 | if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1) |
135 | memcpy(temp_plain + crypto_secretbox_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. | 263 | return -1; |
136 | 264 | ||
137 | crypto_secretbox(temp_encrypted, temp_plain, length + crypto_secretbox_ZEROBYTES, nonce, secret_key); | 265 | return 0; |
138 | /* Unpad the encrypted message. */ | ||
139 | memcpy(encrypted, temp_encrypted + crypto_secretbox_BOXZEROBYTES, length + crypto_secretbox_MACBYTES); | ||
140 | return length + crypto_secretbox_MACBYTES; | ||
141 | } | 266 | } |
142 | 267 | ||
143 | int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain) | 268 | /* Handle a cookie response packet of length encrypted with shared_key. |
269 | * put the cookie in the response in cookie | ||
270 | * | ||
271 | * cookie must be of length COOKIE_LENGTH. | ||
272 | * | ||
273 | * return -1 on failure. | ||
274 | * return COOKIE_LENGTH on success. | ||
275 | */ | ||
276 | static int handle_cookie_response(uint8_t *cookie, uint64_t *number, uint8_t *packet, uint32_t length, | ||
277 | uint8_t *shared_key) | ||
278 | { | ||
279 | if (length != COOKIE_RESPONSE_LENGTH) | ||
280 | return -1; | ||
281 | |||
282 | uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; | ||
283 | int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES, | ||
284 | length - (1 + crypto_box_NONCEBYTES), plain); | ||
285 | |||
286 | if (len != sizeof(plain)) | ||
287 | return -1; | ||
288 | |||
289 | memcpy(cookie, plain, COOKIE_LENGTH); | ||
290 | memcpy(number, plain + COOKIE_LENGTH, sizeof(uint64_t)); | ||
291 | return COOKIE_LENGTH; | ||
292 | } | ||
293 | |||
294 | #define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH + crypto_box_MACBYTES) | ||
295 | |||
296 | /* Create a handshake packet and put it in packet. | ||
297 | * cookie must be COOKIE_LENGTH bytes. | ||
298 | * packet must be of size HANDSHAKE_PACKET_LENGTH or bigger. | ||
299 | * | ||
300 | * return -1 on failure. | ||
301 | * return HANDSHAKE_PACKET_LENGTH on success. | ||
302 | */ | ||
303 | static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk, | ||
304 | uint8_t *peer_real_pk, uint8_t *peer_dht_pubkey) | ||
305 | { | ||
306 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH]; | ||
307 | memcpy(plain, nonce, crypto_box_NONCEBYTES); | ||
308 | memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES); | ||
309 | crypto_hash_sha512(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, cookie, COOKIE_LENGTH); | ||
310 | uint8_t cookie_plain[COOKIE_DATA_LENGTH]; | ||
311 | memcpy(cookie_plain, peer_real_pk, crypto_box_PUBLICKEYBYTES); | ||
312 | memcpy(cookie_plain + crypto_box_PUBLICKEYBYTES, peer_dht_pubkey, crypto_box_PUBLICKEYBYTES); | ||
313 | |||
314 | if (create_cookie(plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, cookie_plain, | ||
315 | c->secret_symmetric_key) != 0) | ||
316 | return -1; | ||
317 | |||
318 | new_nonce(packet + 1 + COOKIE_LENGTH); | ||
319 | int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), | ||
320 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES); | ||
321 | |||
322 | if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES)) | ||
323 | return -1; | ||
324 | |||
325 | packet[0] = NET_PACKET_CRYPTO_HS; | ||
326 | memcpy(packet + 1, cookie, COOKIE_LENGTH); | ||
327 | |||
328 | return HANDSHAKE_PACKET_LENGTH; | ||
329 | } | ||
330 | |||
331 | /* Handle a crypto handshake packet of length. | ||
332 | * put the nonce contained in the packet in nonce, | ||
333 | * the session public key in session_pk | ||
334 | * the real public key of the peer in peer_real_pk | ||
335 | * the dht public key of the peer in dht_public_key and | ||
336 | * the cookie inside the encrypted part of the packet in cookie. | ||
337 | * | ||
338 | * if expected_real_pk isn't NULL it denotes the real public key | ||
339 | * the packet should be from. | ||
340 | * | ||
341 | * nonce must be at least crypto_box_NONCEBYTES | ||
342 | * session_pk must be at least crypto_box_PUBLICKEYBYTES | ||
343 | * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES | ||
344 | * cookie must be at least COOKIE_LENGTH | ||
345 | * | ||
346 | * return -1 on failure. | ||
347 | * return 0 on success. | ||
348 | */ | ||
349 | static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, | ||
350 | uint8_t *dht_public_key, uint8_t *cookie, uint8_t *packet, uint32_t length, uint8_t *expected_real_pk) | ||
144 | { | 351 | { |
145 | if (length <= crypto_secretbox_BOXZEROBYTES) | 352 | if (length != HANDSHAKE_PACKET_LENGTH) |
353 | return -1; | ||
354 | |||
355 | uint8_t cookie_plain[COOKIE_DATA_LENGTH]; | ||
356 | |||
357 | if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0) | ||
146 | return -1; | 358 | return -1; |
147 | 359 | ||
148 | uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES]; | 360 | if (expected_real_pk) |
149 | uint8_t temp_encrypted[length + crypto_secretbox_BOXZEROBYTES]; | 361 | if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0) |
362 | return -1; | ||
363 | |||
364 | uint8_t cookie_hash[crypto_hash_sha512_BYTES]; | ||
365 | crypto_hash_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); | ||
150 | 366 | ||
151 | memset(temp_plain, 0, crypto_secretbox_BOXZEROBYTES); | 367 | uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH]; |
152 | memcpy(temp_encrypted + crypto_secretbox_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes. | 368 | int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, |
369 | packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES, | ||
370 | HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain); | ||
153 | 371 | ||
154 | if (crypto_secretbox_open(temp_plain, temp_encrypted, length + crypto_secretbox_BOXZEROBYTES, nonce, secret_key) == -1) | 372 | if (len != sizeof(plain)) |
155 | return -1; | 373 | return -1; |
156 | 374 | ||
157 | memcpy(plain, temp_plain + crypto_secretbox_ZEROBYTES, length - crypto_secretbox_MACBYTES); | 375 | if (memcmp(cookie_hash, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, crypto_hash_sha512_BYTES) != 0) |
158 | return length - crypto_secretbox_MACBYTES; | 376 | return -1; |
377 | |||
378 | memcpy(nonce, plain, crypto_box_NONCEBYTES); | ||
379 | memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); | ||
380 | memcpy(cookie, plain + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES, COOKIE_LENGTH); | ||
381 | memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES); | ||
382 | memcpy(dht_public_key, cookie_plain + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | ||
383 | return 0; | ||
159 | } | 384 | } |
160 | 385 | ||
161 | /* Increment the given nonce by 1. */ | 386 | |
162 | void increment_nonce(uint8_t *nonce) | 387 | static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connection_id) |
163 | { | 388 | { |
389 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) | ||
390 | return 0; | ||
391 | |||
392 | return &c->crypto_connections[crypt_connection_id]; | ||
393 | } | ||
394 | |||
395 | |||
396 | /* Sends a packet to the peer using the fastest route. | ||
397 | * | ||
398 | * return -1 on failure. | ||
399 | * return 0 on success. | ||
400 | */ | ||
401 | static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) | ||
402 | { | ||
403 | //TODO TCP, etc... | ||
404 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
405 | |||
406 | if (conn == 0) | ||
407 | return -1; | ||
408 | |||
409 | int direct_send_attempt = 0; | ||
410 | |||
411 | //TODO: on bad networks, direct connections might not last indefinitely. | ||
412 | if (conn->ip_port.ip.family != 0) { | ||
413 | uint8_t direct_connected = 0; | ||
414 | crypto_connection_status(c, crypt_connection_id, &direct_connected); | ||
415 | |||
416 | if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) | ||
417 | return 0; | ||
418 | |||
419 | //TODO: a better way of sending packets directly to confirm the others ip. | ||
420 | if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) { | ||
421 | if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) | ||
422 | direct_send_attempt = 1; | ||
423 | } | ||
424 | |||
425 | } | ||
426 | |||
427 | //TODO: spread packets over many relays, detect and kill bad relays. | ||
164 | uint32_t i; | 428 | uint32_t i; |
165 | 429 | ||
166 | for (i = 0; i < crypto_box_NONCEBYTES; ++i) { | 430 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
167 | ++nonce[i]; | 431 | if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ |
432 | if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1) | ||
433 | return 0; | ||
434 | } | ||
435 | } | ||
168 | 436 | ||
169 | if (nonce[i] != 0) | 437 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
170 | break; | 438 | if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) { |
439 | if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1) | ||
440 | return 0; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | if (direct_send_attempt) { | ||
445 | return 0; | ||
171 | } | 446 | } |
447 | |||
448 | return -1; | ||
172 | } | 449 | } |
173 | 450 | ||
174 | #if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES | 451 | /** START: Array Related functions **/ |
175 | /*if they no longer equal each other, this function must be split into two.*/ | 452 | |
176 | #error random_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES. | 453 | |
177 | #endif | 454 | /* Return number of packets in array |
178 | /* Fill the given nonce with random bytes. */ | 455 | * Note that holes are counted too. |
179 | void random_nonce(uint8_t *nonce) | 456 | */ |
457 | static uint32_t num_packets_array(Packets_Array *array) | ||
180 | { | 458 | { |
181 | randombytes(nonce, crypto_box_NONCEBYTES); | 459 | return array->buffer_end - array->buffer_start; |
182 | } | 460 | } |
183 | 461 | ||
184 | /* Fill a key crypto_secretbox_KEYBYTES big with random bytes */ | 462 | /* Add data with packet number to array. |
185 | void new_symmetric_key(uint8_t *key) | 463 | * |
464 | * return -1 on failure. | ||
465 | * return 0 on success. | ||
466 | */ | ||
467 | static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data *data) | ||
186 | { | 468 | { |
187 | randombytes(key, crypto_secretbox_KEYBYTES); | 469 | if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE) |
470 | return -1; | ||
471 | |||
472 | uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE; | ||
473 | |||
474 | if (array->buffer[num]) | ||
475 | return -1; | ||
476 | |||
477 | Packet_Data *new_d = malloc(sizeof(Packet_Data)); | ||
478 | |||
479 | if (new_d == NULL) | ||
480 | return -1; | ||
481 | |||
482 | memcpy(new_d, data, sizeof(Packet_Data)); | ||
483 | array->buffer[num] = new_d; | ||
484 | |||
485 | if ((number - array->buffer_start) >= (array->buffer_end - array->buffer_start)) | ||
486 | array->buffer_end = number + 1; | ||
487 | |||
488 | return 0; | ||
188 | } | 489 | } |
189 | 490 | ||
190 | static uint8_t base_nonce[crypto_box_NONCEBYTES]; | 491 | /* Get pointer of data with packet number. |
191 | static uint8_t nonce_set = 0; | 492 | * |
493 | * return -1 on failure. | ||
494 | * return 0 if data at number is empty. | ||
495 | * return 1 if data pointer was put in data. | ||
496 | */ | ||
497 | static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t number) | ||
498 | { | ||
499 | uint32_t num_spots = array->buffer_end - array->buffer_start; | ||
500 | |||
501 | if (array->buffer_end - number > num_spots || number - array->buffer_start >= num_spots) | ||
502 | return -1; | ||
503 | |||
504 | uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE; | ||
192 | 505 | ||
193 | #if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES | 506 | if (!array->buffer[num]) |
194 | /*if they no longer equal each other, this function must be split into two.*/ | 507 | return 0; |
195 | #error new_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES. | 508 | |
196 | #endif | 509 | *data = array->buffer[num]; |
197 | /* Gives a nonce guaranteed to be different from previous ones.*/ | 510 | return 1; |
198 | void new_nonce(uint8_t *nonce) | 511 | } |
512 | |||
513 | /* Add data to end of array. | ||
514 | * | ||
515 | * return -1 on failure. | ||
516 | * return packet number on success. | ||
517 | */ | ||
518 | static int64_t add_data_end_of_buffer(Packets_Array *array, Packet_Data *data) | ||
199 | { | 519 | { |
200 | if (nonce_set == 0) { | 520 | if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE) |
201 | random_nonce(base_nonce); | 521 | return -1; |
202 | nonce_set = 1; | 522 | |
203 | } | 523 | Packet_Data *new_d = malloc(sizeof(Packet_Data)); |
524 | |||
525 | if (new_d == NULL) | ||
526 | return -1; | ||
204 | 527 | ||
205 | increment_nonce(base_nonce); | 528 | memcpy(new_d, data, sizeof(Packet_Data)); |
206 | memcpy(nonce, base_nonce, crypto_box_NONCEBYTES); | 529 | uint32_t id = array->buffer_end; |
530 | array->buffer[id % CRYPTO_PACKET_BUFFER_SIZE] = new_d; | ||
531 | ++array->buffer_end; | ||
532 | return id; | ||
207 | } | 533 | } |
208 | 534 | ||
535 | /* Read data from begginning of array. | ||
536 | * | ||
537 | * return -1 on failure. | ||
538 | * return packet number on success. | ||
539 | */ | ||
540 | static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) | ||
541 | { | ||
542 | if (array->buffer_end == array->buffer_start) | ||
543 | return -1; | ||
209 | 544 | ||
210 | /* return 0 if there is no received data in the buffer. | 545 | uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE; |
211 | * return -1 if the packet was discarded. | 546 | |
212 | * return length of received data if successful. | 547 | if (!array->buffer[num]) |
548 | return -1; | ||
549 | |||
550 | memcpy(data, array->buffer[num], sizeof(Packet_Data)); | ||
551 | uint32_t id = array->buffer_start; | ||
552 | ++array->buffer_start; | ||
553 | free(array->buffer[num]); | ||
554 | array->buffer[num] = NULL; | ||
555 | return id; | ||
556 | } | ||
557 | |||
558 | /* Delete all packets in array before number (but not number) | ||
559 | * | ||
560 | * return -1 on failure. | ||
561 | * return 0 on success | ||
213 | */ | 562 | */ |
214 | int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data) | 563 | static int clear_buffer_until(Packets_Array *array, uint32_t number) |
215 | { | 564 | { |
216 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) | 565 | uint32_t num_spots = array->buffer_end - array->buffer_start; |
217 | return 0; | ||
218 | 566 | ||
219 | if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED) | 567 | if (array->buffer_end - number >= num_spots || number - array->buffer_start > num_spots) |
220 | return 0; | 568 | return -1; |
569 | |||
570 | uint32_t i; | ||
221 | 571 | ||
222 | uint8_t temp_data[MAX_DATA_SIZE]; | 572 | for (i = array->buffer_start; i != number; ++i) { |
223 | int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data); | 573 | uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; |
224 | 574 | ||
225 | if (length == 0) | 575 | if (array->buffer[num]) { |
226 | return 0; | 576 | free(array->buffer[num]); |
577 | array->buffer[num] = NULL; | ||
578 | } | ||
579 | } | ||
580 | |||
581 | array->buffer_start = i; | ||
582 | return 0; | ||
583 | } | ||
227 | 584 | ||
228 | if (temp_data[0] != 3) | 585 | /* Set array buffer end to number. |
586 | * | ||
587 | * return -1 on failure. | ||
588 | * return 0 on success. | ||
589 | */ | ||
590 | static int set_buffer_end(Packets_Array *array, uint32_t number) | ||
591 | { | ||
592 | if ((number - array->buffer_start) > CRYPTO_PACKET_BUFFER_SIZE) | ||
593 | return -1; | ||
594 | |||
595 | if ((number - array->buffer_end) > CRYPTO_PACKET_BUFFER_SIZE) | ||
229 | return -1; | 596 | return -1; |
230 | 597 | ||
231 | int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, | 598 | array->buffer_end = number; |
232 | c->crypto_connections[crypt_connection_id].recv_nonce, | 599 | return 0; |
233 | temp_data + 1, length - 1, data); | 600 | } |
601 | |||
602 | /* Create a packet request packet from recv_array and send_buffer_end into | ||
603 | * data of length. | ||
604 | * | ||
605 | * return -1 on failure. | ||
606 | * return length of packet on success. | ||
607 | */ | ||
608 | static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array *recv_array, uint32_t send_buffer_end) | ||
609 | { | ||
610 | if (length <= (sizeof(uint32_t) * 2)) | ||
611 | return -1; | ||
612 | |||
613 | uint32_t recv_buffer_start = htonl(recv_array->buffer_start); | ||
614 | send_buffer_end = htonl(send_buffer_end); | ||
615 | memcpy(data, &recv_buffer_start, sizeof(uint32_t)); | ||
616 | memcpy(data + sizeof(uint32_t), &send_buffer_end, sizeof(uint32_t)); | ||
617 | data[sizeof(uint32_t) * 2] = PACKET_ID_REQUEST; | ||
618 | |||
619 | uint16_t cur_len = sizeof(uint32_t) * 2 + 1; | ||
620 | |||
621 | if (recv_array->buffer_start == recv_array->buffer_end) | ||
622 | return cur_len; | ||
623 | |||
624 | if (length <= cur_len) | ||
625 | return cur_len; | ||
626 | |||
627 | uint32_t i, n = 1; | ||
628 | |||
629 | for (i = recv_array->buffer_start; i != recv_array->buffer_end; ++i) { | ||
630 | uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; | ||
631 | |||
632 | if (!recv_array->buffer[num]) { | ||
633 | data[cur_len] = n; | ||
634 | n = 0; | ||
635 | ++cur_len; | ||
636 | |||
637 | if (length <= cur_len) | ||
638 | return cur_len; | ||
639 | |||
640 | } else if (n == 255) { | ||
641 | data[cur_len] = 0; | ||
642 | n = 0; | ||
643 | ++cur_len; | ||
644 | |||
645 | if (length <= cur_len) | ||
646 | return cur_len; | ||
647 | } | ||
234 | 648 | ||
235 | if (len != -1) { | 649 | ++n; |
236 | increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce); | ||
237 | return len; | ||
238 | } | 650 | } |
239 | 651 | ||
240 | return -1; | 652 | return cur_len; |
241 | } | 653 | } |
242 | 654 | ||
243 | /* returns the number of packet slots left in the sendbuffer. | 655 | /* Handle a request data packet. |
244 | * return 0 if failure. | 656 | * Remove all the packets the other recieved from the array. |
657 | * | ||
658 | * return -1 on failure. | ||
659 | * return number of requested packets on success. | ||
245 | */ | 660 | */ |
246 | uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) | 661 | static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint16_t length) |
247 | { | 662 | { |
248 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) | 663 | if (length < 1) |
664 | return -1; | ||
665 | |||
666 | if (data[0] != PACKET_ID_REQUEST) | ||
667 | return -1; | ||
668 | |||
669 | if (length == 1) | ||
249 | return 0; | 670 | return 0; |
250 | 671 | ||
251 | return num_free_sendqueue_slots(c->lossless_udp, c->crypto_connections[crypt_connection_id].number); | 672 | ++data; |
673 | --length; | ||
674 | |||
675 | uint32_t i, n = 1; | ||
676 | uint32_t requested = 0; | ||
677 | |||
678 | for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) { | ||
679 | if (length == 0) | ||
680 | break; | ||
681 | |||
682 | uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; | ||
683 | |||
684 | if (n == data[0]) { | ||
685 | if (send_array->buffer[num]) { | ||
686 | send_array->buffer[num]->time = 0; | ||
687 | } | ||
688 | |||
689 | ++data; | ||
690 | --length; | ||
691 | n = 0; | ||
692 | ++requested; | ||
693 | } else { | ||
694 | free(send_array->buffer[num]); | ||
695 | send_array->buffer[num] = NULL; | ||
696 | } | ||
697 | |||
698 | if (n == 255) { | ||
699 | n = 1; | ||
700 | |||
701 | if (data[0] != 0) | ||
702 | return -1; | ||
703 | |||
704 | ++data; | ||
705 | --length; | ||
706 | } else { | ||
707 | ++n; | ||
708 | } | ||
709 | } | ||
710 | |||
711 | return requested; | ||
252 | } | 712 | } |
253 | 713 | ||
254 | /* return 0 if data could not be put in packet queue. | 714 | /** END: Array Related functions **/ |
255 | * return 1 if data was put into the queue. | 715 | |
716 | #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES)) | ||
717 | |||
718 | /* Creates and sends a data packet to the peer using the fastest route. | ||
719 | * | ||
720 | * return -1 on failure. | ||
721 | * return 0 on success. | ||
256 | */ | 722 | */ |
257 | int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) | 723 | static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) |
258 | { | 724 | { |
259 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) | 725 | if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE) |
260 | return 0; | 726 | return -1; |
261 | 727 | ||
262 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) | 728 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
263 | return 0; | ||
264 | 729 | ||
265 | if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED) | 730 | if (conn == 0) |
266 | return 0; | 731 | return -1; |
267 | 732 | ||
268 | uint8_t temp_data[MAX_DATA_SIZE]; | 733 | uint8_t packet[1 + sizeof(uint16_t) + length + crypto_box_MACBYTES]; |
269 | int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, | 734 | packet[0] = NET_PACKET_CRYPTO_DATA; |
270 | c->crypto_connections[crypt_connection_id].sent_nonce, | 735 | memcpy(packet + 1, conn->sent_nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t)); |
271 | data, length, temp_data + 1); | 736 | int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); |
272 | 737 | ||
273 | if (len == -1) | 738 | if (len + 1 + sizeof(uint16_t) != sizeof(packet)) |
274 | return 0; | 739 | return -1; |
275 | 740 | ||
276 | temp_data[0] = 3; | 741 | increment_nonce(conn->sent_nonce); |
742 | return send_packet_to(c, crypt_connection_id, packet, sizeof(packet)); | ||
743 | } | ||
277 | 744 | ||
278 | if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) | 745 | /* Creates and sends a data packet with buffer_start and num to the peer using the fastest route. |
279 | return 0; | 746 | * |
747 | * return -1 on failure. | ||
748 | * return 0 on success. | ||
749 | */ | ||
750 | static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, | ||
751 | uint8_t *data, uint32_t length) | ||
752 | { | ||
753 | num = htonl(num); | ||
754 | buffer_start = htonl(buffer_start); | ||
755 | uint8_t packet[sizeof(uint32_t) + sizeof(uint32_t) + length]; | ||
756 | memcpy(packet, &buffer_start, sizeof(uint32_t)); | ||
757 | memcpy(packet + sizeof(uint32_t), &num, sizeof(uint32_t)); | ||
758 | memcpy(packet + (sizeof(uint32_t) * 2), data, length); | ||
759 | |||
760 | return send_data_packet(c, crypt_connection_id, packet, sizeof(packet)); | ||
761 | } | ||
280 | 762 | ||
281 | increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce); | 763 | /* return -1 if data could not be put in packet queue. |
282 | return 1; | 764 | * return positive packet number if data was put into the queue. |
765 | */ | ||
766 | static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) | ||
767 | { | ||
768 | if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) | ||
769 | return -1; | ||
770 | |||
771 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
772 | |||
773 | if (conn == 0) | ||
774 | return -1; | ||
775 | |||
776 | Packet_Data dt; | ||
777 | dt.time = current_time_monotonic(); | ||
778 | dt.length = length; | ||
779 | memcpy(dt.data, data, length); | ||
780 | int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt); | ||
781 | |||
782 | if (packet_num == -1) | ||
783 | return -1; | ||
784 | |||
785 | if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0) | ||
786 | fprintf(stderr, "send_data_packet failed\n"); | ||
787 | |||
788 | return packet_num; | ||
789 | } | ||
790 | |||
791 | /* Get the lowest 2 bytes from the nonce and convert | ||
792 | * them to host byte format before returning them. | ||
793 | */ | ||
794 | static uint16_t get_nonce_uint16(uint8_t *nonce) | ||
795 | { | ||
796 | uint16_t num; | ||
797 | memcpy(&num, nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t)); | ||
798 | return ntohs(num); | ||
283 | } | 799 | } |
284 | 800 | ||
285 | /* Create a request to peer. | 801 | #define DATA_NUM_THRESHOLD 21845 |
286 | * send_public_key and send_secret_key are the pub/secret keys of the sender. | 802 | |
287 | * recv_public_key is public key of reciever. | 803 | /* Handle a data packet. |
288 | * packet must be an array of MAX_DATA_SIZE big. | 804 | * Decrypt packet of length and put it into data. |
289 | * Data represents the data we send with the request with length being the length of the data. | 805 | * data must be at least MAX_DATA_DATA_PACKET_SIZE big. |
290 | * request_id is the id of the request (32 = friend request, 254 = ping request). | ||
291 | * | 806 | * |
292 | * return -1 on failure. | 807 | * return -1 on failure. |
293 | * return the length of the created packet on success. | 808 | * return length of data on success. |
294 | */ | 809 | */ |
295 | int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, | 810 | static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint8_t *packet, uint16_t length) |
296 | uint8_t *data, uint32_t length, uint8_t request_id) | ||
297 | { | 811 | { |
298 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES) | 812 | if (length <= (1 + sizeof(uint16_t) + crypto_box_MACBYTES) || length > MAX_CRYPTO_PACKET_SIZE) |
813 | return -1; | ||
814 | |||
815 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
816 | |||
817 | if (conn == 0) | ||
299 | return -1; | 818 | return -1; |
300 | 819 | ||
301 | uint8_t nonce[crypto_box_NONCEBYTES]; | 820 | uint8_t nonce[crypto_box_NONCEBYTES]; |
302 | uint8_t temp[MAX_DATA_SIZE]; | 821 | memcpy(nonce, conn->recv_nonce, crypto_box_NONCEBYTES); |
303 | memcpy(temp + 1, data, length); | 822 | uint16_t num_cur_nonce = get_nonce_uint16(nonce); |
304 | temp[0] = request_id; | 823 | uint16_t num; |
305 | new_nonce(nonce); | 824 | memcpy(&num, packet + 1, sizeof(uint16_t)); |
306 | int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, | 825 | num = ntohs(num); |
307 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); | 826 | uint16_t diff = num - num_cur_nonce; |
827 | increment_nonce_number(nonce, diff); | ||
828 | int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), | ||
829 | length - (1 + sizeof(uint16_t)), data); | ||
830 | |||
831 | if ((unsigned int)len != length - (1 + sizeof(uint16_t) + crypto_box_MACBYTES)) | ||
832 | return -1; | ||
308 | 833 | ||
309 | if (len == -1) | 834 | if (diff > DATA_NUM_THRESHOLD * 2) { |
835 | increment_nonce_number(conn->recv_nonce, DATA_NUM_THRESHOLD); | ||
836 | } | ||
837 | |||
838 | return len; | ||
839 | } | ||
840 | |||
841 | /* Send a request packet. | ||
842 | * | ||
843 | * return -1 on failure. | ||
844 | * return 0 on success. | ||
845 | */ | ||
846 | static int send_request_packet(Net_Crypto *c, int crypt_connection_id) | ||
847 | { | ||
848 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
849 | |||
850 | if (conn == 0) | ||
310 | return -1; | 851 | return -1; |
311 | 852 | ||
312 | packet[0] = NET_PACKET_CRYPTO; | 853 | uint8_t packet[MAX_DATA_DATA_PACKET_SIZE]; |
313 | memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); | 854 | int len = generate_request_packet(packet, sizeof(packet), &conn->recv_array, conn->send_array.buffer_end); |
314 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); | ||
315 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); | ||
316 | 855 | ||
317 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; | 856 | if (len == -1) |
857 | return -1; | ||
858 | |||
859 | return send_data_packet(c, crypt_connection_id, packet, len); | ||
318 | } | 860 | } |
319 | 861 | ||
320 | /* Puts the senders public key in the request in public_key, the data from the request | 862 | /* Send up to max num previously requested data packets. |
321 | * in data if a friend or ping request was sent to us and returns the length of the data. | ||
322 | * packet is the request packet and length is its length. | ||
323 | * | 863 | * |
324 | * return -1 if not valid request. | 864 | * return -1 on failure. |
865 | * return number of packets sent on success. | ||
325 | */ | 866 | */ |
326 | int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, | 867 | static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num) |
327 | uint8_t *request_id, uint8_t *packet, uint16_t length) | ||
328 | { | 868 | { |
329 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES && | 869 | if (max_num == 0) |
330 | length <= MAX_DATA_SIZE) { | 870 | return -1; |
331 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
332 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | ||
333 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
334 | uint8_t temp[MAX_DATA_SIZE]; | ||
335 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); | ||
336 | int len1 = decrypt_data(public_key, self_secret_key, nonce, | ||
337 | packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, | ||
338 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); | ||
339 | 871 | ||
340 | if (len1 == -1 || len1 == 0) | 872 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
341 | return -1; | 873 | |
874 | if (conn == 0) | ||
875 | return -1; | ||
876 | |||
877 | uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array); | ||
342 | 878 | ||
343 | request_id[0] = temp[0]; | 879 | for (i = 0; i < array_size; ++i) { |
344 | --len1; | 880 | Packet_Data *dt; |
345 | memcpy(data, temp + 1, len1); | 881 | uint32_t packet_num = (i + conn->send_array.buffer_start); |
346 | return len1; | 882 | int ret = get_data_pointer(&conn->send_array, &dt, packet_num); |
883 | |||
884 | if (ret == -1) { | ||
885 | return -1; | ||
886 | } else if (ret == 0) { | ||
887 | continue; | ||
888 | } | ||
889 | |||
890 | if (dt->time != 0) { | ||
891 | continue; | ||
347 | } | 892 | } |
893 | |||
894 | dt->time = current_time_monotonic(); | ||
895 | |||
896 | if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data, | ||
897 | dt->length) == 0) | ||
898 | ++num_sent; | ||
899 | |||
900 | if (num_sent >= max_num) | ||
901 | break; | ||
348 | } | 902 | } |
349 | 903 | ||
350 | return -1; | 904 | return num_sent; |
351 | } | 905 | } |
352 | 906 | ||
353 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object) | 907 | |
908 | /* Add a new temp packet to send repeatedly. | ||
909 | * | ||
910 | * return -1 on failure. | ||
911 | * return 0 on success. | ||
912 | */ | ||
913 | static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) | ||
354 | { | 914 | { |
355 | c->cryptopackethandlers[byte].function = cb; | 915 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) |
356 | c->cryptopackethandlers[byte].object = object; | 916 | return -1; |
917 | |||
918 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
919 | |||
920 | if (conn == 0) | ||
921 | return -1; | ||
922 | |||
923 | uint8_t *temp_packet = malloc(length); | ||
924 | |||
925 | if (temp_packet == 0) | ||
926 | return -1; | ||
927 | |||
928 | if (conn->temp_packet) | ||
929 | free(conn->temp_packet); | ||
930 | |||
931 | memcpy(temp_packet, packet, length); | ||
932 | conn->temp_packet = temp_packet; | ||
933 | conn->temp_packet_length = length; | ||
934 | conn->temp_packet_sent_time = 0; | ||
935 | conn->temp_packet_num_sent = 0; | ||
936 | return 0; | ||
357 | } | 937 | } |
358 | 938 | ||
359 | static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 939 | /* Clear the temp packet. |
940 | * | ||
941 | * return -1 on failure. | ||
942 | * return 0 on success. | ||
943 | */ | ||
944 | static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id) | ||
360 | { | 945 | { |
361 | DHT *dht = object; | 946 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
362 | 947 | ||
363 | if (packet[0] == NET_PACKET_CRYPTO) { | 948 | if (conn == 0) |
364 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || | 949 | return -1; |
365 | length > MAX_DATA_SIZE + crypto_box_MACBYTES) | ||
366 | return 1; | ||
367 | 950 | ||
368 | if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. | 951 | if (conn->temp_packet) |
369 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 952 | free(conn->temp_packet); |
370 | uint8_t data[MAX_DATA_SIZE]; | ||
371 | uint8_t number; | ||
372 | int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length); | ||
373 | 953 | ||
374 | if (len == -1 || len == 0) | 954 | conn->temp_packet = 0; |
375 | return 1; | 955 | conn->temp_packet_length = 0; |
956 | conn->temp_packet_sent_time = 0; | ||
957 | conn->temp_packet_num_sent = 0; | ||
958 | return 0; | ||
959 | } | ||
376 | 960 | ||
377 | if (!dht->c->cryptopackethandlers[number].function) return 1; | ||
378 | 961 | ||
379 | return dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, | 962 | /* Send the temp packet. |
380 | data, len); | 963 | * |
964 | * return -1 on failure. | ||
965 | * return 0 on success. | ||
966 | */ | ||
967 | static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) | ||
968 | { | ||
969 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
381 | 970 | ||
382 | } else { /* If request is not for us, try routing it. */ | 971 | if (conn == 0) |
383 | int retval = route_packet(dht, packet + 1, packet, length); | 972 | return -1; |
384 | 973 | ||
385 | if ((unsigned int)retval == length) | 974 | if (!conn->temp_packet) |
386 | return 0; | 975 | return -1; |
387 | } | ||
388 | } | ||
389 | 976 | ||
390 | return 1; | 977 | if (send_packet_to(c, crypt_connection_id, conn->temp_packet, conn->temp_packet_length) != 0) |
978 | return -1; | ||
979 | |||
980 | conn->temp_packet_sent_time = current_time_monotonic(); | ||
981 | ++conn->temp_packet_num_sent; | ||
982 | return 0; | ||
391 | } | 983 | } |
392 | 984 | ||
393 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key | 985 | /* Create a handshake packet and set it as a temp packet. |
394 | * to peer with connection_id and public_key. | 986 | * cookie must be COOKIE_LENGTH. |
395 | * The packet is encrypted with a random nonce which is sent in plain text with the packet. | 987 | * |
988 | * return -1 on failure. | ||
989 | * return 0 on success. | ||
396 | */ | 990 | */ |
397 | static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, | 991 | static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, uint8_t *cookie, uint8_t *dht_public_key) |
398 | uint8_t *session_key) | ||
399 | { | 992 | { |
400 | uint8_t temp_data[MAX_DATA_SIZE]; | 993 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
401 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | ||
402 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
403 | 994 | ||
404 | new_nonce(nonce); | 995 | if (conn == 0) |
405 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); | 996 | return -1; |
406 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); | ||
407 | 997 | ||
408 | int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 998 | uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH]; |
409 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | ||
410 | 999 | ||
411 | if (len == -1) | 1000 | if (create_crypto_handshake(c, handshake_packet, cookie, conn->sent_nonce, conn->sessionpublic_key, |
412 | return 0; | 1001 | conn->public_key, dht_public_key) != sizeof(handshake_packet)) |
1002 | return -1; | ||
1003 | |||
1004 | if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0) | ||
1005 | return -1; | ||
413 | 1006 | ||
414 | temp_data[0] = 2; | 1007 | send_temp_packet(c, crypt_connection_id); |
415 | memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); | 1008 | return 0; |
416 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | ||
417 | return write_packet(c->lossless_udp, connection_id, temp_data, | ||
418 | len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | ||
419 | } | 1009 | } |
420 | 1010 | ||
421 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length. | 1011 | /* Send a kill packet. |
422 | * | 1012 | * |
423 | * return 1 if successful. | 1013 | * return -1 on failure. |
424 | * return 0 if failure. | 1014 | * return 0 on success. |
425 | */ | 1015 | */ |
426 | static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, | 1016 | static int send_kill_packet(Net_Crypto *c, int crypt_connection_id) |
427 | uint8_t *session_key, uint8_t *data, uint16_t length) | ||
428 | { | 1017 | { |
429 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); | 1018 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
430 | 1019 | ||
431 | if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES | 1020 | if (conn == 0) |
432 | + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) { | 1021 | return -1; |
433 | return 0; | 1022 | |
1023 | uint8_t kill_packet = PACKET_ID_KILL; | ||
1024 | return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, | ||
1025 | &kill_packet, sizeof(kill_packet)); | ||
1026 | } | ||
1027 | |||
1028 | /* Handle a recieved data packet. | ||
1029 | * | ||
1030 | * return -1 on failure. | ||
1031 | * return 0 on success. | ||
1032 | */ | ||
1033 | static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) | ||
1034 | { | ||
1035 | if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) | ||
1036 | return -1; | ||
1037 | |||
1038 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1039 | |||
1040 | if (conn == 0) | ||
1041 | return -1; | ||
1042 | |||
1043 | uint8_t data[MAX_DATA_DATA_PACKET_SIZE]; | ||
1044 | int len = handle_data_packet(c, crypt_connection_id, data, packet, length); | ||
1045 | |||
1046 | if (len <= (int)(sizeof(uint32_t) * 2)) | ||
1047 | return -1; | ||
1048 | |||
1049 | uint32_t buffer_start, num; | ||
1050 | memcpy(&buffer_start, data, sizeof(uint32_t)); | ||
1051 | memcpy(&num, data + sizeof(uint32_t), sizeof(uint32_t)); | ||
1052 | buffer_start = ntohl(buffer_start); | ||
1053 | num = ntohl(num); | ||
1054 | |||
1055 | if (buffer_start != conn->send_array.buffer_start && clear_buffer_until(&conn->send_array, buffer_start) != 0) | ||
1056 | return -1; | ||
1057 | |||
1058 | uint8_t *real_data = data + (sizeof(uint32_t) * 2); | ||
1059 | uint16_t real_length = len - (sizeof(uint32_t) * 2); | ||
1060 | |||
1061 | while (real_data[0] == 0) { /* Remove Padding */ | ||
1062 | ++real_data; | ||
1063 | --real_length; | ||
1064 | |||
1065 | if (real_length == 0) | ||
1066 | return -1; | ||
434 | } | 1067 | } |
435 | 1068 | ||
436 | if (data[0] != 2) | 1069 | if (real_data[0] == PACKET_ID_REQUEST) { |
1070 | int requested = handle_request_packet(&conn->send_array, real_data, real_length); | ||
1071 | |||
1072 | if (requested == -1) { | ||
1073 | return -1; | ||
1074 | } else { | ||
1075 | //TODO? | ||
1076 | } | ||
1077 | |||
1078 | set_buffer_end(&conn->recv_array, num); | ||
1079 | } else if (real_data[0] == PACKET_ID_KILL) { | ||
1080 | conn->killed = 1; | ||
437 | return 0; | 1081 | return 0; |
1082 | } else { | ||
1083 | Packet_Data dt; | ||
1084 | dt.time = current_time_monotonic(); | ||
1085 | dt.length = real_length; | ||
1086 | memcpy(dt.data, real_data, real_length); | ||
438 | 1087 | ||
439 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 1088 | if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0) |
1089 | return -1; | ||
440 | 1090 | ||
441 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); | 1091 | while (read_data_beg_buffer(&conn->recv_array, &dt) != -1) { |
1092 | if (conn->connection_data_callback) | ||
1093 | conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data, | ||
1094 | dt.length); | ||
1095 | } | ||
442 | 1096 | ||
443 | int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, | 1097 | /* Packet counter. */ |
444 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | 1098 | ++conn->packet_counter; |
445 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); | 1099 | } |
446 | 1100 | ||
447 | if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) | 1101 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { |
448 | return 0; | 1102 | if (conn->connection_status_callback) |
1103 | conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1); | ||
449 | 1104 | ||
450 | memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); | 1105 | clear_temp_packet(c, crypt_connection_id); |
451 | memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); | 1106 | conn->status = CRYPTO_CONN_ESTABLISHED; |
452 | return 1; | 1107 | } |
1108 | |||
1109 | return 0; | ||
453 | } | 1110 | } |
454 | 1111 | ||
455 | /* Get crypto connection id from public key of peer. | 1112 | /* Handle a packet that was recieved for the connection. |
456 | * | 1113 | * |
457 | * return -1 if there are no connections like we are looking for. | 1114 | * return -1 on failure. |
458 | * return id if it found it. | 1115 | * return 0 on success. |
459 | */ | 1116 | */ |
460 | static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) | 1117 | static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) |
461 | { | 1118 | { |
462 | uint32_t i; | 1119 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) |
1120 | return -1; | ||
463 | 1121 | ||
464 | for (i = 0; i < c->crypto_connections_length; ++i) { | 1122 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
465 | if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) | 1123 | |
466 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) | 1124 | if (conn == 0) |
467 | return i; | 1125 | return -1; |
1126 | |||
1127 | switch (packet[0]) { | ||
1128 | case NET_PACKET_COOKIE_RESPONSE: { | ||
1129 | if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) | ||
1130 | return -1; | ||
1131 | |||
1132 | uint8_t cookie[COOKIE_LENGTH]; | ||
1133 | uint64_t number; | ||
1134 | |||
1135 | if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) | ||
1136 | return -1; | ||
1137 | |||
1138 | if (number != conn->cookie_request_number) | ||
1139 | return -1; | ||
1140 | |||
1141 | if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) | ||
1142 | return -1; | ||
1143 | |||
1144 | conn->status = CRYPTO_CONN_HANDSHAKE_SENT; | ||
1145 | return 0; | ||
1146 | } | ||
1147 | |||
1148 | case NET_PACKET_CRYPTO_HS: { | ||
1149 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT) { | ||
1150 | uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES]; | ||
1151 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; | ||
1152 | uint8_t cookie[COOKIE_LENGTH]; | ||
1153 | |||
1154 | if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, | ||
1155 | packet, length, conn->public_key) != 0) | ||
1156 | return -1; | ||
1157 | |||
1158 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | ||
1159 | |||
1160 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { | ||
1161 | if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) | ||
1162 | return -1; | ||
1163 | } | ||
1164 | |||
1165 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | ||
1166 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | ||
1167 | set_connection_dht_public_key(c, crypt_connection_id, dht_public_key, current_time_monotonic()); | ||
1168 | } else { | ||
1169 | return -1; | ||
1170 | } | ||
1171 | |||
1172 | return 0; | ||
1173 | } | ||
1174 | |||
1175 | case NET_PACKET_CRYPTO_DATA: { | ||
1176 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) { | ||
1177 | return handle_data_packet_helper(c, crypt_connection_id, packet, length); | ||
1178 | } else { | ||
1179 | return -1; | ||
1180 | } | ||
1181 | |||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1185 | default: { | ||
1186 | return -1; | ||
1187 | } | ||
468 | } | 1188 | } |
469 | 1189 | ||
470 | return -1; | 1190 | return 0; |
471 | } | 1191 | } |
472 | 1192 | ||
473 | /* Set the size of the friend list to numfriends. | 1193 | /* Set the size of the friend list to numfriends. |
@@ -492,326 +1212,1100 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) | |||
492 | return 0; | 1212 | return 0; |
493 | } | 1213 | } |
494 | 1214 | ||
495 | /* Start a secure connection with other peer who has public_key and ip_port. | 1215 | |
1216 | /* Create a new empty crypto connection. | ||
496 | * | 1217 | * |
497 | * return -1 if failure. | 1218 | * return -1 on failure. |
498 | * return crypt_connection_id of the initialized connection if everything went well. | 1219 | * return connection id on success. |
499 | */ | 1220 | */ |
500 | int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) | 1221 | static int create_crypto_connection(Net_Crypto *c) |
501 | { | 1222 | { |
502 | uint32_t i; | 1223 | uint32_t i; |
503 | int id_existing = getcryptconnection_id(c, public_key); | ||
504 | 1224 | ||
505 | if (id_existing != -1) { | 1225 | for (i = 0; i < c->crypto_connections_length; ++i) { |
506 | IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id_existing].number); | 1226 | if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) |
507 | 1227 | return i; | |
508 | if (ipport_equal(&c_ip, &ip_port)) | ||
509 | return -1; | ||
510 | } | 1228 | } |
511 | 1229 | ||
512 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 | 1230 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) |
513 | || c->crypto_connections == NULL) | ||
514 | return -1; | 1231 | return -1; |
515 | 1232 | ||
516 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); | 1233 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); |
517 | c->crypto_connections[c->crypto_connections_length].number = ~0; | 1234 | int id = c->crypto_connections_length; |
1235 | ++c->crypto_connections_length; | ||
1236 | return id; | ||
1237 | } | ||
518 | 1238 | ||
519 | for (i = 0; i <= c->crypto_connections_length; ++i) { | 1239 | /* Wipe a crypto connection. |
520 | if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { | 1240 | * |
521 | int id_new = new_connection(c->lossless_udp, ip_port); | 1241 | * return -1 on failure. |
1242 | * return 0 on success. | ||
1243 | */ | ||
1244 | static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) | ||
1245 | { | ||
1246 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) | ||
1247 | return -1; | ||
522 | 1248 | ||
523 | if (id_new == -1) | 1249 | uint32_t i; |
524 | return -1; | 1250 | memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); |
525 | 1251 | ||
526 | c->crypto_connections[i].number = id_new; | 1252 | for (i = c->crypto_connections_length; i != 0; --i) { |
527 | c->crypto_connections[i].status = CRYPTO_CONN_HANDSHAKE_SENT; | 1253 | if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION) |
528 | random_nonce(c->crypto_connections[i].recv_nonce); | 1254 | break; |
529 | memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 1255 | } |
530 | crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); | ||
531 | c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT; | ||
532 | 1256 | ||
533 | if (c->crypto_connections_length == i) | 1257 | if (c->crypto_connections_length != i) { |
534 | ++c->crypto_connections_length; | 1258 | c->crypto_connections_length = i; |
1259 | realloc_cryptoconnection(c, c->crypto_connections_length); | ||
1260 | } | ||
535 | 1261 | ||
536 | if (send_cryptohandshake(c, id_new, public_key, c->crypto_connections[i].recv_nonce, | 1262 | return 0; |
537 | c->crypto_connections[i].sessionpublic_key) == 1) { | 1263 | } |
538 | increment_nonce(c->crypto_connections[i].recv_nonce); | 1264 | |
1265 | /* Get crypto connection id from public key of peer. | ||
1266 | * | ||
1267 | * return -1 if there are no connections like we are looking for. | ||
1268 | * return id if it found it. | ||
1269 | */ | ||
1270 | static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) | ||
1271 | { | ||
1272 | uint32_t i; | ||
1273 | |||
1274 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
1275 | if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION) | ||
1276 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
539 | return i; | 1277 | return i; |
540 | } | 1278 | } |
541 | 1279 | ||
542 | return -1; /* This should never happen. */ | 1280 | return -1; |
543 | } | 1281 | } |
1282 | |||
1283 | /* Get crypto connection id from public key of peer. | ||
1284 | * | ||
1285 | * return -1 if there are no connections like we are looking for. | ||
1286 | * return id if it found it. | ||
1287 | */ | ||
1288 | static int getcryptconnection_id_dht_pubkey(Net_Crypto *c, uint8_t *dht_public_key) | ||
1289 | { | ||
1290 | uint32_t i; | ||
1291 | |||
1292 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
1293 | if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set) | ||
1294 | if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1295 | return i; | ||
544 | } | 1296 | } |
545 | 1297 | ||
546 | return -1; | 1298 | return -1; |
547 | } | 1299 | } |
548 | 1300 | ||
549 | /* Handle an incoming connection. | 1301 | /* Add a source to the crypto connection. |
1302 | * This is to be used only when we have recieved a packet from that source. | ||
550 | * | 1303 | * |
551 | * return -1 if no crypto inbound connection. | 1304 | * return -1 on failure. |
552 | * return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection. | 1305 | * return positive number on success. |
1306 | * 0 if source was a direct UDP connection. | ||
1307 | * TODO | ||
1308 | */ | ||
1309 | static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source) | ||
1310 | { | ||
1311 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1312 | |||
1313 | if (conn == 0) | ||
1314 | return -1; | ||
1315 | |||
1316 | if (source.ip.family == AF_INET || source.ip.family == AF_INET6) { | ||
1317 | conn->ip_port = source; | ||
1318 | conn->direct_lastrecv_time = current_time_monotonic(); | ||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | return -1; | ||
1323 | } | ||
1324 | |||
1325 | |||
1326 | /* Set function to be called when someone requests a new connection to us. | ||
553 | * | 1327 | * |
554 | * Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce | 1328 | * The set function should return -1 on failure and 0 on success. |
555 | * and the session public key for the connection in session_key. | 1329 | * |
556 | * to accept it see: accept_crypto_inbound(...). | 1330 | * n_c is only valid for the duration of the function call. |
557 | * to refuse it just call kill_connection(...) on the connection id. | ||
558 | */ | 1331 | */ |
559 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 1332 | void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c), |
1333 | void *object) | ||
560 | { | 1334 | { |
561 | while (1) { | 1335 | c->new_connection_callback = new_connection_callback; |
562 | int incoming_con = incoming_connection(c->lossless_udp, 1); | 1336 | c->new_connection_callback_object = object; |
1337 | } | ||
563 | 1338 | ||
564 | if (incoming_con != -1) { | 1339 | /* Handle a handshake packet by someone who wants to initiate a new connection with us. |
565 | if (is_connected(c->lossless_udp, incoming_con) == LUDP_TIMED_OUT) { | 1340 | * This calls the callback set by new_connection_handler() if the handshake is ok. |
566 | kill_connection(c->lossless_udp, incoming_con); | 1341 | * |
567 | continue; | 1342 | * return -1 on failure. |
568 | } | 1343 | * return 0 on success. |
1344 | */ | ||
1345 | static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, uint8_t *data, uint16_t length) | ||
1346 | { | ||
1347 | New_Connection n_c; | ||
1348 | n_c.cookie = malloc(COOKIE_LENGTH); | ||
569 | 1349 | ||
570 | if (id_packet(c->lossless_udp, incoming_con) == 2) { | 1350 | if (n_c.cookie == NULL) |
571 | uint8_t temp_data[MAX_DATA_SIZE]; | 1351 | return -1; |
572 | uint16_t len = read_packet_silent(c->lossless_udp, incoming_con, temp_data); | ||
573 | 1352 | ||
574 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { | 1353 | n_c.source = source; |
575 | return incoming_con; | 1354 | n_c.cookie_length = COOKIE_LENGTH; |
576 | } else { | 1355 | |
577 | kill_connection(c->lossless_udp, incoming_con); | 1356 | if (handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, |
578 | } | 1357 | n_c.cookie, data, length, 0) != 0) { |
579 | } else { | 1358 | free(n_c.cookie); |
580 | kill_connection(c->lossless_udp, incoming_con); | 1359 | return -1; |
1360 | } | ||
1361 | |||
1362 | int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); | ||
1363 | |||
1364 | if (crypt_connection_id != -1) { | ||
1365 | int ret = -1; | ||
1366 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1367 | |||
1368 | if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { | ||
1369 | memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES); | ||
1370 | memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES); | ||
1371 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | ||
1372 | |||
1373 | crypto_connection_add_source(c, crypt_connection_id, source); | ||
1374 | |||
1375 | if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { | ||
1376 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | ||
1377 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | ||
1378 | set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key, current_time_monotonic()); | ||
1379 | ret = 0; | ||
581 | } | 1380 | } |
582 | } else { | ||
583 | break; | ||
584 | } | 1381 | } |
1382 | |||
1383 | free(n_c.cookie); | ||
1384 | return ret; | ||
585 | } | 1385 | } |
586 | 1386 | ||
587 | return -1; | 1387 | int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); |
1388 | free(n_c.cookie); | ||
1389 | return ret; | ||
588 | } | 1390 | } |
589 | 1391 | ||
590 | /* Kill a crypto connection. | 1392 | /* Accept a crypto connection. |
591 | * | 1393 | * |
592 | * return 0 if killed successfully. | 1394 | * return -1 on failure. |
593 | * return 1 if there was a problem. | 1395 | * return connection id on success. |
594 | */ | 1396 | */ |
595 | int crypto_kill(Net_Crypto *c, int crypt_connection_id) | 1397 | int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) |
596 | { | 1398 | { |
597 | if (crypt_connection_id_not_valid(c, crypt_connection_id)) | 1399 | if (getcryptconnection_id(c, n_c->public_key) != -1) |
598 | return 1; | 1400 | return -1; |
1401 | |||
1402 | int crypt_connection_id = create_crypto_connection(c); | ||
1403 | |||
1404 | if (crypt_connection_id == -1) | ||
1405 | return -1; | ||
599 | 1406 | ||
600 | if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_NO_CONNECTION) { | 1407 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
601 | c->crypto_connections[crypt_connection_id].status = CRYPTO_CONN_NO_CONNECTION; | ||
602 | kill_connection(c->lossless_udp, c->crypto_connections[crypt_connection_id].number); | ||
603 | memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); | ||
604 | c->crypto_connections[crypt_connection_id].number = ~0; | ||
605 | uint32_t i; | ||
606 | 1408 | ||
607 | for (i = c->crypto_connections_length; i != 0; --i) { | 1409 | if (conn == 0) |
608 | if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION) | 1410 | return -1; |
609 | break; | 1411 | |
1412 | memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); | ||
1413 | memcpy(conn->recv_nonce, n_c->recv_nonce, crypto_box_NONCEBYTES); | ||
1414 | memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, crypto_box_PUBLICKEYBYTES); | ||
1415 | random_nonce(conn->sent_nonce); | ||
1416 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); | ||
1417 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | ||
1418 | |||
1419 | if (n_c->cookie_length != COOKIE_LENGTH) | ||
1420 | return -1; | ||
1421 | |||
1422 | if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) | ||
1423 | return -1; | ||
1424 | |||
1425 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | ||
1426 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | ||
1427 | set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic()); | ||
1428 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | ||
1429 | crypto_connection_add_source(c, crypt_connection_id, n_c->source); | ||
1430 | return crypt_connection_id; | ||
1431 | } | ||
1432 | |||
1433 | /* Create a crypto connection. | ||
1434 | * If one to that real public key already exists, return it. | ||
1435 | * | ||
1436 | * return -1 on failure. | ||
1437 | * return connection id on success. | ||
1438 | */ | ||
1439 | int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key) | ||
1440 | { | ||
1441 | int crypt_connection_id = getcryptconnection_id(c, real_public_key); | ||
1442 | |||
1443 | if (crypt_connection_id != -1) | ||
1444 | return crypt_connection_id; | ||
1445 | |||
1446 | crypt_connection_id = create_crypto_connection(c); | ||
1447 | |||
1448 | if (crypt_connection_id == -1) | ||
1449 | return -1; | ||
1450 | |||
1451 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1452 | |||
1453 | if (conn == 0) | ||
1454 | return -1; | ||
1455 | |||
1456 | memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); | ||
1457 | random_nonce(conn->sent_nonce); | ||
1458 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); | ||
1459 | conn->status = CRYPTO_CONN_COOKIE_REQUESTING; | ||
1460 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | ||
1461 | return crypt_connection_id; | ||
1462 | } | ||
1463 | |||
1464 | /* Disconnect peer from all associated TCP connections. | ||
1465 | * | ||
1466 | * return -1 on failure. | ||
1467 | * return 0 on success. | ||
1468 | */ | ||
1469 | static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | ||
1470 | { | ||
1471 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1472 | |||
1473 | if (conn == 0) | ||
1474 | return -1; | ||
1475 | |||
1476 | uint32_t i; | ||
1477 | |||
1478 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1479 | if (conn->status_tcp[i] != STATUS_TCP_NULL) { | ||
1480 | send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]); | ||
1481 | conn->status_tcp[i] = STATUS_TCP_NULL; | ||
1482 | conn->con_number_tcp[i] = 0; | ||
610 | } | 1483 | } |
1484 | } | ||
611 | 1485 | ||
612 | if (c->crypto_connections_length != i) { | 1486 | return 0; |
613 | c->crypto_connections_length = i; | 1487 | } |
614 | realloc_cryptoconnection(c, c->crypto_connections_length); | 1488 | |
1489 | /* Connect peer to all associated TCP connections. | ||
1490 | * | ||
1491 | * return -1 on failure. | ||
1492 | * return 0 on success. | ||
1493 | */ | ||
1494 | static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | ||
1495 | { | ||
1496 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1497 | |||
1498 | if (conn == 0) | ||
1499 | return -1; | ||
1500 | |||
1501 | uint32_t i; | ||
1502 | |||
1503 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1504 | if (c->tcp_connections[i] == NULL) | ||
1505 | continue; | ||
1506 | |||
1507 | //TODO check function return? | ||
1508 | send_routing_request(c->tcp_connections[i], conn->dht_public_key); | ||
1509 | } | ||
1510 | |||
1511 | return 0; | ||
1512 | } | ||
1513 | |||
1514 | /* Copy friends DHT public key into dht_key. | ||
1515 | * | ||
1516 | * return 0 on failure (no key copied). | ||
1517 | * return timestamp on success (key copied). | ||
1518 | */ | ||
1519 | uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key) | ||
1520 | { | ||
1521 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1522 | |||
1523 | if (conn == 0) | ||
1524 | return 0; | ||
1525 | |||
1526 | if (conn->dht_public_key_set == 0) | ||
1527 | return 0; | ||
1528 | |||
1529 | memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES); | ||
1530 | return conn->dht_public_key_timestamp; | ||
1531 | } | ||
1532 | |||
1533 | |||
1534 | /* Set the DHT public key of the crypto connection. | ||
1535 | * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to | ||
1536 | * the other peer. | ||
1537 | * | ||
1538 | * return -1 on failure. | ||
1539 | * return 0 on success. | ||
1540 | */ | ||
1541 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp) | ||
1542 | { | ||
1543 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1544 | |||
1545 | if (conn == 0) | ||
1546 | return -1; | ||
1547 | |||
1548 | if (timestamp <= conn->dht_public_key_timestamp) | ||
1549 | return -1; | ||
1550 | |||
1551 | if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1552 | return -1; | ||
1553 | |||
1554 | if (conn->dht_public_key_set == 1) { | ||
1555 | disconnect_peer_tcp(c, crypt_connection_id); | ||
1556 | } | ||
1557 | |||
1558 | memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); | ||
1559 | conn->dht_public_key_set = 1; | ||
1560 | conn->dht_public_key_timestamp = timestamp; | ||
1561 | |||
1562 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { | ||
1563 | conn->cookie_request_number = random_64b(); | ||
1564 | uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; | ||
1565 | |||
1566 | if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, | ||
1567 | conn->shared_key) != sizeof(cookie_request)) | ||
1568 | return -1; | ||
1569 | |||
1570 | if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) | ||
1571 | return -1; | ||
1572 | }//TODO | ||
1573 | |||
1574 | connect_peer_tcp(c, crypt_connection_id); | ||
1575 | return 0; | ||
1576 | } | ||
1577 | |||
1578 | /* Set the direct ip of the crypto connection. | ||
1579 | * | ||
1580 | * return -1 on failure. | ||
1581 | * return 0 on success. | ||
1582 | */ | ||
1583 | int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port) | ||
1584 | { | ||
1585 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1586 | |||
1587 | if (conn == 0) | ||
1588 | return -1; | ||
1589 | |||
1590 | if (!ipport_equal(&ip_port, &conn->ip_port)) { | ||
1591 | conn->ip_port = ip_port; | ||
1592 | conn->direct_lastrecv_time = 0; | ||
1593 | return 0; | ||
1594 | } | ||
1595 | |||
1596 | return -1; | ||
1597 | } | ||
1598 | |||
1599 | static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key) | ||
1600 | { | ||
1601 | TCP_Client_Connection *TCP_con = object; | ||
1602 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1603 | |||
1604 | int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key); | ||
1605 | |||
1606 | if (crypt_connection_id == -1) | ||
1607 | return -1; | ||
1608 | |||
1609 | set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id); | ||
1610 | |||
1611 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1612 | |||
1613 | if (conn == 0) | ||
1614 | return -1; | ||
1615 | |||
1616 | uint32_t location = TCP_con->net_crypto_location; | ||
1617 | |||
1618 | if (location >= MAX_TCP_CONNECTIONS) | ||
1619 | return -1; | ||
1620 | |||
1621 | if (c->tcp_connections[location] != TCP_con) | ||
1622 | return -1; | ||
1623 | |||
1624 | conn->con_number_tcp[location] = connection_id; | ||
1625 | uint32_t i; | ||
1626 | |||
1627 | for (i = 0; i < conn->num_tcp_relays; ++i) { | ||
1628 | if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { | ||
1629 | conn->status_tcp[location] = STATUS_TCP_INVISIBLE; | ||
1630 | return 0; | ||
1631 | } | ||
1632 | } | ||
1633 | |||
1634 | conn->status_tcp[location] = STATUS_TCP_OFFLINE; | ||
1635 | return 0; | ||
1636 | } | ||
1637 | |||
1638 | static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) | ||
1639 | { | ||
1640 | TCP_Client_Connection *TCP_con = object; | ||
1641 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1642 | |||
1643 | Crypto_Connection *conn = get_crypto_connection(c, number); | ||
1644 | |||
1645 | if (conn == 0) | ||
1646 | return -1; | ||
1647 | |||
1648 | uint32_t location = TCP_con->net_crypto_location; | ||
1649 | |||
1650 | if (location >= MAX_TCP_CONNECTIONS) | ||
1651 | return -1; | ||
1652 | |||
1653 | if (c->tcp_connections[location] != TCP_con) | ||
1654 | return -1; | ||
1655 | |||
1656 | if (status == 1) { | ||
1657 | conn->status_tcp[location] = STATUS_TCP_OFFLINE; | ||
1658 | } else if (status == 2) { | ||
1659 | conn->status_tcp[location] = STATUS_TCP_ONLINE; | ||
1660 | } | ||
1661 | |||
1662 | conn->con_number_tcp[location] = connection_id; | ||
1663 | return 0; | ||
1664 | } | ||
1665 | |||
1666 | static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) | ||
1667 | { | ||
1668 | |||
1669 | if (length == 0) | ||
1670 | return -1; | ||
1671 | |||
1672 | TCP_Client_Connection *TCP_con = object; | ||
1673 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1674 | |||
1675 | if (data[0] == NET_PACKET_COOKIE_REQUEST) { | ||
1676 | return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length); | ||
1677 | } | ||
1678 | |||
1679 | Crypto_Connection *conn = get_crypto_connection(c, number); | ||
1680 | |||
1681 | if (conn == 0) | ||
1682 | return -1; | ||
1683 | |||
1684 | if (handle_packet_connection(c, number, data, length) != 0) | ||
1685 | return -1; | ||
1686 | |||
1687 | //TODO detect and kill bad TCP connections. | ||
1688 | return 0; | ||
1689 | } | ||
1690 | |||
1691 | static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length) | ||
1692 | { | ||
1693 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) | ||
1694 | return -1; | ||
1695 | |||
1696 | TCP_Client_Connection *TCP_con = object; | ||
1697 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1698 | uint32_t location = TCP_con->net_crypto_location; | ||
1699 | |||
1700 | if (data[0] == NET_PACKET_COOKIE_REQUEST) { | ||
1701 | return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length); | ||
1702 | } | ||
1703 | |||
1704 | int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key); | ||
1705 | |||
1706 | if (crypt_connection_id == -1) { | ||
1707 | IP_Port source; | ||
1708 | source.ip.family = TCP_FAMILY; | ||
1709 | source.ip.ip6.uint32[0] = location; | ||
1710 | |||
1711 | if (data[0] != NET_PACKET_CRYPTO_HS) { | ||
1712 | fprintf(stderr, "tcp snhappen %u\n", data[0]); | ||
1713 | return -1; | ||
615 | } | 1714 | } |
616 | 1715 | ||
1716 | if (handle_new_connection_handshake(c, source, data, length) != 0) | ||
1717 | return -1; | ||
1718 | |||
617 | return 0; | 1719 | return 0; |
618 | } | 1720 | } |
619 | 1721 | ||
620 | return 1; | 1722 | if (handle_packet_connection(c, crypt_connection_id, data, length) != 0) |
1723 | return -1; | ||
1724 | |||
1725 | return 0; | ||
621 | } | 1726 | } |
622 | 1727 | ||
623 | /* Accept an incoming connection using the parameters provided by crypto_inbound. | 1728 | /* Check if tcp connection to public key can be created. |
624 | * | 1729 | * |
625 | * return -1 if not successful. | 1730 | * return -1 if it can't. |
626 | * return the crypt_connection_id if successful. | 1731 | * return 0 if it can. |
627 | */ | 1732 | */ |
628 | int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, | 1733 | static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key) |
629 | uint8_t *session_key) | ||
630 | { | 1734 | { |
631 | uint32_t i; | 1735 | uint32_t i; |
632 | 1736 | ||
633 | if (discard_packet(c->lossless_udp, connection_id) == -1) | 1737 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
1738 | if (c->tcp_connections_new[i] == NULL) | ||
1739 | continue; | ||
1740 | |||
1741 | if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1742 | return -1; | ||
1743 | } | ||
1744 | |||
1745 | uint32_t num = 0; | ||
1746 | |||
1747 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1748 | if (c->tcp_connections[i] == NULL) | ||
1749 | continue; | ||
1750 | |||
1751 | if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1752 | return -1; | ||
1753 | |||
1754 | ++num; | ||
1755 | } | ||
1756 | |||
1757 | if (num == MAX_TCP_CONNECTIONS) | ||
634 | return -1; | 1758 | return -1; |
635 | 1759 | ||
636 | /* | 1760 | return 0; |
637 | * if(getcryptconnection_id(public_key) != -1) | 1761 | } |
638 | * { | ||
639 | * return -1; | ||
640 | * } | ||
641 | */ | ||
642 | 1762 | ||
643 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 | 1763 | /* Add a tcp relay, associating it to a crypt_connection_id. |
644 | || c->crypto_connections == NULL) | 1764 | * |
1765 | * return 0 if it was added. | ||
1766 | * return -1 if it wasn't. | ||
1767 | */ | ||
1768 | int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key) | ||
1769 | { | ||
1770 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1771 | |||
1772 | if (conn == 0) | ||
645 | return -1; | 1773 | return -1; |
646 | 1774 | ||
647 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); | 1775 | if (ip_port.ip.family == TCP_INET) { |
648 | c->crypto_connections[c->crypto_connections_length].number = ~0; | 1776 | ip_port.ip.family = AF_INET; |
649 | 1777 | } else if (ip_port.ip.family == TCP_INET6) { | |
650 | for (i = 0; i <= c->crypto_connections_length; ++i) { | 1778 | ip_port.ip.family = AF_INET6; |
651 | if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) { | 1779 | } |
652 | c->crypto_connections[i].number = connection_id; | 1780 | |
653 | c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; | 1781 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) |
654 | c->crypto_connections[i].timeout = unix_time() + CRYPTO_HANDSHAKE_TIMEOUT; | 1782 | return -1; |
655 | random_nonce(c->crypto_connections[i].recv_nonce); | 1783 | |
656 | memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 1784 | uint32_t i; |
657 | memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 1785 | |
658 | increment_nonce(c->crypto_connections[i].sent_nonce); | 1786 | for (i = 0; i < conn->num_tcp_relays; ++i) { |
659 | memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 1787 | if (memcmp(conn->tcp_relays[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
660 | 1788 | conn->tcp_relays[i].ip_port = ip_port; | |
661 | crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); | 1789 | return 0; |
662 | 1790 | } | |
663 | if (c->crypto_connections_length == i) | 1791 | } |
664 | ++c->crypto_connections_length; | ||
665 | |||
666 | if (send_cryptohandshake(c, connection_id, public_key, c->crypto_connections[i].recv_nonce, | ||
667 | c->crypto_connections[i].sessionpublic_key) == 1) { | ||
668 | increment_nonce(c->crypto_connections[i].recv_nonce); | ||
669 | uint32_t zero = 0; | ||
670 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, | ||
671 | c->crypto_connections[i].sessionsecret_key, | ||
672 | c->crypto_connections[i].shared_key); | ||
673 | c->crypto_connections[i].status = | ||
674 | CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */ | ||
675 | write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); | ||
676 | c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */ | ||
677 | return i; | ||
678 | } | ||
679 | 1792 | ||
680 | return -1; /* This should never happen. */ | 1793 | if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) { |
1794 | uint16_t index = rand() % MAX_TCP_RELAYS_PEER; | ||
1795 | conn->tcp_relays[index].ip_port = ip_port; | ||
1796 | memcpy(conn->tcp_relays[index].client_id, public_key, crypto_box_PUBLICKEYBYTES); | ||
1797 | } else { | ||
1798 | conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port; | ||
1799 | memcpy(conn->tcp_relays[conn->num_tcp_relays].client_id, public_key, crypto_box_PUBLICKEYBYTES); | ||
1800 | ++conn->num_tcp_relays; | ||
1801 | } | ||
1802 | |||
1803 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1804 | if (c->tcp_connections[i] == NULL) | ||
1805 | continue; | ||
1806 | |||
1807 | if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
1808 | if (conn->status_tcp[i] == STATUS_TCP_OFFLINE) | ||
1809 | conn->status_tcp[i] = STATUS_TCP_INVISIBLE; | ||
1810 | } | ||
1811 | } | ||
1812 | |||
1813 | return add_tcp_relay(c, ip_port, public_key); | ||
1814 | } | ||
1815 | |||
1816 | /* Add a tcp relay to the array. | ||
1817 | * | ||
1818 | * return 0 if it was added. | ||
1819 | * return -1 if it wasn't. | ||
1820 | */ | ||
1821 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key) | ||
1822 | { | ||
1823 | if (ip_port.ip.family == TCP_INET) { | ||
1824 | ip_port.ip.family = AF_INET; | ||
1825 | } else if (ip_port.ip.family == TCP_INET6) { | ||
1826 | ip_port.ip.family = AF_INET6; | ||
1827 | } | ||
1828 | |||
1829 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | ||
1830 | return -1; | ||
1831 | |||
1832 | if (tcp_connection_check(c, public_key) != 0) | ||
1833 | return -1; | ||
1834 | |||
1835 | uint32_t i; | ||
1836 | |||
1837 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1838 | if (c->tcp_connections_new[i] == NULL) { | ||
1839 | c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key); | ||
1840 | return 0; | ||
681 | } | 1841 | } |
682 | } | 1842 | } |
683 | 1843 | ||
684 | return -1; | 1844 | return -1; |
685 | } | 1845 | } |
686 | 1846 | ||
687 | /* return 0 if no connection. | 1847 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. |
688 | * return 1 we have sent a handshake. | 1848 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. |
689 | * return 2 if connection is not confirmed yet (we have received a handshake but no empty data packet). | 1849 | * |
690 | * return 3 if the connection is established. | 1850 | * return number of relays copied to tcp_relays on success. |
691 | * return 4 if the connection is timed out and waiting to be killed. | 1851 | * return 0 on failure. |
692 | */ | 1852 | */ |
693 | int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id) | 1853 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num) |
694 | { | 1854 | { |
695 | if ((unsigned int)crypt_connection_id < c->crypto_connections_length) | 1855 | if (num == 0) |
696 | return c->crypto_connections[crypt_connection_id].status; | 1856 | return 0; |
1857 | |||
1858 | uint32_t i; | ||
1859 | uint16_t copied = 0; | ||
1860 | |||
1861 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1862 | if (c->tcp_connections[i] != NULL) { | ||
1863 | memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES); | ||
1864 | tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port; | ||
1865 | |||
1866 | if (tcp_relays[copied].ip_port.ip.family == AF_INET) { | ||
1867 | tcp_relays[copied].ip_port.ip.family = TCP_INET; | ||
1868 | } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) { | ||
1869 | tcp_relays[copied].ip_port.ip.family = TCP_INET6; | ||
1870 | } | ||
1871 | |||
1872 | ++copied; | ||
1873 | |||
1874 | if (copied == num) | ||
1875 | return copied; | ||
1876 | } | ||
1877 | } | ||
697 | 1878 | ||
698 | return CRYPTO_CONN_NO_CONNECTION; | 1879 | return copied; |
699 | } | 1880 | } |
700 | 1881 | ||
701 | void new_keys(Net_Crypto *c) | 1882 | /* Add a connected tcp connection to the tcp_connections array. |
1883 | * | ||
1884 | * return 0 if it was added. | ||
1885 | * return -1 if it wasn't. | ||
1886 | */ | ||
1887 | static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con) | ||
702 | { | 1888 | { |
703 | crypto_box_keypair(c->self_public_key, c->self_secret_key); | 1889 | uint32_t i; |
1890 | |||
1891 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1892 | if (c->tcp_connections[i] == NULL) | ||
1893 | break; | ||
1894 | } | ||
1895 | |||
1896 | if (i == MAX_TCP_CONNECTIONS) | ||
1897 | return -1; | ||
1898 | |||
1899 | uint32_t tcp_num = i; | ||
1900 | |||
1901 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
1902 | Crypto_Connection *conn = get_crypto_connection(c, i); | ||
1903 | |||
1904 | if (conn == 0) | ||
1905 | return -1; | ||
1906 | |||
1907 | if (conn->status == CRYPTO_CONN_NO_CONNECTION) | ||
1908 | continue; | ||
1909 | |||
1910 | if (conn->status == CRYPTO_CONN_TIMED_OUT) | ||
1911 | continue; | ||
1912 | |||
1913 | if (conn->dht_public_key_set) | ||
1914 | if (send_routing_request(tcp_con, conn->dht_public_key) != 1) | ||
1915 | return -1; | ||
1916 | |||
1917 | } | ||
1918 | |||
1919 | tcp_con->net_crypto_pointer = c; | ||
1920 | tcp_con->net_crypto_location = tcp_num; | ||
1921 | routing_response_handler(tcp_con, tcp_response_callback, tcp_con); | ||
1922 | routing_status_handler(tcp_con, tcp_status_callback, tcp_con); | ||
1923 | routing_data_handler(tcp_con, tcp_data_callback, tcp_con); | ||
1924 | oob_data_handler(tcp_con, tcp_oob_callback, tcp_con); | ||
1925 | c->tcp_connections[tcp_num] = tcp_con; | ||
1926 | return 0; | ||
704 | } | 1927 | } |
705 | 1928 | ||
706 | /* Save the public and private keys to the keys array. | 1929 | static void do_tcp(Net_Crypto *c) |
707 | * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. | 1930 | { |
1931 | uint32_t i; | ||
1932 | |||
1933 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1934 | if (c->tcp_connections_new[i] == NULL) | ||
1935 | continue; | ||
1936 | |||
1937 | do_TCP_connection(c->tcp_connections_new[i]); | ||
1938 | |||
1939 | if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) { | ||
1940 | if (add_tcp_connected(c, c->tcp_connections_new[i]) == 0) { | ||
1941 | c->tcp_connections_new[i] = NULL; | ||
1942 | } else { | ||
1943 | kill_TCP_connection(c->tcp_connections_new[i]); | ||
1944 | c->tcp_connections_new[i] = NULL; | ||
1945 | } | ||
1946 | } | ||
1947 | } | ||
1948 | |||
1949 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1950 | if (c->tcp_connections[i] == NULL) | ||
1951 | continue; | ||
1952 | |||
1953 | do_TCP_connection(c->tcp_connections[i]); | ||
1954 | } | ||
1955 | } | ||
1956 | |||
1957 | static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number) | ||
1958 | { | ||
1959 | if (conn->status == CRYPTO_CONN_NO_CONNECTION) | ||
1960 | return; | ||
1961 | |||
1962 | if (number >= MAX_TCP_CONNECTIONS) | ||
1963 | return; | ||
1964 | |||
1965 | conn->status_tcp[number] = STATUS_TCP_NULL; | ||
1966 | conn->con_number_tcp[number] = 0; | ||
1967 | } | ||
1968 | |||
1969 | static void clear_disconnected_tcp(Net_Crypto *c) | ||
1970 | { | ||
1971 | uint32_t i, j; | ||
1972 | |||
1973 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1974 | if (c->tcp_connections_new[i] == NULL) | ||
1975 | continue; | ||
1976 | |||
1977 | if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED) | ||
1978 | continue; | ||
1979 | |||
1980 | kill_TCP_connection(c->tcp_connections_new[i]); | ||
1981 | c->tcp_connections_new[i] = NULL; | ||
1982 | } | ||
1983 | |||
1984 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1985 | if (c->tcp_connections[i] == NULL) | ||
1986 | continue; | ||
1987 | |||
1988 | TCP_Client_Connection *tcp_con = c->tcp_connections[i]; | ||
1989 | |||
1990 | if (tcp_con->status != TCP_CLIENT_DISCONNECTED) | ||
1991 | continue; | ||
1992 | |||
1993 | c->tcp_connections[i] = NULL; | ||
1994 | kill_TCP_connection(tcp_con); | ||
1995 | |||
1996 | for (j = 0; j < c->crypto_connections_length; ++j) { | ||
1997 | Crypto_Connection *conn = get_crypto_connection(c, j); | ||
1998 | |||
1999 | if (conn == 0) | ||
2000 | return; | ||
2001 | |||
2002 | clear_disconnected_tcp_peer(conn, i); | ||
2003 | } | ||
2004 | } | ||
2005 | } | ||
2006 | |||
2007 | /* Set function to be called when connection with crypt_connection_id goes connects/disconnects. | ||
2008 | * | ||
2009 | * The set function should return -1 on failure and 0 on success. | ||
2010 | * Note that if this function is set, the connection will clear itself on disconnect. | ||
2011 | * Object and id will be passed to this function untouched. | ||
2012 | * status is 1 if the connection is going online, 0 if it is going offline. | ||
2013 | * | ||
2014 | * return -1 on failure. | ||
2015 | * return 0 on success. | ||
708 | */ | 2016 | */ |
709 | void save_keys(Net_Crypto *c, uint8_t *keys) | 2017 | int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object, |
2018 | int id, uint8_t status), void *object, int id) | ||
710 | { | 2019 | { |
711 | memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES); | 2020 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
712 | memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); | 2021 | |
2022 | if (conn == 0) | ||
2023 | return -1; | ||
2024 | |||
2025 | conn->connection_status_callback = connection_status_callback; | ||
2026 | conn->connection_status_callback_object = object; | ||
2027 | conn->connection_status_callback_id = id; | ||
2028 | return 0; | ||
713 | } | 2029 | } |
714 | 2030 | ||
715 | /* Load the public and private keys from the keys array. | 2031 | /* Set function to be called when connection with crypt_connection_id receives a data packet of length. |
716 | * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. | 2032 | * |
2033 | * The set function should return -1 on failure and 0 on success. | ||
2034 | * Object and id will be passed to this function untouched. | ||
2035 | * | ||
2036 | * return -1 on failure. | ||
2037 | * return 0 on success. | ||
717 | */ | 2038 | */ |
718 | void load_keys(Net_Crypto *c, uint8_t *keys) | 2039 | int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, |
2040 | int id, uint8_t *data, uint16_t length), void *object, int id) | ||
719 | { | 2041 | { |
720 | memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES); | 2042 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
721 | memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); | 2043 | |
2044 | if (conn == 0) | ||
2045 | return -1; | ||
2046 | |||
2047 | conn->connection_data_callback = connection_data_callback; | ||
2048 | conn->connection_data_callback_object = object; | ||
2049 | conn->connection_data_callback_id = id; | ||
2050 | return 0; | ||
722 | } | 2051 | } |
723 | 2052 | ||
724 | /* Handle received packets for not yet established crypto connections. */ | 2053 | /* Get the crypto connection id from the ip_port. |
725 | static void receive_crypto(Net_Crypto *c) | 2054 | * |
2055 | * return -1 on failure. | ||
2056 | * return connection id on success. | ||
2057 | */ | ||
2058 | static int crypto_id_ip_port(Net_Crypto *c, IP_Port ip_port) | ||
726 | { | 2059 | { |
727 | uint32_t i; | 2060 | uint32_t i; |
728 | uint64_t temp_time = unix_time(); | ||
729 | 2061 | ||
730 | for (i = 0; i < c->crypto_connections_length; ++i) { | 2062 | for (i = 0; i < c->crypto_connections_length; ++i) { |
731 | if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION) | 2063 | if (is_alive(c->crypto_connections[i].status)) |
732 | continue; | 2064 | if (ipport_equal(&ip_port, &c->crypto_connections[i].ip_port)) |
2065 | return i; | ||
2066 | } | ||
733 | 2067 | ||
734 | if (c->crypto_connections[i].status == CRYPTO_CONN_HANDSHAKE_SENT) { | 2068 | return -1; |
735 | uint8_t temp_data[MAX_DATA_SIZE]; | 2069 | } |
736 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 2070 | |
737 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 2071 | #define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + crypto_box_MACBYTES) |
738 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 2072 | |
739 | uint16_t len; | 2073 | /* Handle raw UDP packets coming directly from the socket. |
740 | 2074 | * | |
741 | if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* Handle handshake packet. */ | 2075 | * Handles: |
742 | len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); | 2076 | * Cookie response packets. |
743 | 2077 | * Crypto handshake packets. | |
744 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { | 2078 | * Crypto data packets. |
745 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 2079 | * |
746 | memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 2080 | */ |
747 | memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 2081 | static int udp_handle_packet(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
748 | increment_nonce(c->crypto_connections[i].sent_nonce); | 2082 | { |
749 | uint32_t zero = 0; | 2083 | if (length <= CRYPTO_MIN_PACKET_SIZE || length > MAX_CRYPTO_PACKET_SIZE) |
750 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, | 2084 | return 1; |
751 | c->crypto_connections[i].sessionsecret_key, | 2085 | |
752 | c->crypto_connections[i].shared_key); | 2086 | Net_Crypto *c = object; |
753 | c->crypto_connections[i].status = | 2087 | int crypt_connection_id = crypto_id_ip_port(c, source); |
754 | CRYPTO_CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */ | 2088 | |
755 | write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); | 2089 | if (crypt_connection_id == -1) { |
756 | c->crypto_connections[i].status = CRYPTO_CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */ | 2090 | if (packet[0] != NET_PACKET_CRYPTO_HS) |
757 | } else { | 2091 | return 1; |
758 | /* This should not happen, timeout the connection if it does. */ | 2092 | |
759 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | 2093 | if (handle_new_connection_handshake(c, source, packet, length) != 0) |
760 | } | 2094 | return 1; |
761 | } else { | 2095 | |
762 | /* This should not happen, timeout the connection if it does. */ | 2096 | return 0; |
763 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | 2097 | } |
764 | } | 2098 | |
765 | } else if (id_packet(c->lossless_udp, | 2099 | if (handle_packet_connection(c, crypt_connection_id, packet, length) != 0) |
766 | c->crypto_connections[i].number) != (uint8_t)~0) { | 2100 | return 1; |
767 | /* This should not happen, timeout the connection if it does. */ | 2101 | |
768 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | 2102 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
2103 | |||
2104 | if (conn == 0) | ||
2105 | return -1; | ||
2106 | |||
2107 | conn->direct_lastrecv_time = current_time_monotonic(); | ||
2108 | return 0; | ||
2109 | } | ||
2110 | |||
2111 | /* The dT for the average packet recieving rate calculations. | ||
2112 | Also used as the */ | ||
2113 | #define PACKET_COUNTER_AVERAGE_INTERVAL 200 | ||
2114 | |||
2115 | /* Ratio of recv queue size / recv packet rate (in seconds) times | ||
2116 | * the number of ms between request packets to send at that ratio | ||
2117 | */ | ||
2118 | #define REQUEST_PACKETS_COMPARE_CONSTANT (0.5 * 100.0) | ||
2119 | static void send_crypto_packets(Net_Crypto *c) | ||
2120 | { | ||
2121 | uint32_t i; | ||
2122 | uint64_t temp_time = current_time_monotonic(); | ||
2123 | |||
2124 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
2125 | Crypto_Connection *conn = get_crypto_connection(c, i); | ||
2126 | |||
2127 | if (conn == 0) | ||
2128 | return; | ||
2129 | |||
2130 | if (CRYPTO_SEND_PACKET_INTERVAL + conn->temp_packet_sent_time < temp_time) { | ||
2131 | send_temp_packet(c, i); | ||
2132 | } | ||
2133 | |||
2134 | if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) | ||
2135 | && (CRYPTO_SEND_PACKET_INTERVAL + conn->last_request_packet_sent) < temp_time) { | ||
2136 | if (send_request_packet(c, i) == 0) { | ||
2137 | conn->last_request_packet_sent = temp_time; | ||
769 | } | 2138 | } |
2139 | |||
770 | } | 2140 | } |
771 | 2141 | ||
772 | if (c->crypto_connections[i].status == CRYPTO_CONN_NOT_CONFIRMED) { | 2142 | if (conn->status == CRYPTO_CONN_ESTABLISHED) { |
773 | if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { | 2143 | if (((double)num_packets_array(&conn->recv_array) / (conn->packet_recv_rate + 1.0)) * (double)( |
774 | uint8_t temp_data[MAX_DATA_SIZE]; | 2144 | temp_time - conn->last_request_packet_sent) > REQUEST_PACKETS_COMPARE_CONSTANT) { |
775 | uint8_t data[MAX_DATA_SIZE]; | 2145 | if (send_request_packet(c, i) == 0) { |
776 | int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); | 2146 | conn->last_request_packet_sent = temp_time; |
777 | int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, | 2147 | } |
778 | c->crypto_connections[i].sessionsecret_key, | 2148 | } |
779 | c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); | 2149 | |
780 | uint32_t zero = 0; | 2150 | if ((PACKET_COUNTER_AVERAGE_INTERVAL + conn->packet_counter_set) < temp_time) { |
781 | 2151 | conn->packet_recv_rate = (double)conn->packet_counter / ((double)(temp_time - conn->packet_counter_set) / 1000.0); | |
782 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { | 2152 | conn->packet_counter = 0; |
783 | increment_nonce(c->crypto_connections[i].recv_nonce); | 2153 | conn->packet_counter_set = temp_time; |
784 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, | 2154 | |
785 | c->crypto_connections[i].sessionsecret_key, | 2155 | if ((double)num_packets_array(&conn->send_array) < 0.3 * (conn->packet_send_rate)) { |
786 | c->crypto_connections[i].shared_key); | 2156 | conn->packet_send_rate *= 1.2; |
787 | c->crypto_connections[i].status = CRYPTO_CONN_ESTABLISHED; | 2157 | } else if ((double)num_packets_array(&conn->send_array) > 0.4 * (conn->packet_send_rate)) { |
788 | c->crypto_connections[i].timeout = ~0; | 2158 | conn->packet_send_rate *= 0.8; |
789 | /* Connection is accepted. */ | 2159 | } |
790 | confirm_connection(c->lossless_udp, c->crypto_connections[i].number); | 2160 | |
2161 | if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) | ||
2162 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | ||
2163 | |||
2164 | if (conn->packet_send_rate > CRYPTO_PACKET_BUFFER_SIZE * 2) | ||
2165 | conn->packet_send_rate = CRYPTO_PACKET_BUFFER_SIZE * 2; | ||
2166 | |||
2167 | } | ||
2168 | |||
2169 | if (conn->last_packets_left_set == 0) { | ||
2170 | conn->last_packets_left_set = temp_time; | ||
2171 | conn->packets_left = conn->packet_send_rate; | ||
2172 | } else if (((1000.0 / conn->packet_send_rate) + conn->last_packets_left_set) < temp_time) { | ||
2173 | uint32_t num_packets = conn->packet_send_rate * ((double)(temp_time - conn->last_packets_left_set) / 1000.0); | ||
2174 | |||
2175 | if (conn->packets_left > num_packets * 2 + CRYPTO_MIN_QUEUE_LENGTH) { | ||
2176 | conn->packets_left = num_packets * 2 + CRYPTO_MIN_QUEUE_LENGTH; | ||
791 | } else { | 2177 | } else { |
792 | /* This should not happen, timeout the connection if it does. */ | 2178 | conn->packets_left += num_packets; |
793 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | ||
794 | } | 2179 | } |
795 | } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != (uint8_t)~0) { | 2180 | |
796 | /* This should not happen, timeout the connection if it does. */ | 2181 | conn->last_packets_left_set = temp_time; |
797 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | ||
798 | } | 2182 | } |
799 | } | ||
800 | 2183 | ||
801 | if (temp_time > c->crypto_connections[i].timeout) { | 2184 | int ret = send_requested_packets(c, i, conn->packets_left); |
802 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | 2185 | |
2186 | if (ret != -1) { | ||
2187 | conn->packets_left -= ret; | ||
2188 | } | ||
2189 | |||
2190 | if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH) { | ||
2191 | --conn->sending; | ||
2192 | } | ||
803 | } | 2193 | } |
804 | } | 2194 | } |
805 | } | 2195 | } |
806 | 2196 | ||
2197 | |||
2198 | /* returns the number of packet slots left in the sendbuffer. | ||
2199 | * return 0 if failure. | ||
2200 | */ | ||
2201 | uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) | ||
2202 | { | ||
2203 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
2204 | |||
2205 | if (conn == 0) | ||
2206 | return 0; | ||
2207 | |||
2208 | return conn->packets_left; | ||
2209 | } | ||
2210 | |||
2211 | |||
2212 | |||
2213 | |||
2214 | /* return -1 if data could not be put in packet queue. | ||
2215 | * return positive packet number if data was put into the queue. | ||
2216 | */ | ||
2217 | int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) | ||
2218 | { | ||
2219 | if (length == 0) | ||
2220 | return -1; | ||
2221 | |||
2222 | if (data[0] < CRYPTO_RESERVED_PACKETS) | ||
2223 | return -1; | ||
2224 | |||
2225 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
2226 | |||
2227 | if (conn == 0) | ||
2228 | return -1; | ||
2229 | |||
2230 | if (conn->status != CRYPTO_CONN_ESTABLISHED) | ||
2231 | return -1; | ||
2232 | |||
2233 | if (conn->packets_left == 0) | ||
2234 | return -1; | ||
2235 | |||
2236 | int64_t ret = send_lossless_packet(c, crypt_connection_id, data, length); | ||
2237 | |||
2238 | if (ret == -1) | ||
2239 | return -1; | ||
2240 | |||
2241 | --conn->packets_left; | ||
2242 | conn->sending = CRYPTO_MIN_QUEUE_LENGTH; | ||
2243 | return ret; | ||
2244 | } | ||
2245 | |||
2246 | /* Kill a crypto connection. | ||
2247 | * | ||
2248 | * return -1 on failure. | ||
2249 | * return 0 on success. | ||
2250 | */ | ||
2251 | int crypto_kill(Net_Crypto *c, int crypt_connection_id) | ||
2252 | { | ||
2253 | //TODO | ||
2254 | send_kill_packet(c, crypt_connection_id); | ||
2255 | disconnect_peer_tcp(c, crypt_connection_id); | ||
2256 | return wipe_crypto_connection(c, crypt_connection_id); | ||
2257 | } | ||
2258 | |||
2259 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. | ||
2260 | * | ||
2261 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. | ||
2262 | */ | ||
2263 | unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) | ||
2264 | { | ||
2265 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
2266 | |||
2267 | if (conn == 0) | ||
2268 | return CRYPTO_CONN_NO_CONNECTION; | ||
2269 | |||
2270 | *direct_connected = 0; | ||
2271 | |||
2272 | if ((CRYPTO_SEND_PACKET_INTERVAL * MAX_NUM_SENDPACKET_TRIES + conn->direct_lastrecv_time) > current_time_monotonic()) | ||
2273 | *direct_connected = 1; | ||
2274 | |||
2275 | return conn->status; | ||
2276 | } | ||
2277 | |||
2278 | void new_keys(Net_Crypto *c) | ||
2279 | { | ||
2280 | crypto_box_keypair(c->self_public_key, c->self_secret_key); | ||
2281 | } | ||
2282 | |||
2283 | /* Save the public and private keys to the keys array. | ||
2284 | * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. | ||
2285 | */ | ||
2286 | void save_keys(Net_Crypto *c, uint8_t *keys) | ||
2287 | { | ||
2288 | memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
2289 | memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); | ||
2290 | } | ||
2291 | |||
2292 | /* Load the public and private keys from the keys array. | ||
2293 | * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. | ||
2294 | */ | ||
2295 | void load_keys(Net_Crypto *c, uint8_t *keys) | ||
2296 | { | ||
2297 | memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES); | ||
2298 | memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); | ||
2299 | } | ||
2300 | |||
807 | /* Run this to (re)initialize net_crypto. | 2301 | /* Run this to (re)initialize net_crypto. |
808 | * Sets all the global connection variables to their default values. | 2302 | * Sets all the global connection variables to their default values. |
809 | */ | 2303 | */ |
810 | Net_Crypto *new_net_crypto(Networking_Core *net) | 2304 | Net_Crypto *new_net_crypto(DHT *dht) |
811 | { | 2305 | { |
812 | unix_time_update(); | 2306 | unix_time_update(); |
813 | 2307 | ||
814 | if (net == NULL) | 2308 | if (dht == NULL) |
815 | return NULL; | 2309 | return NULL; |
816 | 2310 | ||
817 | Net_Crypto *temp = calloc(1, sizeof(Net_Crypto)); | 2311 | Net_Crypto *temp = calloc(1, sizeof(Net_Crypto)); |
@@ -819,31 +2313,55 @@ Net_Crypto *new_net_crypto(Networking_Core *net) | |||
819 | if (temp == NULL) | 2313 | if (temp == NULL) |
820 | return NULL; | 2314 | return NULL; |
821 | 2315 | ||
822 | temp->lossless_udp = new_lossless_udp(net); | 2316 | temp->dht = dht; |
823 | |||
824 | if (temp->lossless_udp == NULL) { | ||
825 | free(temp); | ||
826 | return NULL; | ||
827 | } | ||
828 | 2317 | ||
829 | new_keys(temp); | 2318 | new_keys(temp); |
830 | return temp; | 2319 | new_symmetric_key(temp->secret_symmetric_key); |
831 | } | ||
832 | 2320 | ||
833 | void init_cryptopackets(void *dht) | 2321 | networking_registerhandler(dht->net, NET_PACKET_COOKIE_REQUEST, &udp_handle_cookie_request, temp); |
834 | { | 2322 | networking_registerhandler(dht->net, NET_PACKET_COOKIE_RESPONSE, &udp_handle_packet, temp); |
835 | DHT *s_dht = dht; | 2323 | networking_registerhandler(dht->net, NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp); |
836 | networking_registerhandler(s_dht->c->lossless_udp->net, NET_PACKET_CRYPTO, &cryptopacket_handle, s_dht); | 2324 | networking_registerhandler(dht->net, NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp); |
2325 | return temp; | ||
837 | } | 2326 | } |
838 | 2327 | ||
839 | static void kill_timedout(Net_Crypto *c) | 2328 | static void kill_timedout(Net_Crypto *c) |
840 | { | 2329 | { |
841 | uint32_t i; | 2330 | uint32_t i; |
2331 | //uint64_t temp_time = current_time_monotonic(); | ||
842 | 2332 | ||
843 | for (i = 0; i < c->crypto_connections_length; ++i) { | 2333 | for (i = 0; i < c->crypto_connections_length; ++i) { |
844 | if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION | 2334 | Crypto_Connection *conn = get_crypto_connection(c, i); |
845 | && is_connected(c->lossless_udp, c->crypto_connections[i].number) == LUDP_TIMED_OUT) | 2335 | |
846 | c->crypto_connections[i].status = CRYPTO_CONN_TIMED_OUT; | 2336 | if (conn == 0) |
2337 | return; | ||
2338 | |||
2339 | if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT) | ||
2340 | continue; | ||
2341 | |||
2342 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT | ||
2343 | || conn->status == CRYPTO_CONN_NOT_CONFIRMED) { | ||
2344 | if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) | ||
2345 | continue; | ||
2346 | |||
2347 | conn->killed = 1; | ||
2348 | |||
2349 | } | ||
2350 | |||
2351 | if (conn->killed) { | ||
2352 | if (conn->connection_status_callback) { | ||
2353 | conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0); | ||
2354 | crypto_kill(c, i); | ||
2355 | continue; | ||
2356 | } | ||
2357 | |||
2358 | conn->status = CRYPTO_CONN_TIMED_OUT; | ||
2359 | continue; | ||
2360 | } | ||
2361 | |||
2362 | if (conn->status == CRYPTO_CONN_ESTABLISHED) { | ||
2363 | //TODO: add a timeout here? | ||
2364 | } | ||
847 | } | 2365 | } |
848 | } | 2366 | } |
849 | 2367 | ||
@@ -851,9 +2369,10 @@ static void kill_timedout(Net_Crypto *c) | |||
851 | void do_net_crypto(Net_Crypto *c) | 2369 | void do_net_crypto(Net_Crypto *c) |
852 | { | 2370 | { |
853 | unix_time_update(); | 2371 | unix_time_update(); |
854 | do_lossless_udp(c->lossless_udp); | ||
855 | kill_timedout(c); | 2372 | kill_timedout(c); |
856 | receive_crypto(c); | 2373 | do_tcp(c); |
2374 | clear_disconnected_tcp(c); | ||
2375 | send_crypto_packets(c); | ||
857 | } | 2376 | } |
858 | 2377 | ||
859 | void kill_net_crypto(Net_Crypto *c) | 2378 | void kill_net_crypto(Net_Crypto *c) |
@@ -864,7 +2383,15 @@ void kill_net_crypto(Net_Crypto *c) | |||
864 | crypto_kill(c, i); | 2383 | crypto_kill(c, i); |
865 | } | 2384 | } |
866 | 2385 | ||
867 | kill_lossless_udp(c->lossless_udp); | 2386 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
2387 | kill_TCP_connection(c->tcp_connections_new[i]); | ||
2388 | kill_TCP_connection(c->tcp_connections[i]); | ||
2389 | } | ||
2390 | |||
2391 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); | ||
2392 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); | ||
2393 | networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL); | ||
2394 | networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_DATA, NULL, NULL); | ||
868 | memset(c, 0, sizeof(Net_Crypto)); | 2395 | memset(c, 0, sizeof(Net_Crypto)); |
869 | free(c); | 2396 | free(c); |
870 | } | 2397 | } |