diff options
-rw-r--r-- | core/DHT.c | 331 | ||||
-rw-r--r-- | core/DHT.h | 148 | ||||
-rw-r--r-- | core/LAN_discovery.c | 6 | ||||
-rw-r--r-- | core/LAN_discovery.h | 22 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 78 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 112 | ||||
-rw-r--r-- | core/Messenger.c | 124 | ||||
-rw-r--r-- | core/Messenger.h | 216 | ||||
-rw-r--r-- | core/friend_requests.c | 33 | ||||
-rw-r--r-- | core/friend_requests.h | 30 | ||||
-rw-r--r-- | core/net_crypto.c | 138 | ||||
-rw-r--r-- | core/net_crypto.h | 194 | ||||
-rw-r--r-- | core/network.c | 64 | ||||
-rw-r--r-- | core/network.h | 124 |
14 files changed, 804 insertions, 816 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* DHT.c | 1 | /* DHT.c |
2 | * | 2 | * |
3 | * An implementation of the DHT as seen in docs/DHT.txt | 3 | * An implementation of the DHT as seen in docs/DHT.txt |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
@@ -18,52 +18,48 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "DHT.h" | 24 | #include "DHT.h" |
25 | 25 | ||
26 | typedef struct | 26 | typedef struct { |
27 | { | ||
28 | uint8_t client_id[CLIENT_ID_SIZE]; | 27 | uint8_t client_id[CLIENT_ID_SIZE]; |
29 | IP_Port ip_port; | 28 | IP_Port ip_port; |
30 | uint32_t timestamp; | 29 | uint32_t timestamp; |
31 | uint32_t last_pinged; | 30 | uint32_t last_pinged; |
32 | IP_Port ret_ip_port;/* The ip_port returned by this node for the friend | 31 | IP_Port ret_ip_port;/* The ip_port returned by this node for the friend |
33 | (for nodes in friends_list) or us (for nodes in close_clientlist) */ | 32 | (for nodes in friends_list) or us (for nodes in close_clientlist) */ |
34 | uint32_t ret_timestamp; | 33 | uint32_t ret_timestamp; |
35 | }Client_data; | 34 | } Client_data; |
36 | 35 | ||
37 | /* maximum number of clients stored per friend. */ | 36 | /* maximum number of clients stored per friend. */ |
38 | #define MAX_FRIEND_CLIENTS 8 | 37 | #define MAX_FRIEND_CLIENTS 8 |
39 | 38 | ||
40 | typedef struct | 39 | typedef struct { |
41 | { | ||
42 | uint8_t client_id[CLIENT_ID_SIZE]; | 40 | uint8_t client_id[CLIENT_ID_SIZE]; |
43 | Client_data client_list[MAX_FRIEND_CLIENTS]; | 41 | Client_data client_list[MAX_FRIEND_CLIENTS]; |
44 | uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ | 42 | uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ |
45 | 43 | ||
46 | /*Symetric NAT hole punching stuff*/ | 44 | /*Symetric NAT hole punching stuff*/ |
47 | uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */ | 45 | uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */ |
48 | uint32_t punching_index; | 46 | uint32_t punching_index; |
49 | uint32_t punching_timestamp; | 47 | uint32_t punching_timestamp; |
50 | uint64_t NATping_id; | 48 | uint64_t NATping_id; |
51 | uint32_t NATping_timestamp; | 49 | uint32_t NATping_timestamp; |
52 | }Friend; | 50 | } Friend; |
53 | 51 | ||
54 | typedef struct | 52 | typedef struct { |
55 | { | ||
56 | uint8_t client_id[CLIENT_ID_SIZE]; | 53 | uint8_t client_id[CLIENT_ID_SIZE]; |
57 | IP_Port ip_port; | 54 | IP_Port ip_port; |
58 | }Node_format; | 55 | } Node_format; |
59 | 56 | ||
60 | typedef struct | 57 | typedef struct { |
61 | { | ||
62 | IP_Port ip_port; | 58 | IP_Port ip_port; |
63 | uint64_t ping_id; | 59 | uint64_t ping_id; |
64 | uint32_t timestamp; | 60 | uint32_t timestamp; |
65 | 61 | ||
66 | }Pinged; | 62 | } Pinged; |
67 | 63 | ||
68 | /* Our client id/public key */ | 64 | /* Our client id/public key */ |
69 | uint8_t self_public_key[CLIENT_ID_SIZE]; | 65 | uint8_t self_public_key[CLIENT_ID_SIZE]; |
@@ -115,7 +111,7 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_ | |||
115 | for(i = 0; i < length; ++i) { | 111 | for(i = 0; i < length; ++i) { |
116 | /*If ip_port is assigned to a different client_id replace it*/ | 112 | /*If ip_port is assigned to a different client_id replace it*/ |
117 | if(list[i].ip_port.ip.i == ip_port.ip.i && | 113 | if(list[i].ip_port.ip.i == ip_port.ip.i && |
118 | list[i].ip_port.port == ip_port.port) { | 114 | list[i].ip_port.port == ip_port.port) { |
119 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 115 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
120 | } | 116 | } |
121 | 117 | ||
@@ -167,39 +163,38 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) | |||
167 | int num_nodes=0; | 163 | int num_nodes=0; |
168 | uint32_t temp_time = unix_time(); | 164 | uint32_t temp_time = unix_time(); |
169 | for(i = 0; i < LCLIENT_LIST; ++i) | 165 | for(i = 0; i < LCLIENT_LIST; ++i) |
170 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && | 166 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && |
171 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { | 167 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { |
172 | /* if node is good and not already in list. */ | 168 | /* if node is good and not already in list. */ |
173 | if(num_nodes < MAX_SENT_NODES) { | 169 | if(num_nodes < MAX_SENT_NODES) { |
174 | memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); | 170 | memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); |
175 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; | 171 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; |
176 | num_nodes++; | 172 | num_nodes++; |
177 | } | 173 | } else for(j = 0; j < MAX_SENT_NODES; ++j) |
178 | else for(j = 0; j < MAX_SENT_NODES; ++j) | 174 | if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { |
179 | if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { | 175 | memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); |
180 | memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); | 176 | nodes_list[j].ip_port = close_clientlist[i].ip_port; |
181 | nodes_list[j].ip_port = close_clientlist[i].ip_port; | 177 | break; |
182 | break; | 178 | } |
183 | } | ||
184 | } | 179 | } |
185 | 180 | ||
186 | for(i = 0; i < num_friends; ++i) | 181 | for(i = 0; i < num_friends; ++i) |
187 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | 182 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
188 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && | 183 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && |
189 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) { | 184 | !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) { |
190 | /* if node is good and not already in list. */ | 185 | /* if node is good and not already in list. */ |
191 | if(num_nodes < MAX_SENT_NODES) { | 186 | if(num_nodes < MAX_SENT_NODES) { |
192 | memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); | 187 | memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); |
193 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; | 188 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; |
194 | num_nodes++; | 189 | num_nodes++; |
195 | } else for(k = 0; k < MAX_SENT_NODES; ++k) | 190 | } else for(k = 0; k < MAX_SENT_NODES; ++k) |
196 | if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) { | 191 | if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) { |
197 | memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); | 192 | memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); |
198 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; | 193 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; |
199 | break; | 194 | break; |
200 | } | 195 | } |
201 | } | 196 | } |
202 | return num_nodes; | 197 | return num_nodes; |
203 | } | 198 | } |
204 | 199 | ||
205 | /* replace first bad (or empty) node with this one | 200 | /* replace first bad (or empty) node with this one |
@@ -210,7 +205,7 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por | |||
210 | uint32_t i; | 205 | uint32_t i; |
211 | uint32_t temp_time = unix_time(); | 206 | uint32_t temp_time = unix_time(); |
212 | for(i = 0; i < length; ++i) | 207 | for(i = 0; i < length; ++i) |
213 | if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ { | 208 | if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */ |
214 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 209 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
215 | list[i].ip_port = ip_port; | 210 | list[i].ip_port = ip_port; |
216 | list[i].timestamp = temp_time; | 211 | list[i].timestamp = temp_time; |
@@ -228,7 +223,7 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po | |||
228 | { | 223 | { |
229 | uint32_t i; | 224 | uint32_t i; |
230 | uint32_t temp_time = unix_time(); | 225 | uint32_t temp_time = unix_time(); |
231 | 226 | ||
232 | for(i = 0; i < length; ++i) | 227 | for(i = 0; i < length; ++i) |
233 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { | 228 | if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { |
234 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 229 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
@@ -247,7 +242,7 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po | |||
247 | void addto_lists(IP_Port ip_port, uint8_t * client_id) | 242 | void addto_lists(IP_Port ip_port, uint8_t * client_id) |
248 | { | 243 | { |
249 | uint32_t i; | 244 | uint32_t i; |
250 | 245 | ||
251 | /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ | 246 | /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ |
252 | if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) | 247 | if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
253 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) | 248 | if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) |
@@ -261,7 +256,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id) | |||
261 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); | 256 | replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); |
262 | } | 257 | } |
263 | 258 | ||
264 | /* If client_id is a friend or us, update ret_ip_port | 259 | /* If client_id is a friend or us, update ret_ip_port |
265 | nodeclient_id is the id of the node that sent us this info */ | 260 | nodeclient_id is the id of the node that sent us this info */ |
266 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) | 261 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) |
267 | { | 262 | { |
@@ -275,14 +270,14 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient | |||
275 | return; | 270 | return; |
276 | } | 271 | } |
277 | } else | 272 | } else |
278 | for(i = 0; i < num_friends; ++i) | 273 | for(i = 0; i < num_friends; ++i) |
279 | if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) | 274 | if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) |
280 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | 275 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
281 | if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { | 276 | if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { |
282 | friends_list[i].client_list[j].ret_ip_port = ip_port; | 277 | friends_list[i].client_list[j].ret_ip_port = ip_port; |
283 | friends_list[i].client_list[j].ret_timestamp = temp_time; | 278 | friends_list[i].client_list[j].ret_timestamp = temp_time; |
284 | return; | 279 | return; |
285 | } | 280 | } |
286 | } | 281 | } |
287 | 282 | ||
288 | /* ping timeout in seconds */ | 283 | /* ping timeout in seconds */ |
@@ -304,13 +299,13 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id) | |||
304 | pinging = 0; | 299 | pinging = 0; |
305 | if(ip_port.ip.i != 0) | 300 | if(ip_port.ip.i != 0) |
306 | if(pings[i].ip_port.ip.i == ip_port.ip.i && | 301 | if(pings[i].ip_port.ip.i == ip_port.ip.i && |
307 | pings[i].ip_port.port == ip_port.port) | 302 | pings[i].ip_port.port == ip_port.port) |
308 | ++pinging; | 303 | ++pinging; |
309 | if(ping_id != 0) | 304 | if(ping_id != 0) |
310 | if(pings[i].ping_id == ping_id) | 305 | if(pings[i].ping_id == ping_id) |
311 | ++pinging; | 306 | ++pinging; |
312 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 307 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
313 | return 1; | 308 | return 1; |
314 | } | 309 | } |
315 | 310 | ||
316 | return 0; | 311 | return 0; |
@@ -328,14 +323,14 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
328 | pinging = 0; | 323 | pinging = 0; |
329 | if(ip_port.ip.i != 0) | 324 | if(ip_port.ip.i != 0) |
330 | if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && | 325 | if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && |
331 | send_nodes[i].ip_port.port == ip_port.port) | 326 | send_nodes[i].ip_port.port == ip_port.port) |
332 | ++pinging; | 327 | ++pinging; |
333 | if(ping_id != 0) | 328 | if(ping_id != 0) |
334 | if(send_nodes[i].ping_id == ping_id) | 329 | if(send_nodes[i].ping_id == ping_id) |
335 | ++pinging; | 330 | ++pinging; |
336 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 331 | if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
337 | return 1; | 332 | return 1; |
338 | 333 | ||
339 | } | 334 | } |
340 | 335 | ||
341 | return 0; | 336 | return 0; |
@@ -354,10 +349,10 @@ uint64_t add_pinging(IP_Port ip_port) | |||
354 | for(i = 0; i < PING_TIMEOUT; ++i ) | 349 | for(i = 0; i < PING_TIMEOUT; ++i ) |
355 | for(j = 0; j < LPING_ARRAY; ++j ) | 350 | for(j = 0; j < LPING_ARRAY; ++j ) |
356 | if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { | 351 | if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { |
357 | pings[j].timestamp = temp_time; | 352 | pings[j].timestamp = temp_time; |
358 | pings[j].ip_port = ip_port; | 353 | pings[j].ip_port = ip_port; |
359 | pings[j].ping_id = ping_id; | 354 | pings[j].ping_id = ping_id; |
360 | return ping_id; | 355 | return ping_id; |
361 | } | 356 | } |
362 | 357 | ||
363 | return 0; | 358 | return 0; |
@@ -373,10 +368,10 @@ uint64_t add_gettingnodes(IP_Port ip_port) | |||
373 | for(i = 0; i < PING_TIMEOUT; ++i ) | 368 | for(i = 0; i < PING_TIMEOUT; ++i ) |
374 | for(j = 0; j < LSEND_NODES_ARRAY; ++j ) | 369 | for(j = 0; j < LSEND_NODES_ARRAY; ++j ) |
375 | if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { | 370 | if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { |
376 | send_nodes[j].timestamp = temp_time; | 371 | send_nodes[j].timestamp = temp_time; |
377 | send_nodes[j].ip_port = ip_port; | 372 | send_nodes[j].ip_port = ip_port; |
378 | send_nodes[j].ping_id = ping_id; | 373 | send_nodes[j].ping_id = ping_id; |
379 | return ping_id; | 374 | return ping_id; |
380 | } | 375 | } |
381 | 376 | ||
382 | return 0; | 377 | return 0; |
@@ -415,7 +410,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key) | |||
415 | /* send a ping response */ | 410 | /* send a ping response */ |
416 | static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) | 411 | static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) |
417 | { | 412 | { |
418 | /* check if packet is gonna be sent to ourself */ | 413 | /* check if packet is gonna be sent to ourself */ |
419 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) | 414 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) |
420 | return 1; | 415 | return 1; |
421 | 416 | ||
@@ -431,7 +426,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) | |||
431 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 426 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
432 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 427 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
433 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 428 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
434 | 429 | ||
435 | return sendpacket(ip_port, data, sizeof(data)); | 430 | return sendpacket(ip_port, data, sizeof(data)); |
436 | } | 431 | } |
437 | 432 | ||
@@ -441,26 +436,26 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) | |||
441 | /* check if packet is gonna be sent to ourself */ | 436 | /* check if packet is gonna be sent to ourself */ |
442 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) | 437 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) |
443 | return 1; | 438 | return 1; |
444 | 439 | ||
445 | if(is_gettingnodes(ip_port, 0)) | 440 | if(is_gettingnodes(ip_port, 0)) |
446 | return 1; | 441 | return 1; |
447 | 442 | ||
448 | uint64_t ping_id = add_gettingnodes(ip_port); | 443 | uint64_t ping_id = add_gettingnodes(ip_port); |
449 | 444 | ||
450 | if(ping_id == 0) | 445 | if(ping_id == 0) |
451 | return 1; | 446 | return 1; |
452 | 447 | ||
453 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; | 448 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; |
454 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 449 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
455 | uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; | 450 | uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; |
456 | uint8_t nonce[crypto_box_NONCEBYTES]; | 451 | uint8_t nonce[crypto_box_NONCEBYTES]; |
457 | random_nonce(nonce); | 452 | random_nonce(nonce); |
458 | 453 | ||
459 | memcpy(plain, &ping_id, sizeof(ping_id)); | 454 | memcpy(plain, &ping_id, sizeof(ping_id)); |
460 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); | 455 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
461 | 456 | ||
462 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); | 457 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); |
463 | 458 | ||
464 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | 459 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) |
465 | return -1; | 460 | return -1; |
466 | data[0] = 2; | 461 | data[0] = 2; |
@@ -476,8 +471,8 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, | |||
476 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ | 471 | if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ |
477 | return 1; | 472 | return 1; |
478 | 473 | ||
479 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 474 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
480 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 475 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
481 | 476 | ||
482 | Node_format nodes_list[MAX_SENT_NODES]; | 477 | Node_format nodes_list[MAX_SENT_NODES]; |
483 | int num_nodes = get_close_nodes(client_id, nodes_list); | 478 | int num_nodes = get_close_nodes(client_id, nodes_list); |
@@ -489,16 +484,16 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, | |||
489 | uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 484 | uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
490 | uint8_t nonce[crypto_box_NONCEBYTES]; | 485 | uint8_t nonce[crypto_box_NONCEBYTES]; |
491 | random_nonce(nonce); | 486 | random_nonce(nonce); |
492 | 487 | ||
493 | memcpy(plain, &ping_id, sizeof(ping_id)); | 488 | memcpy(plain, &ping_id, sizeof(ping_id)); |
494 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); | 489 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); |
495 | 490 | ||
496 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, | 491 | int len = encrypt_data(public_key, self_secret_key, nonce, plain, |
497 | sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); | 492 | sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); |
498 | 493 | ||
499 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) | 494 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) |
500 | return -1; | 495 | return -1; |
501 | 496 | ||
502 | data[0] = 3; | 497 | data[0] = 3; |
503 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 498 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); |
504 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 499 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
@@ -515,13 +510,13 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) | |||
515 | uint64_t ping_id; | 510 | uint64_t ping_id; |
516 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) | 511 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) |
517 | return 1; | 512 | return 1; |
518 | /* check if packet is from ourself. */ | 513 | /* check if packet is from ourself. */ |
519 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) | 514 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) |
520 | return 1; | 515 | return 1; |
521 | 516 | ||
522 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 517 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
523 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 518 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
524 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | 519 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); |
525 | if(len != sizeof(ping_id)) | 520 | if(len != sizeof(ping_id)) |
526 | return 1; | 521 | return 1; |
527 | 522 | ||
@@ -540,18 +535,18 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) | |||
540 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ | 535 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ |
541 | return 1; | 536 | return 1; |
542 | 537 | ||
543 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 538 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
544 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 539 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
545 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); | 540 | sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); |
546 | if(len != sizeof(ping_id)) | 541 | if(len != sizeof(ping_id)) |
547 | return 1; | 542 | return 1; |
548 | 543 | ||
549 | if(is_pinging(source, ping_id)) { | 544 | if(is_pinging(source, ping_id)) { |
550 | addto_lists(source, packet + 1); | 545 | addto_lists(source, packet + 1); |
551 | return 0; | 546 | return 0; |
552 | } | 547 | } |
553 | return 1; | 548 | return 1; |
554 | 549 | ||
555 | } | 550 | } |
556 | 551 | ||
557 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | 552 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) |
@@ -559,15 +554,15 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
559 | uint64_t ping_id; | 554 | uint64_t ping_id; |
560 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) | 555 | if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) |
561 | return 1; | 556 | return 1; |
562 | /* check if packet is from ourself. */ | 557 | /* check if packet is from ourself. */ |
563 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) | 558 | if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) |
564 | return 1; | 559 | return 1; |
565 | 560 | ||
566 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 561 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
567 | 562 | ||
568 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 563 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
569 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 564 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
570 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); | 565 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); |
571 | 566 | ||
572 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE) | 567 | if(len != sizeof(ping_id) + CLIENT_ID_SIZE) |
573 | return 1; | 568 | return 1; |
@@ -578,7 +573,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
578 | pingreq(source, packet + 1); /* TODO: make this smarter? */ | 573 | pingreq(source, packet + 1); /* TODO: make this smarter? */ |
579 | 574 | ||
580 | return 0; | 575 | return 0; |
581 | 576 | ||
582 | } | 577 | } |
583 | 578 | ||
584 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | 579 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) |
@@ -586,21 +581,21 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | |||
586 | uint64_t ping_id; | 581 | uint64_t ping_id; |
587 | /* TODO: make this more readable */ | 582 | /* TODO: make this more readable */ |
588 | if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 583 | if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
589 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || | 584 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || |
590 | (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 585 | (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
591 | + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || | 586 | + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || |
592 | length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 587 | length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
593 | + sizeof(Node_format) + ENCRYPTION_PADDING) { | 588 | + sizeof(Node_format) + ENCRYPTION_PADDING) { |
594 | return 1; | 589 | return 1; |
595 | } | 590 | } |
596 | uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | 591 | uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
597 | + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); | 592 | + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format); |
598 | 593 | ||
599 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; | 594 | uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; |
600 | 595 | ||
601 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, | 596 | int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, |
602 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 597 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
603 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); | 598 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); |
604 | 599 | ||
605 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) | 600 | if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) |
606 | return 1; | 601 | return 1; |
@@ -648,7 +643,7 @@ int DHT_delfriend(uint8_t * client_id) | |||
648 | uint32_t i; | 643 | uint32_t i; |
649 | Friend * temp; | 644 | Friend * temp; |
650 | for(i = 0; i < num_friends; ++i) | 645 | for(i = 0; i < num_friends; ++i) |
651 | /* Equal */ | 646 | /* Equal */ |
652 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { | 647 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { |
653 | --num_friends; | 648 | --num_friends; |
654 | if(num_friends != i) | 649 | if(num_friends != i) |
@@ -669,18 +664,18 @@ IP_Port DHT_getfriendip(uint8_t * client_id) | |||
669 | IP_Port empty = {{{0}}, 0}; | 664 | IP_Port empty = {{{0}}, 0}; |
670 | uint32_t temp_time = unix_time(); | 665 | uint32_t temp_time = unix_time(); |
671 | for(i = 0; i < num_friends; ++i) | 666 | for(i = 0; i < num_friends; ++i) |
672 | /* Equal */ | 667 | /* Equal */ |
673 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { | 668 | if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { |
674 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | 669 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
675 | if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && | 670 | if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && |
676 | friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) | 671 | friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) |
677 | return friends_list[i].client_list[j].ip_port; | 672 | return friends_list[i].client_list[j].ip_port; |
678 | 673 | ||
679 | return empty; | 674 | return empty; |
680 | } | 675 | } |
681 | empty.ip.i = 1; | 676 | empty.ip.i = 1; |
682 | return empty; | 677 | return empty; |
683 | 678 | ||
684 | } | 679 | } |
685 | 680 | ||
686 | /* The timeout after which a node is discarded completely. */ | 681 | /* The timeout after which a node is discarded completely. */ |
@@ -700,24 +695,24 @@ void doDHTFriends() | |||
700 | uint32_t temp_time = unix_time(); | 695 | uint32_t temp_time = unix_time(); |
701 | uint32_t rand_node; | 696 | uint32_t rand_node; |
702 | uint32_t index[MAX_FRIEND_CLIENTS]; | 697 | uint32_t index[MAX_FRIEND_CLIENTS]; |
703 | 698 | ||
704 | for(i = 0; i < num_friends; ++i) { | 699 | for(i = 0; i < num_friends; ++i) { |
705 | uint32_t num_nodes = 0; | 700 | uint32_t num_nodes = 0; |
706 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | 701 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
707 | if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ { | 702 | if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { /* if node is not dead. */ |
708 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 703 | if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
709 | pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); | 704 | pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); |
710 | friends_list[i].client_list[j].last_pinged = temp_time; | 705 | friends_list[i].client_list[j].last_pinged = temp_time; |
711 | } | 706 | } |
712 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ { | 707 | if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { /* if node is good. */ |
713 | index[num_nodes] = j; | 708 | index[num_nodes] = j; |
714 | ++num_nodes; | 709 | ++num_nodes; |
715 | } | 710 | } |
716 | } | 711 | } |
717 | if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 712 | if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
718 | rand_node = rand() % num_nodes; | 713 | rand_node = rand() % num_nodes; |
719 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, | 714 | getnodes(friends_list[i].client_list[index[rand_node]].ip_port, |
720 | friends_list[i].client_list[index[rand_node]].client_id, | 715 | friends_list[i].client_list[index[rand_node]].client_id, |
721 | friends_list[i].client_id); | 716 | friends_list[i].client_id); |
722 | friends_list[i].lastgetnode = temp_time; | 717 | friends_list[i].lastgetnode = temp_time; |
723 | } | 718 | } |
@@ -735,25 +730,25 @@ void doClose() /* tested */ | |||
735 | uint32_t num_nodes = 0; | 730 | uint32_t num_nodes = 0; |
736 | uint32_t rand_node; | 731 | uint32_t rand_node; |
737 | uint32_t index[LCLIENT_LIST]; | 732 | uint32_t index[LCLIENT_LIST]; |
738 | 733 | ||
739 | for(i = 0; i < LCLIENT_LIST; ++i) | 734 | for(i = 0; i < LCLIENT_LIST; ++i) |
740 | /* if node is not dead. */ | 735 | /* if node is not dead. */ |
741 | if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { | 736 | if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { |
742 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 737 | if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
743 | pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); | 738 | pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); |
744 | close_clientlist[i].last_pinged = temp_time; | 739 | close_clientlist[i].last_pinged = temp_time; |
745 | } | 740 | } |
746 | /* if node is good. */ | 741 | /* if node is good. */ |
747 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { | 742 | if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { |
748 | index[num_nodes] = i; | 743 | index[num_nodes] = i; |
749 | ++num_nodes; | 744 | ++num_nodes; |
750 | } | 745 | } |
751 | } | 746 | } |
752 | 747 | ||
753 | if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 748 | if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
754 | rand_node = rand() % num_nodes; | 749 | rand_node = rand() % num_nodes; |
755 | getnodes(close_clientlist[index[rand_node]].ip_port, | 750 | getnodes(close_clientlist[index[rand_node]].ip_port, |
756 | close_clientlist[index[rand_node]].client_id, | 751 | close_clientlist[index[rand_node]].client_id, |
757 | self_public_key); | 752 | self_public_key); |
758 | close_lastgetnodes = temp_time; | 753 | close_lastgetnodes = temp_time; |
759 | } | 754 | } |
@@ -761,7 +756,7 @@ void doClose() /* tested */ | |||
761 | 756 | ||
762 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) | 757 | void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) |
763 | { | 758 | { |
764 | getnodes(ip_port, public_key, self_public_key); | 759 | getnodes(ip_port, public_key, self_public_key); |
765 | } | 760 | } |
766 | 761 | ||
767 | /* send the given packet to node with client_id | 762 | /* send the given packet to node with client_id |
@@ -775,7 +770,7 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) | |||
775 | return -1; | 770 | return -1; |
776 | } | 771 | } |
777 | 772 | ||
778 | /* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist | 773 | /* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist |
779 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | 774 | ip_portlist must be at least MAX_FRIEND_CLIENTS big |
780 | returns the number of ips returned | 775 | returns the number of ips returned |
781 | return 0 if we are connected to friend or if no ips were found. | 776 | return 0 if we are connected to friend or if no ips were found. |
@@ -788,9 +783,9 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) | |||
788 | if(friend_num >= num_friends) | 783 | if(friend_num >= num_friends) |
789 | return -1; | 784 | return -1; |
790 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) | 785 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) |
791 | /*If ip is not zero and node is good */ | 786 | /*If ip is not zero and node is good */ |
792 | if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && | 787 | if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && |
793 | friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { | 788 | friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { |
794 | if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) | 789 | if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) |
795 | return 0; | 790 | return 0; |
796 | ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; | 791 | ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; |
@@ -807,11 +802,11 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | |||
807 | uint32_t sent = 0; | 802 | uint32_t sent = 0; |
808 | uint32_t temp_time = unix_time(); | 803 | uint32_t temp_time = unix_time(); |
809 | for(i = 0; i < num_friends; ++i) | 804 | for(i = 0; i < num_friends; ++i) |
810 | /* Equal */ | 805 | /* Equal */ |
811 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { | 806 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { |
812 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | 807 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
813 | /*If ip is not zero and node is good */ | 808 | /*If ip is not zero and node is good */ |
814 | if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && | 809 | if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && |
815 | friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) | 810 | friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) |
816 | if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) | 811 | if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) |
817 | ++sent; | 812 | ++sent; |
@@ -827,15 +822,15 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | |||
827 | int num = friend_number(friend_id); | 822 | int num = friend_number(friend_id); |
828 | if(num == -1) | 823 | if(num == -1) |
829 | return 0; | 824 | return 0; |
830 | 825 | ||
831 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 826 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
832 | int n = 0; | 827 | int n = 0; |
833 | uint32_t i; | 828 | uint32_t i; |
834 | uint32_t temp_time = unix_time(); | 829 | uint32_t temp_time = unix_time(); |
835 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) | 830 | for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) |
836 | /*If ip is not zero and node is good */ | 831 | /*If ip is not zero and node is good */ |
837 | if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && | 832 | if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && |
838 | friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { | 833 | friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { |
839 | ip_list[n] = friends_list[num].client_list[i].ip_port; | 834 | ip_list[n] = friends_list[num].client_list[i].ip_port; |
840 | ++n; | 835 | ++n; |
841 | } | 836 | } |
@@ -846,7 +841,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | |||
846 | return 0; | 841 | return 0; |
847 | } | 842 | } |
848 | 843 | ||
849 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist | 844 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist |
850 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | 845 | ip_portlist must be at least MAX_FRIEND_CLIENTS big |
851 | returns the number of ips returned | 846 | returns the number of ips returned |
852 | return 0 if we are connected to friend or if no ips were found. | 847 | return 0 if we are connected to friend or if no ips were found. |
@@ -856,7 +851,7 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) | |||
856 | 851 | ||
857 | uint32_t i; | 852 | uint32_t i; |
858 | for(i = 0; i < num_friends; ++i) | 853 | for(i = 0; i < num_friends; ++i) |
859 | /* Equal */ | 854 | /* Equal */ |
860 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) | 855 | if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) |
861 | return friend_iplist(ip_portlist, i); | 856 | return friend_iplist(ip_portlist, i); |
862 | return -1; | 857 | return -1; |
@@ -869,7 +864,7 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
869 | uint8_t data[sizeof(uint64_t) + 1]; | 864 | uint8_t data[sizeof(uint64_t) + 1]; |
870 | data[0] = type; | 865 | data[0] = type; |
871 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); | 866 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); |
872 | 867 | ||
873 | uint8_t packet[MAX_DATA_SIZE]; | 868 | uint8_t packet[MAX_DATA_SIZE]; |
874 | int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */ | 869 | int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */ |
875 | if(len == -1) | 870 | if(len == -1) |
@@ -890,9 +885,9 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
890 | int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | 885 | int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) |
891 | { | 886 | { |
892 | if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 887 | if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
893 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 888 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
894 | return 1; | 889 | return 1; |
895 | /* check if request is for us. */ | 890 | /* check if request is for us. */ |
896 | if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 891 | if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
897 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 892 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
898 | uint8_t data[MAX_DATA_SIZE]; | 893 | uint8_t data[MAX_DATA_SIZE]; |
@@ -901,11 +896,11 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | |||
901 | return 1; | 896 | return 1; |
902 | uint64_t ping_id; | 897 | uint64_t ping_id; |
903 | memcpy(&ping_id, data + 1, sizeof(uint64_t)); | 898 | memcpy(&ping_id, data + 1, sizeof(uint64_t)); |
904 | 899 | ||
905 | int friendnumber = friend_number(public_key); | 900 | int friendnumber = friend_number(public_key); |
906 | if(friendnumber == -1) | 901 | if(friendnumber == -1) |
907 | return 1; | 902 | return 1; |
908 | 903 | ||
909 | if(data[0] == 0) { | 904 | if(data[0] == 0) { |
910 | send_NATping(public_key, ping_id, 1); /*1 is reply*/ | 905 | send_NATping(public_key, ping_id, 1); /*1 is reply*/ |
911 | return 0; | 906 | return 0; |
@@ -917,10 +912,9 @@ int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | |||
917 | } | 912 | } |
918 | return 1; | 913 | return 1; |
919 | } | 914 | } |
920 | /* if request is not for us, try routing it. */ | 915 | /* if request is not for us, try routing it. */ |
921 | else | 916 | else if(route_packet(packet + 1, packet, length) == length) |
922 | if(route_packet(packet + 1, packet, length) == length) | 917 | return 0; |
923 | return 0; | ||
924 | return 0; | 918 | return 0; |
925 | } | 919 | } |
926 | 920 | ||
@@ -933,7 +927,7 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) | |||
933 | IP zero = {{0}}; | 927 | IP zero = {{0}}; |
934 | if(len > MAX_FRIEND_CLIENTS) | 928 | if(len > MAX_FRIEND_CLIENTS) |
935 | return zero; | 929 | return zero; |
936 | 930 | ||
937 | uint32_t i, j; | 931 | uint32_t i, j; |
938 | uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; | 932 | uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; |
939 | for(i = 0; i < len; ++i) { | 933 | for(i = 0; i < len; ++i) { |
@@ -998,8 +992,7 @@ static void doNAT() | |||
998 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ | 992 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ |
999 | friends_list[i].NATping_timestamp = temp_time; | 993 | friends_list[i].NATping_timestamp = temp_time; |
1000 | } | 994 | } |
1001 | } | 995 | } else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) { |
1002 | else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) { | ||
1003 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); | 996 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); |
1004 | if(ip.i == 0) | 997 | if(ip.i == 0) |
1005 | continue; | 998 | continue; |
@@ -1020,23 +1013,23 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | |||
1020 | { | 1013 | { |
1021 | switch (packet[0]) { | 1014 | switch (packet[0]) { |
1022 | case 0: | 1015 | case 0: |
1023 | return handle_pingreq(packet, length, source); | 1016 | return handle_pingreq(packet, length, source); |
1024 | 1017 | ||
1025 | case 1: | 1018 | case 1: |
1026 | return handle_pingres(packet, length, source); | 1019 | return handle_pingres(packet, length, source); |
1027 | 1020 | ||
1028 | case 2: | 1021 | case 2: |
1029 | return handle_getnodes(packet, length, source); | 1022 | return handle_getnodes(packet, length, source); |
1030 | 1023 | ||
1031 | case 3: | 1024 | case 3: |
1032 | return handle_sendnodes(packet, length, source); | 1025 | return handle_sendnodes(packet, length, source); |
1033 | 1026 | ||
1034 | case 254: | 1027 | case 254: |
1035 | return handle_NATping(packet, length, source); | 1028 | return handle_NATping(packet, length, source); |
1036 | 1029 | ||
1037 | default: | 1030 | default: |
1038 | return 1; | 1031 | return 1; |
1039 | 1032 | ||
1040 | } | 1033 | } |
1041 | 1034 | ||
1042 | return 0; | 1035 | return 0; |
@@ -1074,17 +1067,17 @@ int DHT_load(uint8_t * data, uint32_t size) | |||
1074 | uint32_t i, j; | 1067 | uint32_t i, j; |
1075 | /* uint32_t temp_time = unix_time(); */ | 1068 | /* uint32_t temp_time = unix_time(); */ |
1076 | uint16_t temp; | 1069 | uint16_t temp; |
1077 | 1070 | ||
1078 | temp = (size - sizeof(close_clientlist))/sizeof(Friend); | 1071 | temp = (size - sizeof(close_clientlist))/sizeof(Friend); |
1079 | 1072 | ||
1080 | if(temp != 0) { | 1073 | if(temp != 0) { |
1081 | Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); | 1074 | Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); |
1082 | 1075 | ||
1083 | for(i = 0; i < temp; ++i) { | 1076 | for(i = 0; i < temp; ++i) { |
1084 | DHT_addfriend(tempfriends_list[i].client_id); | 1077 | DHT_addfriend(tempfriends_list[i].client_id); |
1085 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) | 1078 | for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) |
1086 | if(tempfriends_list[i].client_list[j].timestamp != 0) { | 1079 | if(tempfriends_list[i].client_list[j].timestamp != 0) { |
1087 | getnodes(tempfriends_list[i].client_list[j].ip_port, | 1080 | getnodes(tempfriends_list[i].client_list[j].ip_port, |
1088 | tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); | 1081 | tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); |
1089 | } | 1082 | } |
1090 | } | 1083 | } |
@@ -1,7 +1,7 @@ | |||
1 | /* DHT.h | 1 | /* DHT.h |
2 | * | 2 | * |
3 | * An implementation of the DHT as seen in docs/DHT.txt | 3 | * An implementation of the DHT as seen in docs/DHT.txt |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,11 +18,11 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef DHT_H | 24 | #ifndef DHT_H |
25 | #define DHT_H | 25 | #define DHT_H |
26 | 26 | ||
27 | #include "net_crypto.h" | 27 | #include "net_crypto.h" |
28 | 28 | ||
@@ -30,79 +30,79 @@ | |||
30 | extern "C" { | 30 | extern "C" { |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | /* Current time, unix format */ | 33 | /* Current time, unix format */ |
34 | #define unix_time() ((uint32_t)time(NULL)) | 34 | #define unix_time() ((uint32_t)time(NULL)) |
35 | 35 | ||
36 | /* size of the client_id in bytes */ | 36 | /* size of the client_id in bytes */ |
37 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES | 37 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES |
38 | 38 | ||
39 | /* Add a new friend to the friends list | 39 | /* Add a new friend to the friends list |
40 | client_id must be CLIENT_ID_SIZE bytes long. | 40 | client_id must be CLIENT_ID_SIZE bytes long. |
41 | returns 0 if success | 41 | returns 0 if success |
42 | returns 1 if failure (friends list is full) */ | 42 | returns 1 if failure (friends list is full) */ |
43 | int DHT_addfriend(uint8_t *client_id); | 43 | int DHT_addfriend(uint8_t *client_id); |
44 | 44 | ||
45 | /* Delete a friend from the friends list | 45 | /* Delete a friend from the friends list |
46 | client_id must be CLIENT_ID_SIZE bytes long. | 46 | client_id must be CLIENT_ID_SIZE bytes long. |
47 | returns 0 if success | 47 | returns 0 if success |
48 | returns 1 if failure (client_id not in friends list) */ | 48 | returns 1 if failure (client_id not in friends list) */ |
49 | int DHT_delfriend(uint8_t *client_id); | 49 | int DHT_delfriend(uint8_t *client_id); |
50 | 50 | ||
51 | /* Get ip of friend | 51 | /* Get ip of friend |
52 | client_id must be CLIENT_ID_SIZE bytes long. | 52 | client_id must be CLIENT_ID_SIZE bytes long. |
53 | ip must be 4 bytes long. | 53 | ip must be 4 bytes long. |
54 | port must be 2 bytes long. | 54 | port must be 2 bytes long. |
55 | returns ip if success | 55 | returns ip if success |
56 | returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) | 56 | returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) |
57 | returns ip of 1 if friend is not in list. */ | 57 | returns ip of 1 if friend is not in list. */ |
58 | IP_Port DHT_getfriendip(uint8_t *client_id); | 58 | IP_Port DHT_getfriendip(uint8_t *client_id); |
59 | 59 | ||
60 | /* Run this function at least a couple times per second (It's the main loop) */ | 60 | /* Run this function at least a couple times per second (It's the main loop) */ |
61 | void doDHT(); | 61 | void doDHT(); |
62 | 62 | ||
63 | /* if we receive a DHT packet we call this function so it can be handled. | 63 | /* if we receive a DHT packet we call this function so it can be handled. |
64 | return 0 if packet is handled correctly. | 64 | return 0 if packet is handled correctly. |
65 | return 1 if it didn't handle the packet or if the packet was shit. */ | 65 | return 1 if it didn't handle the packet or if the packet was shit. */ |
66 | int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 66 | int DHT_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); |
67 | 67 | ||
68 | /* Use this function to bootstrap the client | 68 | /* Use this function to bootstrap the client |
69 | Sends a get nodes request to the given node with ip port and public_key */ | 69 | Sends a get nodes request to the given node with ip port and public_key */ |
70 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); | 70 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); |
71 | 71 | ||
72 | /* ROUTING FUNCTIONS */ | 72 | /* ROUTING FUNCTIONS */ |
73 | 73 | ||
74 | /* send the given packet to node with client_id | 74 | /* send the given packet to node with client_id |
75 | returns -1 if failure */ | 75 | returns -1 if failure */ |
76 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length); | 76 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length); |
77 | 77 | ||
78 | /* Send the following packet to everyone who tells us they are connected to friend_id | 78 | /* Send the following packet to everyone who tells us they are connected to friend_id |
79 | returns the number of nodes it sent the packet to */ | 79 | returns the number of nodes it sent the packet to */ |
80 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); | 80 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); |
81 | 81 | ||
82 | /* NAT PUNCHING FUNCTIONS */ | 82 | /* NAT PUNCHING FUNCTIONS */ |
83 | 83 | ||
84 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist | 84 | /* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist |
85 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | 85 | ip_portlist must be at least MAX_FRIEND_CLIENTS big |
86 | returns the number of ips returned | 86 | returns the number of ips returned |
87 | returns -1 if no such friend*/ | 87 | returns -1 if no such friend*/ |
88 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id); | 88 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id); |
89 | 89 | ||
90 | /* SAVE/LOAD functions */ | 90 | /* SAVE/LOAD functions */ |
91 | 91 | ||
92 | /* get the size of the DHT (for saving) */ | 92 | /* get the size of the DHT (for saving) */ |
93 | uint32_t DHT_size(); | 93 | uint32_t DHT_size(); |
94 | 94 | ||
95 | /* save the DHT in data where data is an array of size DHT_size() */ | 95 | /* save the DHT in data where data is an array of size DHT_size() */ |
96 | void DHT_save(uint8_t *data); | 96 | void DHT_save(uint8_t *data); |
97 | 97 | ||
98 | /* load the DHT from data of size size; | 98 | /* load the DHT from data of size size; |
99 | return -1 if failure | 99 | return -1 if failure |
100 | return 0 if success */ | 100 | return 0 if success */ |
101 | int DHT_load(uint8_t *data, uint32_t size); | 101 | int DHT_load(uint8_t *data, uint32_t size); |
102 | 102 | ||
103 | /* returns 0 if we are not connected to the DHT | 103 | /* returns 0 if we are not connected to the DHT |
104 | returns 1 if we are */ | 104 | returns 1 if we are */ |
105 | int DHT_isconnected(); | 105 | int DHT_isconnected(); |
106 | 106 | ||
107 | #ifdef __cplusplus | 107 | #ifdef __cplusplus |
108 | } | 108 | } |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index 1ac13c33..0a23914d 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* LAN_discovery.c | 1 | /* LAN_discovery.c |
2 | * | 2 | * |
3 | * LAN discovery implementation. | 3 | * LAN discovery implementation. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "LAN_discovery.h" | 24 | #include "LAN_discovery.h" |
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h index cca5bd30..3c056ba6 100644 --- a/core/LAN_discovery.h +++ b/core/LAN_discovery.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* LAN_discovery.h | 1 | /* LAN_discovery.h |
2 | * | 2 | * |
3 | * LAN discovery implementation. | 3 | * LAN discovery implementation. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,12 +18,12 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | 24 | ||
25 | #ifndef LAN_DISCOVERY_H | 25 | #ifndef LAN_DISCOVERY_H |
26 | #define LAN_DISCOVERY_H | 26 | #define LAN_DISCOVERY_H |
27 | 27 | ||
28 | 28 | ||
29 | #include "DHT.h" | 29 | #include "DHT.h" |
@@ -32,14 +32,14 @@ | |||
32 | extern "C" { | 32 | extern "C" { |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /*Send a LAN discovery pcaket to the broadcast address with port port*/ | 35 | /*Send a LAN discovery pcaket to the broadcast address with port port*/ |
36 | int send_LANdiscovery(uint16_t port); | 36 | int send_LANdiscovery(uint16_t port); |
37 | 37 | ||
38 | 38 | ||
39 | /* if we receive a packet we call this function so it can be handled. | 39 | /* if we receive a packet we call this function so it can be handled. |
40 | return 0 if packet is handled correctly. | 40 | return 0 if packet is handled correctly. |
41 | return 1 if it didn't handle the packet or if the packet was shit. */ | 41 | return 1 if it didn't handle the packet or if the packet was shit. */ |
42 | int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 42 | int LANdiscovery_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); |
43 | 43 | ||
44 | 44 | ||
45 | 45 | ||
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index f9d20b2f..0194375a 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Lossless_UDP.c | 1 | /* Lossless_UDP.c |
2 | * | 2 | * |
3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt | 3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* TODO: clean this file a bit. | 24 | /* TODO: clean this file a bit. |
@@ -47,18 +47,18 @@ timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION | |||
47 | typedef struct { | 47 | typedef struct { |
48 | uint8_t data[MAX_DATA_SIZE]; | 48 | uint8_t data[MAX_DATA_SIZE]; |
49 | uint16_t size; | 49 | uint16_t size; |
50 | }Data; | 50 | } Data; |
51 | 51 | ||
52 | typedef struct { | 52 | typedef struct { |
53 | IP_Port ip_port; | 53 | IP_Port ip_port; |
54 | uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, | 54 | uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, |
55 | 2 if handshake is done (we start sending SYNC packets) | 55 | 2 if handshake is done (we start sending SYNC packets) |
56 | 3 if we are sending SYNC packets and can send data | 56 | 3 if we are sending SYNC packets and can send data |
57 | 4 if the connection has timed out. */ | 57 | 4 if the connection has timed out. */ |
58 | 58 | ||
59 | uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. | 59 | uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. |
60 | 2 if incoming_connection() has not returned it yet, 1 if it has. */ | 60 | 2 if incoming_connection() has not returned it yet, 1 if it has. */ |
61 | 61 | ||
62 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | 62 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ |
63 | uint16_t data_rate; /* current data packet send rate packets per second. */ | 63 | uint16_t data_rate; /* current data packet send rate packets per second. */ |
64 | uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ | 64 | uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ |
@@ -82,7 +82,7 @@ typedef struct { | |||
82 | uint8_t recv_counter; | 82 | uint8_t recv_counter; |
83 | uint8_t send_counter; | 83 | uint8_t send_counter; |
84 | uint8_t timeout; /* connection timeout in seconds. */ | 84 | uint8_t timeout; /* connection timeout in seconds. */ |
85 | }Connection; | 85 | } Connection; |
86 | 86 | ||
87 | #define MAX_CONNECTIONS 256 | 87 | #define MAX_CONNECTIONS 256 |
88 | 88 | ||
@@ -95,10 +95,11 @@ static Connection connections[MAX_CONNECTIONS]; | |||
95 | /* get connection id from IP_Port | 95 | /* get connection id from IP_Port |
96 | return -1 if there are no connections like we are looking for | 96 | return -1 if there are no connections like we are looking for |
97 | return id if it found it */ | 97 | return id if it found it */ |
98 | int getconnection_id(IP_Port ip_port) { | 98 | int getconnection_id(IP_Port ip_port) |
99 | { | ||
99 | uint32_t i; | 100 | uint32_t i; |
100 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 101 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
101 | if (connections[i].ip_port.ip.i == ip_port.ip.i && | 102 | if (connections[i].ip_port.ip.i == ip_port.ip.i && |
102 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) | 103 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) |
103 | return i; | 104 | return i; |
104 | } | 105 | } |
@@ -384,10 +385,10 @@ int send_data_packet(uint32_t connection_id, uint32_t packet_num) | |||
384 | packet[0] = 18; | 385 | packet[0] = 18; |
385 | temp = htonl(packet_num); | 386 | temp = htonl(packet_num); |
386 | memcpy(packet + 1, &temp, 4); | 387 | memcpy(packet + 1, &temp, 4); |
387 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, | 388 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, |
388 | connections[connection_id].sendbuffer[index].size); | 389 | connections[connection_id].sendbuffer[index].size); |
389 | return sendpacket(connections[connection_id].ip_port, packet, | 390 | return sendpacket(connections[connection_id].ip_port, packet, |
390 | 1 + 4 + connections[connection_id].sendbuffer[index].size); | 391 | 1 + 4 + connections[connection_id].sendbuffer[index].size); |
391 | } | 392 | } |
392 | 393 | ||
393 | /* sends 1 data packet */ | 394 | /* sends 1 data packet */ |
@@ -395,7 +396,7 @@ int send_DATA(uint32_t connection_id) | |||
395 | { | 396 | { |
396 | int ret; | 397 | int ret; |
397 | uint32_t buffer[BUFFER_PACKET_NUM]; | 398 | uint32_t buffer[BUFFER_PACKET_NUM]; |
398 | if (connections[connection_id].num_req_paquets > 0) { | 399 | if (connections[connection_id].num_req_paquets > 0) { |
399 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); | 400 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); |
400 | connections[connection_id].num_req_paquets--; | 401 | connections[connection_id].num_req_paquets--; |
401 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); | 402 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); |
@@ -416,9 +417,9 @@ int send_DATA(uint32_t connection_id) | |||
416 | One to handle each type of packets we receive | 417 | One to handle each type of packets we receive |
417 | return 0 if handled correctly, 1 if packet is bad. */ | 418 | return 0 if handled correctly, 1 if packet is bad. */ |
418 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 419 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) |
419 | { | 420 | { |
420 | if (length != (1 + 4 + 4)) | 421 | if (length != (1 + 4 + 4)) |
421 | return 1; | 422 | return 1; |
422 | uint32_t temp; | 423 | uint32_t temp; |
423 | uint32_t handshake_id1, handshake_id2; | 424 | uint32_t handshake_id1, handshake_id2; |
424 | int connection = getconnection_id(source); | 425 | int connection = getconnection_id(source); |
@@ -426,7 +427,7 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | |||
426 | handshake_id1 = ntohl(temp); | 427 | handshake_id1 = ntohl(temp); |
427 | memcpy(&temp, packet + 5, 4); | 428 | memcpy(&temp, packet + 5, 4); |
428 | handshake_id2 = ntohl(temp); | 429 | handshake_id2 = ntohl(temp); |
429 | 430 | ||
430 | if (handshake_id2 == 0) { | 431 | if (handshake_id2 == 0) { |
431 | send_handshake(source, handshake_id(source), handshake_id1); | 432 | send_handshake(source, handshake_id(source), handshake_id1); |
432 | return 0; | 433 | return 0; |
@@ -452,7 +453,7 @@ int SYNC_valid(uint32_t length) | |||
452 | { | 453 | { |
453 | if (length < 4 + 4 + 2) | 454 | if (length < 4 + 4 + 2) |
454 | return 0; | 455 | return 0; |
455 | if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || | 456 | if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || |
456 | ((length - 4 - 4 - 2) % 4) != 0) | 457 | ((length - 4 - 4 - 2) % 4) != 0) |
457 | return 0; | 458 | return 0; |
458 | return 1; | 459 | return 1; |
@@ -482,7 +483,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
482 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 483 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
483 | { | 484 | { |
484 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { | 485 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { |
485 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ | 486 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ |
486 | connections[connection_id].status = 3; | 487 | connections[connection_id].status = 3; |
487 | connections[connection_id].recv_counter = counter; | 488 | connections[connection_id].recv_counter = counter; |
488 | ++connections[connection_id].send_counter; | 489 | ++connections[connection_id].send_counter; |
@@ -522,14 +523,14 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | |||
522 | { | 523 | { |
523 | 524 | ||
524 | if (!SYNC_valid(length)) | 525 | if (!SYNC_valid(length)) |
525 | return 1; | 526 | return 1; |
526 | int connection = getconnection_id(source); | 527 | int connection = getconnection_id(source); |
527 | uint8_t counter; | 528 | uint8_t counter; |
528 | uint32_t temp; | 529 | uint32_t temp; |
529 | uint32_t recv_packetnum, sent_packetnum; | 530 | uint32_t recv_packetnum, sent_packetnum; |
530 | uint32_t req_packets[BUFFER_PACKET_NUM]; | 531 | uint32_t req_packets[BUFFER_PACKET_NUM]; |
531 | uint16_t number = (length - 4 - 4 - 2)/ 4; | 532 | uint16_t number = (length - 4 - 4 - 2)/ 4; |
532 | 533 | ||
533 | memcpy(&counter, packet + 1, 1); | 534 | memcpy(&counter, packet + 1, 1); |
534 | memcpy(&temp, packet + 2, 4); | 535 | memcpy(&temp, packet + 2, 4); |
535 | recv_packetnum = ntohl(temp); | 536 | recv_packetnum = ntohl(temp); |
@@ -556,7 +557,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | |||
556 | uint32_t i; | 557 | uint32_t i; |
557 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 558 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
558 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 559 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; |
559 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 560 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
560 | if (i == data_num) { | 561 | if (i == data_num) { |
561 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 562 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
562 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 563 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
@@ -568,7 +569,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | |||
568 | } | 569 | } |
569 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 570 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
570 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 571 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
571 | connections[connection_id].recv_packetnum = i; | 572 | connections[connection_id].recv_packetnum = i; |
572 | else | 573 | else |
573 | break; | 574 | break; |
574 | } | 575 | } |
@@ -603,15 +604,15 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | |||
603 | { | 604 | { |
604 | switch (packet[0]) { //TODO: check if no break statement is correct??? | 605 | switch (packet[0]) { //TODO: check if no break statement is correct??? |
605 | case 16: | 606 | case 16: |
606 | return handle_handshake(packet, length, source); | 607 | return handle_handshake(packet, length, source); |
607 | 608 | ||
608 | case 17: | 609 | case 17: |
609 | return handle_SYNC(packet, length, source); | 610 | return handle_SYNC(packet, length, source); |
610 | 611 | ||
611 | case 18: | 612 | case 18: |
612 | return handle_data(packet, length, source); | 613 | return handle_data(packet, length, source); |
613 | 614 | ||
614 | default: | 615 | default: |
615 | return 1; | 616 | return 1; |
616 | } | 617 | } |
617 | 618 | ||
@@ -627,13 +628,13 @@ void doNew() | |||
627 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 628 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
628 | if (connections[i].status == 1) | 629 | if (connections[i].status == 1) |
629 | if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { | 630 | if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { |
630 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); | 631 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); |
631 | connections[i].last_sent = temp_time; | 632 | connections[i].last_sent = temp_time; |
632 | } | 633 | } |
633 | 634 | ||
634 | /* kill all timed out connections */ | 635 | /* kill all timed out connections */ |
635 | if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 636 | if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && |
636 | connections[i].status != 4) | 637 | connections[i].status != 4) |
637 | /* kill_connection(i); */ | 638 | /* kill_connection(i); */ |
638 | connections[i].status = 4; | 639 | connections[i].status = 4; |
639 | if (connections[i].status > 0 && connections[i].killat < temp_time) | 640 | if (connections[i].status > 0 && connections[i].killat < temp_time) |
@@ -648,8 +649,8 @@ void doSYNC() | |||
648 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 649 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
649 | if (connections[i].status == 2 || connections[i].status == 3) | 650 | if (connections[i].status == 2 || connections[i].status == 3) |
650 | if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { | 651 | if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { |
651 | send_SYNC(i); | 652 | send_SYNC(i); |
652 | connections[i].last_SYNC = temp_time; | 653 | connections[i].last_SYNC = temp_time; |
653 | } | 654 | } |
654 | } | 655 | } |
655 | } | 656 | } |
@@ -682,10 +683,9 @@ void adjustRates() | |||
682 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 683 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
683 | if (connections[i].status == 3) { | 684 | if (connections[i].status == 3) { |
684 | if (sendqueue(i) != 0) { | 685 | if (sendqueue(i) != 0) { |
685 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; | 686 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; |
686 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 687 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
687 | } | 688 | } else if (connections[i].last_recvdata + 1000000UL > temp_time) |
688 | else if (connections[i].last_recvdata + 1000000UL > temp_time) | ||
689 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 689 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
690 | else | 690 | else |
691 | connections[i].SYNC_rate = SYNC_RATE; | 691 | connections[i].SYNC_rate = SYNC_RATE; |
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h index d27fea79..72214370 100644 --- a/core/Lossless_UDP.h +++ b/core/Lossless_UDP.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Lossless_UDP.h | 1 | /* Lossless_UDP.h |
2 | * | 2 | * |
3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt | 3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,11 +18,11 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef LOSSLESS_UDP_H | 24 | #ifndef LOSSLESS_UDP_H |
25 | #define LOSSLESS_UDP_H | 25 | #define LOSSLESS_UDP_H |
26 | 26 | ||
27 | #include "network.h" | 27 | #include "network.h" |
28 | 28 | ||
@@ -30,74 +30,74 @@ | |||
30 | extern "C" { | 30 | extern "C" { |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | /* maximum length of the data in the data packets */ | 33 | /* maximum length of the data in the data packets */ |
34 | #define MAX_DATA_SIZE 1024 | 34 | #define MAX_DATA_SIZE 1024 |
35 | 35 | ||
36 | /* Functions */ | 36 | /* Functions */ |
37 | 37 | ||
38 | /* initialize a new connection to ip_port | 38 | /* initialize a new connection to ip_port |
39 | returns an integer corresponding to the connection id. | 39 | returns an integer corresponding to the connection id. |
40 | return -1 if it could not initialize the connection. | 40 | return -1 if it could not initialize the connection. |
41 | if there already was an existing connection to that ip_port return its number. */ | 41 | if there already was an existing connection to that ip_port return its number. */ |
42 | int new_connection(IP_Port ip_port); | 42 | int new_connection(IP_Port ip_port); |
43 | 43 | ||
44 | /* get connection id from IP_Port | 44 | /* get connection id from IP_Port |
45 | return -1 if there are no connections like we are looking for | 45 | return -1 if there are no connections like we are looking for |
46 | return id if it found it */ | 46 | return id if it found it */ |
47 | int getconnection_id(IP_Port ip_port); | 47 | int getconnection_id(IP_Port ip_port); |
48 | 48 | ||
49 | /* returns an integer corresponding to the next connection in our imcoming connection list | 49 | /* returns an integer corresponding to the next connection in our imcoming connection list |
50 | return -1 if there are no new incoming connections in the list. */ | 50 | return -1 if there are no new incoming connections in the list. */ |
51 | int incoming_connection(); | 51 | int incoming_connection(); |
52 | 52 | ||
53 | /* return -1 if it could not kill the connection. | 53 | /* return -1 if it could not kill the connection. |
54 | return 0 if killed successfully */ | 54 | return 0 if killed successfully */ |
55 | int kill_connection(int connection_id); | 55 | int kill_connection(int connection_id); |
56 | 56 | ||
57 | /* kill connection in seconds seconds. | 57 | /* kill connection in seconds seconds. |
58 | return -1 if it can not kill the connection. | 58 | return -1 if it can not kill the connection. |
59 | return 0 if it will kill it */ | 59 | return 0 if it will kill it */ |
60 | int kill_connection_in(int connection_id, uint32_t seconds); | 60 | int kill_connection_in(int connection_id, uint32_t seconds); |
61 | 61 | ||
62 | /* returns the ip_port of the corresponding connection. | 62 | /* returns the ip_port of the corresponding connection. |
63 | return 0 if there is no such connection. */ | 63 | return 0 if there is no such connection. */ |
64 | IP_Port connection_ip(int connection_id); | 64 | IP_Port connection_ip(int connection_id); |
65 | 65 | ||
66 | /* returns the id of the next packet in the queue | 66 | /* returns the id of the next packet in the queue |
67 | return -1 if no packet in queue */ | 67 | return -1 if no packet in queue */ |
68 | char id_packet(int connection_id); | 68 | char id_packet(int connection_id); |
69 | 69 | ||
70 | /* return 0 if there is no received data in the buffer. | 70 | /* return 0 if there is no received data in the buffer. |
71 | return length of received packet if successful */ | 71 | return length of received packet if successful */ |
72 | int read_packet(int connection_id, uint8_t *data); | 72 | int read_packet(int connection_id, uint8_t *data); |
73 | 73 | ||
74 | /* return 0 if data could not be put in packet queue | 74 | /* return 0 if data could not be put in packet queue |
75 | return 1 if data was put into the queue */ | 75 | return 1 if data was put into the queue */ |
76 | int write_packet(int connection_id, uint8_t *data, uint32_t length); | 76 | int write_packet(int connection_id, uint8_t *data, uint32_t length); |
77 | 77 | ||
78 | /* returns the number of packets in the queue waiting to be successfully sent. */ | 78 | /* returns the number of packets in the queue waiting to be successfully sent. */ |
79 | uint32_t sendqueue(int connection_id); | 79 | uint32_t sendqueue(int connection_id); |
80 | 80 | ||
81 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ | 81 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ |
82 | uint32_t recvqueue(int connection_id); | 82 | uint32_t recvqueue(int connection_id); |
83 | 83 | ||
84 | /* check if connection is connected | 84 | /* check if connection is connected |
85 | return 0 no. | 85 | return 0 no. |
86 | return 1 if attempting handshake | 86 | return 1 if attempting handshake |
87 | return 2 if handshake is done | 87 | return 2 if handshake is done |
88 | return 3 if fully connected | 88 | return 3 if fully connected |
89 | return 4 if timed out and wating to be killed */ | 89 | return 4 if timed out and wating to be killed */ |
90 | int is_connected(int connection_id); | 90 | int is_connected(int connection_id); |
91 | 91 | ||
92 | /* Call this function a couple times per second | 92 | /* Call this function a couple times per second |
93 | It's the main loop. */ | 93 | It's the main loop. */ |
94 | void doLossless_UDP(); | 94 | void doLossless_UDP(); |
95 | 95 | ||
96 | 96 | ||
97 | /* if we receive a Lossless_UDP packet we call this function so it can be handled. | 97 | /* if we receive a Lossless_UDP packet we call this function so it can be handled. |
98 | return 0 if packet is handled correctly. | 98 | return 0 if packet is handled correctly. |
99 | return 1 if it didn't handle the packet or if the packet was shit. */ | 99 | return 1 if it didn't handle the packet or if the packet was shit. */ |
100 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 100 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); |
101 | 101 | ||
102 | #ifdef __cplusplus | 102 | #ifdef __cplusplus |
103 | } | 103 | } |
diff --git a/core/Messenger.c b/core/Messenger.c index fd95869f..86056df8 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -18,12 +18,12 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "Messenger.h" | 24 | #include "Messenger.h" |
25 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 25 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
26 | 26 | ||
27 | typedef struct { | 27 | typedef struct { |
28 | uint8_t client_id[CLIENT_ID_SIZE]; | 28 | uint8_t client_id[CLIENT_ID_SIZE]; |
29 | int crypt_connection_id; | 29 | int crypt_connection_id; |
@@ -49,7 +49,7 @@ static uint16_t self_userstatus_len; | |||
49 | static Friend friendlist[MAX_NUM_FRIENDS]; | 49 | static Friend friendlist[MAX_NUM_FRIENDS]; |
50 | 50 | ||
51 | static uint32_t numfriends; | 51 | static uint32_t numfriends; |
52 | 52 | ||
53 | /* 1 if we are online | 53 | /* 1 if we are online |
54 | 0 if we are offline | 54 | 0 if we are offline |
55 | static uint8_t online; */ | 55 | static uint8_t online; */ |
@@ -95,7 +95,7 @@ int getclient_id(int friend_id, uint8_t *client_id) | |||
95 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | 95 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) |
96 | { | 96 | { |
97 | if (length == 0 || length >= | 97 | if (length == 0 || length >= |
98 | (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) | 98 | (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) |
99 | return -1; | 99 | return -1; |
100 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | 100 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) |
101 | return -1; | 101 | return -1; |
@@ -113,7 +113,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
113 | friendlist[i].userstatus_length = 1; | 113 | friendlist[i].userstatus_length = 1; |
114 | memcpy(friendlist[i].info, data, length); | 114 | memcpy(friendlist[i].info, data, length); |
115 | friendlist[i].info_size = length; | 115 | friendlist[i].info_size = length; |
116 | 116 | ||
117 | ++numfriends; | 117 | ++numfriends; |
118 | return i; | 118 | return i; |
119 | } | 119 | } |
@@ -183,7 +183,7 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | |||
183 | if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) | 183 | if (friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) |
184 | return 0; | 184 | return 0; |
185 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) | 185 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) |
186 | /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ | 186 | /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ |
187 | return 0; | 187 | return 0; |
188 | uint8_t temp[MAX_DATA_SIZE]; | 188 | uint8_t temp[MAX_DATA_SIZE]; |
189 | temp[0] = PACKET_ID_MESSAGE; | 189 | temp[0] = PACKET_ID_MESSAGE; |
@@ -349,7 +349,8 @@ int initMessenger() | |||
349 | 349 | ||
350 | //TODO: make this function not suck. | 350 | //TODO: make this function not suck. |
351 | static void doFriends() | 351 | static void doFriends() |
352 | {/* TODO: add incoming connections and some other stuff. */ | 352 | { |
353 | /* TODO: add incoming connections and some other stuff. */ | ||
353 | uint32_t i; | 354 | uint32_t i; |
354 | int len; | 355 | int len; |
355 | uint8_t temp[MAX_DATA_SIZE]; | 356 | uint8_t temp[MAX_DATA_SIZE]; |
@@ -370,19 +371,19 @@ static void doFriends() | |||
370 | } | 371 | } |
371 | IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); | 372 | IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); |
372 | switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) { | 373 | switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) { |
373 | case 0: | 374 | case 0: |
374 | if (friendip.ip.i > 1) | 375 | if (friendip.ip.i > 1) |
375 | friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); | 376 | friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); |
376 | break; | 377 | break; |
377 | case 3: /* Connection is established */ | 378 | case 3: /* Connection is established */ |
378 | friendlist[i].status = 4; | 379 | friendlist[i].status = 4; |
379 | break; | 380 | break; |
380 | case 4: | 381 | case 4: |
381 | crypto_kill(friendlist[i].crypt_connection_id); | 382 | crypto_kill(friendlist[i].crypt_connection_id); |
382 | friendlist[i].crypt_connection_id = -1; | 383 | friendlist[i].crypt_connection_id = -1; |
383 | break; | 384 | break; |
384 | default: | 385 | default: |
385 | break; | 386 | break; |
386 | } | 387 | } |
387 | } | 388 | } |
388 | while (friendlist[i].status == 4) { /* friend is online */ | 389 | while (friendlist[i].status == 4) { /* friend is online */ |
@@ -397,38 +398,37 @@ static void doFriends() | |||
397 | len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); | 398 | len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); |
398 | if (len > 0) { | 399 | if (len > 0) { |
399 | switch (temp[0]) { | 400 | switch (temp[0]) { |
400 | case PACKET_ID_NICKNAME: { | 401 | case PACKET_ID_NICKNAME: { |
401 | if (len != MAX_NAME_LENGTH + 1) | 402 | if (len != MAX_NAME_LENGTH + 1) |
402 | break; | ||
403 | if(friend_namechange_isset) | ||
404 | friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */ | ||
405 | memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH); | ||
406 | friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */ | ||
407 | break; | 403 | break; |
408 | } | 404 | if(friend_namechange_isset) |
409 | case PACKET_ID_USERSTATUS: { | 405 | friend_namechange(i, temp + 1, MAX_NAME_LENGTH); /* TODO: use the actual length */ |
410 | uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1); | 406 | memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH); |
411 | memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH)); | 407 | friendlist[i].name[MAX_NAME_LENGTH - 1] = 0; /* make sure the NULL terminator is present. */ |
412 | if (friend_statuschange_isset) | 408 | break; |
413 | friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); | ||
414 | set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); | ||
415 | free(status); | ||
416 | break; | ||
417 | } | ||
418 | case PACKET_ID_MESSAGE: { | ||
419 | if (friend_message_isset) | ||
420 | (*friend_message)(i, temp + 1, len - 1); | ||
421 | break; | ||
422 | } | ||
423 | } | 409 | } |
424 | } | 410 | case PACKET_ID_USERSTATUS: { |
425 | else { | 411 | uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1); |
426 | if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ | 412 | memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH)); |
427 | crypto_kill(friendlist[i].crypt_connection_id); | 413 | if (friend_statuschange_isset) |
428 | friendlist[i].crypt_connection_id = -1; | 414 | friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); |
429 | friendlist[i].status = 3; | 415 | set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); |
430 | } | 416 | free(status); |
431 | break; | 417 | break; |
418 | } | ||
419 | case PACKET_ID_MESSAGE: { | ||
420 | if (friend_message_isset) | ||
421 | (*friend_message)(i, temp + 1, len - 1); | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | } else { | ||
426 | if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ | ||
427 | crypto_kill(friendlist[i].crypt_connection_id); | ||
428 | friendlist[i].crypt_connection_id = -1; | ||
429 | friendlist[i].status = 3; | ||
430 | } | ||
431 | break; | ||
432 | } | 432 | } |
433 | } | 433 | } |
434 | } | 434 | } |
@@ -443,11 +443,11 @@ static void doInbound() | |||
443 | if (inconnection != -1) { | 443 | if (inconnection != -1) { |
444 | int friend_id = getfriend_id(public_key); | 444 | int friend_id = getfriend_id(public_key); |
445 | if (friend_id != -1) { | 445 | if (friend_id != -1) { |
446 | crypto_kill(friendlist[friend_id].crypt_connection_id); | 446 | crypto_kill(friendlist[friend_id].crypt_connection_id); |
447 | friendlist[friend_id].crypt_connection_id = | 447 | friendlist[friend_id].crypt_connection_id = |
448 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); | 448 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); |
449 | 449 | ||
450 | friendlist[friend_id].status = 3; | 450 | friendlist[friend_id].status = 3; |
451 | } | 451 | } |
452 | } | 452 | } |
453 | } | 453 | } |
@@ -477,8 +477,8 @@ void doMessenger() | |||
477 | #ifdef DEBUG | 477 | #ifdef DEBUG |
478 | /* if(rand() % 3 != 1) //simulate packet loss */ | 478 | /* if(rand() % 3 != 1) //simulate packet loss */ |
479 | /* { */ | 479 | /* { */ |
480 | if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && | 480 | if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && |
481 | friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port)) | 481 | friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port)) |
482 | /* if packet is discarded */ | 482 | /* if packet is discarded */ |
483 | printf("Received unhandled packet with length: %u\n", length); | 483 | printf("Received unhandled packet with length: %u\n", length); |
484 | else | 484 | else |
@@ -505,7 +505,7 @@ void doMessenger() | |||
505 | uint32_t Messenger_size() | 505 | uint32_t Messenger_size() |
506 | { | 506 | { |
507 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES | 507 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES |
508 | + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends; | 508 | + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends; |
509 | } | 509 | } |
510 | 510 | ||
511 | /* save the messenger in data of size Messenger_size() */ | 511 | /* save the messenger in data of size Messenger_size() */ |
@@ -537,7 +537,7 @@ int Messenger_load(uint8_t * data, uint32_t length) | |||
537 | uint32_t size; | 537 | uint32_t size; |
538 | memcpy(&size, data, sizeof(size)); | 538 | memcpy(&size, data, sizeof(size)); |
539 | data += sizeof(size); | 539 | data += sizeof(size); |
540 | 540 | ||
541 | if (length < size) | 541 | if (length < size) |
542 | return -1; | 542 | return -1; |
543 | length -= size; | 543 | length -= size; |
@@ -548,12 +548,12 @@ int Messenger_load(uint8_t * data, uint32_t length) | |||
548 | data += sizeof(size); | 548 | data += sizeof(size); |
549 | if (length != size || length % sizeof(Friend) != 0) | 549 | if (length != size || length % sizeof(Friend) != 0) |
550 | return -1; | 550 | return -1; |
551 | 551 | ||
552 | Friend * temp = malloc(size); | 552 | Friend * temp = malloc(size); |
553 | memcpy(temp, data, size); | 553 | memcpy(temp, data, size); |
554 | 554 | ||
555 | uint16_t num = size / sizeof(Friend); | 555 | uint16_t num = size / sizeof(Friend); |
556 | 556 | ||
557 | uint32_t i; | 557 | uint32_t i; |
558 | for (i = 0; i < num; ++i) { | 558 | for (i = 0; i < num; ++i) { |
559 | if(temp[i].status != 0) { | 559 | if(temp[i].status != 0) { |
diff --git a/core/Messenger.h b/core/Messenger.h index 0e2606d9..3cdeeb93 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * An implementation of a simple text chat only messenger on the tox network core. | 3 | * An implementation of a simple text chat only messenger on the tox network core. |
4 | * | 4 | * |
5 | * NOTE: All the text in the messages must be encoded using UTF-8 | 5 | * NOTE: All the text in the messages must be encoded using UTF-8 |
6 | * | 6 | * |
7 | * Copyright (C) 2013 Tox project All Rights Reserved. | 7 | * Copyright (C) 2013 Tox project All Rights Reserved. |
8 | * | 8 | * |
9 | * This file is part of Tox. | 9 | * This file is part of Tox. |
@@ -20,8 +20,8 @@ | |||
20 | * | 20 | * |
21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
22 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 22 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #ifndef MESSENGER_H | 26 | #ifndef MESSENGER_H |
27 | #define MESSENGER_H | 27 | #define MESSENGER_H |
@@ -42,111 +42,111 @@ extern "C" { | |||
42 | #define PACKET_ID_USERSTATUS 49 | 42 | #define PACKET_ID_USERSTATUS 49 |
43 | #define PACKET_ID_MESSAGE 64 | 43 | #define PACKET_ID_MESSAGE 64 |
44 | 44 | ||
45 | /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased | 45 | /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased |
46 | to an absurdly large number later */ | 46 | to an absurdly large number later */ |
47 | 47 | ||
48 | /* add a friend | 48 | /* add a friend |
49 | set the data that will be sent along with friend request | 49 | set the data that will be sent along with friend request |
50 | client_id is the client id of the friend | 50 | client_id is the client id of the friend |
51 | data is the data and length is the length | 51 | data is the data and length is the length |
52 | returns the friend number if success | 52 | returns the friend number if success |
53 | return -1 if failure. */ | 53 | return -1 if failure. */ |
54 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); | 54 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); |
55 | 55 | ||
56 | 56 | ||
57 | /* add a friend without sending a friendrequest. | 57 | /* add a friend without sending a friendrequest. |
58 | returns the friend number if success | 58 | returns the friend number if success |
59 | return -1 if failure. */ | 59 | return -1 if failure. */ |
60 | int m_addfriend_norequest(uint8_t *client_id); | 60 | int m_addfriend_norequest(uint8_t *client_id); |
61 | 61 | ||
62 | /* return the friend id associated to that client id. | 62 | /* return the friend id associated to that client id. |
63 | return -1 if no such friend */ | 63 | return -1 if no such friend */ |
64 | int getfriend_id(uint8_t *client_id); | 64 | int getfriend_id(uint8_t *client_id); |
65 | 65 | ||
66 | /* copies the public key associated to that friend id into client_id buffer. | 66 | /* copies the public key associated to that friend id into client_id buffer. |
67 | make sure that client_id is of size CLIENT_ID_SIZE. | 67 | make sure that client_id is of size CLIENT_ID_SIZE. |
68 | return 0 if success | 68 | return 0 if success |
69 | return -1 if failure */ | 69 | return -1 if failure */ |
70 | int getclient_id(int friend_id, uint8_t *client_id); | 70 | int getclient_id(int friend_id, uint8_t *client_id); |
71 | 71 | ||
72 | /* remove a friend */ | 72 | /* remove a friend */ |
73 | int m_delfriend(int friendnumber); | 73 | int m_delfriend(int friendnumber); |
74 | 74 | ||
75 | /* return 4 if friend is online | 75 | /* return 4 if friend is online |
76 | return 3 if friend is confirmed | 76 | return 3 if friend is confirmed |
77 | return 2 if the friend request was sent | 77 | return 2 if the friend request was sent |
78 | return 1 if the friend was added | 78 | return 1 if the friend was added |
79 | return 0 if there is no friend with that number */ | 79 | return 0 if there is no friend with that number */ |
80 | int m_friendstatus(int friendnumber); | 80 | int m_friendstatus(int friendnumber); |
81 | 81 | ||
82 | /* send a text chat message to an online friend | 82 | /* send a text chat message to an online friend |
83 | returns 1 if packet was successfully put into the send queue | 83 | returns 1 if packet was successfully put into the send queue |
84 | return 0 if it was not */ | 84 | return 0 if it was not */ |
85 | int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); | 85 | int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); |
86 | 86 | ||
87 | /* Set our nickname | 87 | /* Set our nickname |
88 | name must be a string of maximum MAX_NAME_LENGTH length. | 88 | name must be a string of maximum MAX_NAME_LENGTH length. |
89 | return 0 if success | 89 | return 0 if success |
90 | return -1 if failure */ | 90 | return -1 if failure */ |
91 | int setname(uint8_t *name, uint16_t length); | 91 | int setname(uint8_t *name, uint16_t length); |
92 | 92 | ||
93 | /* get name of friendnumber | 93 | /* get name of friendnumber |
94 | put it in name | 94 | put it in name |
95 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. | 95 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. |
96 | return 0 if success | 96 | return 0 if success |
97 | return -1 if failure */ | 97 | return -1 if failure */ |
98 | int getname(int friendnumber, uint8_t *name); | 98 | int getname(int friendnumber, uint8_t *name); |
99 | 99 | ||
100 | /* set our user status | 100 | /* set our user status |
101 | you are responsible for freeing status after | 101 | you are responsible for freeing status after |
102 | returns 0 on success, -1 on failure */ | 102 | returns 0 on success, -1 on failure */ |
103 | int m_set_userstatus(uint8_t *status, uint16_t length); | 103 | int m_set_userstatus(uint8_t *status, uint16_t length); |
104 | 104 | ||
105 | /* return the length of friendnumber's user status, | 105 | /* return the length of friendnumber's user status, |
106 | including null | 106 | including null |
107 | pass it into malloc */ | 107 | pass it into malloc */ |
108 | int m_get_userstatus_size(int friendnumber); | 108 | int m_get_userstatus_size(int friendnumber); |
109 | 109 | ||
110 | /* copy friendnumber's userstatus into buf, truncating if size is over maxlen | 110 | /* copy friendnumber's userstatus into buf, truncating if size is over maxlen |
111 | get the size you need to allocate from m_get_userstatus_size */ | 111 | get the size you need to allocate from m_get_userstatus_size */ |
112 | int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen); | 112 | int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen); |
113 | 113 | ||
114 | /* set the function that will be executed when a friend request is received. | 114 | /* set the function that will be executed when a friend request is received. |
115 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ | 115 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ |
116 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); | 116 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); |
117 | 117 | ||
118 | /* set the function that will be executed when a message from a friend is received. | 118 | /* set the function that will be executed when a message from a friend is received. |
119 | function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ | 119 | function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ |
120 | void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); | 120 | void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); |
121 | 121 | ||
122 | /* set the callback for name changes | 122 | /* set the callback for name changes |
123 | function(int friendnumber, uint8_t *newname, uint16_t length) | 123 | function(int friendnumber, uint8_t *newname, uint16_t length) |
124 | you are not responsible for freeing newname */ | 124 | you are not responsible for freeing newname */ |
125 | void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); | 125 | void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); |
126 | 126 | ||
127 | /* set the callback for user status changes | 127 | /* set the callback for user status changes |
128 | function(int friendnumber, uint8_t *newstatus, uint16_t length) | 128 | function(int friendnumber, uint8_t *newstatus, uint16_t length) |
129 | you are not responsible for freeing newstatus */ | 129 | you are not responsible for freeing newstatus */ |
130 | void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t)); | 130 | void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t)); |
131 | 131 | ||
132 | /* run this at startup | 132 | /* run this at startup |
133 | returns 0 if no connection problems | 133 | returns 0 if no connection problems |
134 | returns -1 if there are problems */ | 134 | returns -1 if there are problems */ |
135 | int initMessenger(); | 135 | int initMessenger(); |
136 | 136 | ||
137 | /* the main loop that needs to be run at least 200 times per second */ | 137 | /* the main loop that needs to be run at least 200 times per second */ |
138 | void doMessenger(); | 138 | void doMessenger(); |
139 | 139 | ||
140 | /* SAVING AND LOADING FUNCTIONS: */ | 140 | /* SAVING AND LOADING FUNCTIONS: */ |
141 | 141 | ||
142 | /* returns the size of the messenger data (for saving) */ | 142 | /* returns the size of the messenger data (for saving) */ |
143 | uint32_t Messenger_size(); | 143 | uint32_t Messenger_size(); |
144 | 144 | ||
145 | /* save the messenger in data (must be allocated memory of size Messenger_size()) */ | 145 | /* save the messenger in data (must be allocated memory of size Messenger_size()) */ |
146 | void Messenger_save(uint8_t *data); | 146 | void Messenger_save(uint8_t *data); |
147 | 147 | ||
148 | /* load the messenger from data of size length */ | 148 | /* load the messenger from data of size length */ |
149 | int Messenger_load(uint8_t *data, uint32_t length); | 149 | int Messenger_load(uint8_t *data, uint32_t length); |
150 | 150 | ||
151 | #ifdef __cplusplus | 151 | #ifdef __cplusplus |
152 | } | 152 | } |
diff --git a/core/friend_requests.c b/core/friend_requests.c index 7a2cdc24..f1ffb8d0 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* friend_requests.c | 1 | /* friend_requests.c |
2 | * | 2 | * |
3 | * Handle friend requests. | 3 | * Handle friend requests. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "friend_requests.h" | 24 | #include "friend_requests.h" |
@@ -26,7 +26,7 @@ | |||
26 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 26 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; |
27 | 27 | ||
28 | /* Try to send a friendrequest to peer with public_key | 28 | /* Try to send a friendrequest to peer with public_key |
29 | data is the data in the request and length is the length. | 29 | data is the data in the request and length is the length. |
30 | return -1 if failure. | 30 | return -1 if failure. |
31 | return 0 if it sent the friend request directly to the friend. | 31 | return 0 if it sent the friend request directly to the friend. |
32 | return the number of peers it was routed through if it did not send it directly.*/ | 32 | return the number of peers it was routed through if it did not send it directly.*/ |
@@ -34,7 +34,7 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length) | |||
34 | { | 34 | { |
35 | uint8_t packet[MAX_DATA_SIZE]; | 35 | uint8_t packet[MAX_DATA_SIZE]; |
36 | int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */ | 36 | int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */ |
37 | 37 | ||
38 | if (len == -1) | 38 | if (len == -1) |
39 | return -1; | 39 | return -1; |
40 | 40 | ||
@@ -48,7 +48,7 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length) | |||
48 | return 0; | 48 | return 0; |
49 | return -1; | 49 | return -1; |
50 | } | 50 | } |
51 | 51 | ||
52 | int num = route_tofriend(public_key, packet, len); | 52 | int num = route_tofriend(public_key, packet, len); |
53 | 53 | ||
54 | if (num == 0) | 54 | if (num == 0) |
@@ -61,7 +61,8 @@ static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t); | |||
61 | static uint8_t handle_friendrequest_isset = 0; | 61 | static uint8_t handle_friendrequest_isset = 0; |
62 | 62 | ||
63 | /* set the function that will be executed when a friend request is received. */ | 63 | /* set the function that will be executed when a friend request is received. */ |
64 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) { | 64 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) |
65 | { | ||
65 | handle_friendrequest = function; | 66 | handle_friendrequest = function; |
66 | handle_friendrequest_isset = 1; | 67 | handle_friendrequest_isset = 1; |
67 | } | 68 | } |
@@ -76,17 +77,19 @@ static uint8_t recieved_requests[MAX_RECIEVED_STORED][crypto_box_PUBLICKEYBYTES] | |||
76 | static uint16_t recieved_requests_index; | 77 | static uint16_t recieved_requests_index; |
77 | 78 | ||
78 | /*Add to list of recieved friend requests*/ | 79 | /*Add to list of recieved friend requests*/ |
79 | static void addto_recievedlist(uint8_t * client_id) { | 80 | static void addto_recievedlist(uint8_t * client_id) |
81 | { | ||
80 | if (recieved_requests_index >= MAX_RECIEVED_STORED) | 82 | if (recieved_requests_index >= MAX_RECIEVED_STORED) |
81 | recieved_requests_index = 0; | 83 | recieved_requests_index = 0; |
82 | 84 | ||
83 | memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES); | 85 | memcpy(recieved_requests[recieved_requests_index], client_id, crypto_box_PUBLICKEYBYTES); |
84 | ++recieved_requests_index; | 86 | ++recieved_requests_index; |
85 | } | 87 | } |
86 | 88 | ||
87 | /* Check if a friend request was already recieved | 89 | /* Check if a friend request was already recieved |
88 | return 0 if not, 1 if we did */ | 90 | return 0 if not, 1 if we did */ |
89 | static int request_recieved(uint8_t * client_id) { | 91 | static int request_recieved(uint8_t * client_id) |
92 | { | ||
90 | uint32_t i; | 93 | uint32_t i; |
91 | 94 | ||
92 | for (i = 0; i < MAX_RECIEVED_STORED; ++i) { | 95 | for (i = 0; i < MAX_RECIEVED_STORED; ++i) { |
@@ -98,7 +101,8 @@ static int request_recieved(uint8_t * client_id) { | |||
98 | } | 101 | } |
99 | 102 | ||
100 | 103 | ||
101 | int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) { | 104 | int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) |
105 | { | ||
102 | if (packet[0] == 32) { | 106 | if (packet[0] == 32) { |
103 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 107 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
104 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 108 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
@@ -118,11 +122,10 @@ int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) { | |||
118 | 122 | ||
119 | addto_recievedlist(public_key); | 123 | addto_recievedlist(public_key); |
120 | (*handle_friendrequest)(public_key, data, len); | 124 | (*handle_friendrequest)(public_key, data, len); |
121 | } | 125 | } else { /* if request is not for us, try routing it. */ |
122 | else {/* if request is not for us, try routing it. */ | ||
123 | if(route_packet(packet + 1, packet, length) == length) | 126 | if(route_packet(packet + 1, packet, length) == length) |
124 | return 0; | 127 | return 0; |
125 | } | 128 | } |
126 | } | 129 | } |
127 | return 1; | 130 | return 1; |
128 | } | 131 | } |
diff --git a/core/friend_requests.h b/core/friend_requests.h index 8988403c..e21c2a90 100644 --- a/core/friend_requests.h +++ b/core/friend_requests.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* friend_requests.h | 1 | /* friend_requests.h |
2 | * | 2 | * |
3 | * Handle friend requests. | 3 | * Handle friend requests. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,11 +18,11 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef FRIEND_REQUESTS_H | 24 | #ifndef FRIEND_REQUESTS_H |
25 | #define FRIEND_REQUESTS_H | 25 | #define FRIEND_REQUESTS_H |
26 | 26 | ||
27 | #include "DHT.h" | 27 | #include "DHT.h" |
28 | #include "net_crypto.h" | 28 | #include "net_crypto.h" |
@@ -31,18 +31,18 @@ | |||
31 | extern "C" { | 31 | extern "C" { |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | /* Try to send a friendrequest to peer with public_key | 34 | /* Try to send a friendrequest to peer with public_key |
35 | data is the data in the request and length is the length. */ | 35 | data is the data in the request and length is the length. */ |
36 | int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length); | 36 | int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length); |
37 | 37 | ||
38 | /* set the function that will be executed when a friend request for us is received. | 38 | /* set the function that will be executed when a friend request for us is received. |
39 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ | 39 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ |
40 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); | 40 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); |
41 | 41 | ||
42 | /* if we receive a packet we call this function so it can be handled. | 42 | /* if we receive a packet we call this function so it can be handled. |
43 | return 0 if packet is handled correctly. | 43 | return 0 if packet is handled correctly. |
44 | return 1 if it didn't handle the packet or if the packet was shit. */ | 44 | return 1 if it didn't handle the packet or if the packet was shit. */ |
45 | int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 45 | int friendreq_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); |
46 | 46 | ||
47 | #ifdef __cplusplus | 47 | #ifdef __cplusplus |
48 | } | 48 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index c1571467..a437c5ee 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* net_crypto.c | 1 | /* net_crypto.c |
2 | * | 2 | * |
3 | * Functions for the core network crypto. | 3 | * Functions for the core network crypto. |
4 | * See also: docs/Crypto.txt | 4 | * See also: docs/Crypto.txt |
5 | * | 5 | * |
6 | * NOTE: This code has to be perfect. We don't mess around with encryption. | 6 | * NOTE: This code has to be perfect. We don't mess around with encryption. |
7 | * | 7 | * |
8 | * Copyright (C) 2013 Tox project All Rights Reserved. | 8 | * Copyright (C) 2013 Tox project All Rights Reserved. |
9 | * | 9 | * |
10 | * This file is part of Tox. | 10 | * This file is part of Tox. |
@@ -21,7 +21,7 @@ | |||
21 | * | 21 | * |
22 | * You should have received a copy of the GNU General Public License | 22 | * You should have received a copy of the GNU General Public License |
23 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 23 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "net_crypto.h" | 27 | #include "net_crypto.h" |
@@ -37,11 +37,11 @@ typedef struct { | |||
37 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ | 37 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ |
38 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ | 38 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ |
39 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | 39 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ |
40 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | 40 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet |
41 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 41 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
42 | 4 if the connection is timed out. */ | 42 | 4 if the connection is timed out. */ |
43 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ | 43 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ |
44 | 44 | ||
45 | } Crypto_Connection; | 45 | } Crypto_Connection; |
46 | 46 | ||
47 | #define MAX_CRYPTO_CONNECTIONS 256 | 47 | #define MAX_CRYPTO_CONNECTIONS 256 |
@@ -53,24 +53,24 @@ static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; | |||
53 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | 53 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ |
54 | static int incoming_connections[MAX_INCOMING]; | 54 | static int incoming_connections[MAX_INCOMING]; |
55 | 55 | ||
56 | /* encrypts plain of length length to encrypted of length + 16 using the | 56 | /* encrypts plain of length length to encrypted of length + 16 using the |
57 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 57 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
58 | return -1 if there was a problem. | 58 | return -1 if there was a problem. |
59 | return length of encrypted data if everything was fine. */ | 59 | return length of encrypted data if everything was fine. */ |
60 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 60 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, |
61 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | 61 | uint8_t *plain, uint32_t length, uint8_t *encrypted) |
62 | { | 62 | { |
63 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) | 63 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) |
64 | return -1; | 64 | return -1; |
65 | 65 | ||
66 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; | 66 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; |
67 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; | 67 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; |
68 | uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0}; | 68 | uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0}; |
69 | 69 | ||
70 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ | 70 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ |
71 | 71 | ||
72 | crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); | 72 | crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); |
73 | 73 | ||
74 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ | 74 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ |
75 | if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) | 75 | if (memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) |
76 | return -1; | 76 | return -1; |
@@ -84,8 +84,8 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
84 | public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce | 84 | public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce |
85 | return -1 if there was a problem(decryption failed) | 85 | return -1 if there was a problem(decryption failed) |
86 | return length of plain data if everything was fine. */ | 86 | return length of plain data if everything was fine. */ |
87 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 87 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, |
88 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | 88 | uint8_t *encrypted, uint32_t length, uint8_t *plain) |
89 | { | 89 | { |
90 | if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) | 90 | if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) |
91 | return -1; | 91 | return -1; |
@@ -93,11 +93,11 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | |||
93 | uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; | 93 | uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES]; |
94 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; | 94 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; |
95 | uint8_t zeroes[crypto_box_ZEROBYTES] = {0}; | 95 | uint8_t zeroes[crypto_box_ZEROBYTES] = {0}; |
96 | 96 | ||
97 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ | 97 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ |
98 | 98 | ||
99 | if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, | 99 | if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, |
100 | nonce, public_key, secret_key) == -1) | 100 | nonce, public_key, secret_key) == -1) |
101 | return -1; | 101 | return -1; |
102 | 102 | ||
103 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */ | 103 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */ |
@@ -130,13 +130,13 @@ void random_nonce(uint8_t *nonce) | |||
130 | } | 130 | } |
131 | } | 131 | } |
132 | 132 | ||
133 | /* return 0 if there is no received data in the buffer | 133 | /* return 0 if there is no received data in the buffer |
134 | return -1 if the packet was discarded. | 134 | return -1 if the packet was discarded. |
135 | return length of received data if successful */ | 135 | return length of received data if successful */ |
136 | int read_cryptpacket(int crypt_connection_id, uint8_t *data) | 136 | int read_cryptpacket(int crypt_connection_id, uint8_t *data) |
137 | { | 137 | { |
138 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 138 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) |
139 | return 0; | 139 | return 0; |
140 | if (crypto_connections[crypt_connection_id].status != 3) | 140 | if (crypto_connections[crypt_connection_id].status != 3) |
141 | return 0; | 141 | return 0; |
142 | uint8_t temp_data[MAX_DATA_SIZE]; | 142 | uint8_t temp_data[MAX_DATA_SIZE]; |
@@ -145,7 +145,7 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
145 | return 0; | 145 | return 0; |
146 | if (temp_data[0] != 3) | 146 | if (temp_data[0] != 3) |
147 | return -1; | 147 | return -1; |
148 | int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, | 148 | int len = decrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, |
149 | crypto_connections[crypt_connection_id].sessionsecret_key, | 149 | crypto_connections[crypt_connection_id].sessionsecret_key, |
150 | crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); | 150 | crypto_connections[crypt_connection_id].recv_nonce, temp_data + 1, length - 1, data); |
151 | if (len != -1) { | 151 | if (len != -1) { |
@@ -160,13 +160,13 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
160 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | 160 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) |
161 | { | 161 | { |
162 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 162 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) |
163 | return 0; | 163 | return 0; |
164 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) | 164 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) |
165 | return 0; | 165 | return 0; |
166 | if (crypto_connections[crypt_connection_id].status != 3) | 166 | if (crypto_connections[crypt_connection_id].status != 3) |
167 | return 0; | 167 | return 0; |
168 | uint8_t temp_data[MAX_DATA_SIZE]; | 168 | uint8_t temp_data[MAX_DATA_SIZE]; |
169 | int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, | 169 | int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, |
170 | crypto_connections[crypt_connection_id].sessionsecret_key, | 170 | crypto_connections[crypt_connection_id].sessionsecret_key, |
171 | crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); | 171 | crypto_connections[crypt_connection_id].sent_nonce, data, length, temp_data + 1); |
172 | if (len == -1) | 172 | if (len == -1) |
@@ -190,7 +190,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
190 | return -1; | 190 | return -1; |
191 | uint8_t nonce[crypto_box_NONCEBYTES]; | 191 | uint8_t nonce[crypto_box_NONCEBYTES]; |
192 | random_nonce(nonce); | 192 | random_nonce(nonce); |
193 | int len = encrypt_data(public_key, self_secret_key, nonce, data, length, | 193 | int len = encrypt_data(public_key, self_secret_key, nonce, data, length, |
194 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); | 194 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); |
195 | if (len == -1) | 195 | if (len == -1) |
196 | return -1; | 196 | return -1; |
@@ -198,11 +198,11 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
198 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 198 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); |
199 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); | 199 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); |
200 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); | 200 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); |
201 | 201 | ||
202 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; | 202 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* puts the senders public key in the request in public_key, the data from the request | 205 | /* puts the senders public key in the request in public_key, the data from the request |
206 | in data if a friend or ping request was sent to us and returns the length of the data. | 206 | in data if a friend or ping request was sent to us and returns the length of the data. |
207 | packet is the request packet and length is its length | 207 | packet is the request packet and length is its length |
208 | return -1 if not valid request. */ | 208 | return -1 if not valid request. */ |
@@ -210,19 +210,17 @@ int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t | |||
210 | { | 210 | { |
211 | 211 | ||
212 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 212 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
213 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && | 213 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && |
214 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | 214 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
215 | { | ||
216 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | 215 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); |
217 | uint8_t nonce[crypto_box_NONCEBYTES]; | 216 | uint8_t nonce[crypto_box_NONCEBYTES]; |
218 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); | 217 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); |
219 | int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, | 218 | int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, |
220 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); | 219 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); |
221 | if(len1 == -1) | 220 | if(len1 == -1) |
222 | return -1; | 221 | return -1; |
223 | return len1; | 222 | return len1; |
224 | } | 223 | } else |
225 | else | ||
226 | return -1; | 224 | return -1; |
227 | } | 225 | } |
228 | 226 | ||
@@ -234,13 +232,13 @@ int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret | |||
234 | uint8_t temp_data[MAX_DATA_SIZE]; | 232 | uint8_t temp_data[MAX_DATA_SIZE]; |
235 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 233 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; |
236 | uint8_t nonce[crypto_box_NONCEBYTES]; | 234 | uint8_t nonce[crypto_box_NONCEBYTES]; |
237 | 235 | ||
238 | random_nonce(nonce); | 236 | random_nonce(nonce); |
239 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); | 237 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); |
240 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); | 238 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); |
241 | 239 | ||
242 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 240 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
243 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | 241 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); |
244 | if (len == -1) | 242 | if (len == -1) |
245 | return 0; | 243 | return 0; |
246 | temp_data[0] = 2; | 244 | temp_data[0] = 2; |
@@ -252,28 +250,27 @@ int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret | |||
252 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length | 250 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length |
253 | return 1 if successful | 251 | return 1 if successful |
254 | return 0 if failure */ | 252 | return 0 if failure */ |
255 | int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | 253 | int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, |
256 | uint8_t *session_key, uint8_t *data, uint16_t length) | 254 | uint8_t *session_key, uint8_t *data, uint16_t length) |
257 | { | 255 | { |
258 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); | 256 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); |
259 | if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES | 257 | if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES |
260 | + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) | 258 | + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) { |
261 | { | ||
262 | return 0; | 259 | return 0; |
263 | } | 260 | } |
264 | if (data[0] != 2) | 261 | if (data[0] != 2) |
265 | return 0; | 262 | return 0; |
266 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 263 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; |
267 | 264 | ||
268 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); | 265 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); |
269 | 266 | ||
270 | int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, | 267 | int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, |
271 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | 268 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, |
272 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); | 269 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); |
273 | 270 | ||
274 | if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) | 271 | if (len != crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES) |
275 | return 0; | 272 | return 0; |
276 | 273 | ||
277 | memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); | 274 | memcpy(secret_nonce, temp, crypto_box_NONCEBYTES); |
278 | memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); | 275 | memcpy(session_key, temp + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES); |
279 | return 1; | 276 | return 1; |
@@ -316,9 +313,8 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port) | |||
316 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 313 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
317 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 314 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); |
318 | 315 | ||
319 | if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, | 316 | if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, |
320 | crypto_connections[i].sessionpublic_key) == 1) | 317 | crypto_connections[i].sessionpublic_key) == 1) { |
321 | { | ||
322 | increment_nonce(crypto_connections[i].recv_nonce); | 318 | increment_nonce(crypto_connections[i].recv_nonce); |
323 | return i; | 319 | return i; |
324 | } | 320 | } |
@@ -363,9 +359,9 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_ | |||
363 | return 0 if killed successfully | 359 | return 0 if killed successfully |
364 | return 1 if there was a problem. */ | 360 | return 1 if there was a problem. */ |
365 | int crypto_kill(int crypt_connection_id) | 361 | int crypto_kill(int crypt_connection_id) |
366 | { | 362 | { |
367 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 363 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) |
368 | return 1; | 364 | return 1; |
369 | if (crypto_connections[crypt_connection_id].status != 0) { | 365 | if (crypto_connections[crypt_connection_id].status != 0) { |
370 | crypto_connections[crypt_connection_id].status = 0; | 366 | crypto_connections[crypt_connection_id].status = 0; |
371 | kill_connection(crypto_connections[crypt_connection_id].number); | 367 | kill_connection(crypto_connections[crypt_connection_id].number); |
@@ -400,9 +396,8 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
400 | 396 | ||
401 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 397 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); |
402 | 398 | ||
403 | if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, | 399 | if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, |
404 | crypto_connections[i].sessionpublic_key) == 1) | 400 | crypto_connections[i].sessionpublic_key) == 1) { |
405 | { | ||
406 | increment_nonce(crypto_connections[i].recv_nonce); | 401 | increment_nonce(crypto_connections[i].recv_nonce); |
407 | uint32_t zero = 0; | 402 | uint32_t zero = 0; |
408 | crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ | 403 | crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ |
@@ -413,10 +408,10 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
413 | return -1; /* this should never happen. */ | 408 | return -1; /* this should never happen. */ |
414 | } | 409 | } |
415 | } | 410 | } |
416 | return -1; | 411 | return -1; |
417 | } | 412 | } |
418 | 413 | ||
419 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet | 414 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet |
420 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 415 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
421 | 4 if the connection is timed out and waiting to be killed */ | 416 | 4 if the connection is timed out and waiting to be killed */ |
422 | int is_cryptoconnected(int crypt_connection_id) | 417 | int is_cryptoconnected(int crypt_connection_id) |
@@ -471,9 +466,9 @@ static void handle_incomings() | |||
471 | { | 466 | { |
472 | int income; | 467 | int income; |
473 | while (1) { | 468 | while (1) { |
474 | income = incoming_connection(); | 469 | income = incoming_connection(); |
475 | if(income == -1 || new_incoming(income) ) | 470 | if(income == -1 || new_incoming(income) ) |
476 | break; | 471 | break; |
477 | } | 472 | } |
478 | } | 473 | } |
479 | 474 | ||
@@ -488,8 +483,8 @@ static void receive_crypto() | |||
488 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 483 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
489 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 484 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; |
490 | uint16_t len; | 485 | uint16_t len; |
491 | if (id_packet(crypto_connections[i].number) == 1) | 486 | if (id_packet(crypto_connections[i].number) == 1) |
492 | /* if the packet is a friend request drop it (because we are already friends) */ | 487 | /* if the packet is a friend request drop it (because we are already friends) */ |
493 | len = read_packet(crypto_connections[i].number, temp_data); | 488 | len = read_packet(crypto_connections[i].number, temp_data); |
494 | if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ | 489 | if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ |
495 | len = read_packet(crypto_connections[i].number, temp_data); | 490 | len = read_packet(crypto_connections[i].number, temp_data); |
@@ -504,31 +499,28 @@ static void receive_crypto() | |||
504 | crypto_connections[i].status = 2; /* set it to its proper value right after. */ | 499 | crypto_connections[i].status = 2; /* set it to its proper value right after. */ |
505 | } | 500 | } |
506 | } | 501 | } |
507 | } | 502 | } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does |
508 | else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does | ||
509 | crypto_kill(crypto_connections[i].number); | 503 | crypto_kill(crypto_connections[i].number); |
510 | 504 | ||
511 | } | 505 | } |
512 | if (crypto_connections[i].status == 2) { | 506 | if (crypto_connections[i].status == 2) { |
513 | if (id_packet(crypto_connections[i].number) == 3) { | 507 | if (id_packet(crypto_connections[i].number) == 3) { |
514 | uint8_t temp_data[MAX_DATA_SIZE]; | 508 | uint8_t temp_data[MAX_DATA_SIZE]; |
515 | uint8_t data[MAX_DATA_SIZE]; | 509 | uint8_t data[MAX_DATA_SIZE]; |
516 | int length = read_packet(crypto_connections[i].number, temp_data); | 510 | int length = read_packet(crypto_connections[i].number, temp_data); |
517 | int len = decrypt_data(crypto_connections[i].peersessionpublic_key, | 511 | int len = decrypt_data(crypto_connections[i].peersessionpublic_key, |
518 | crypto_connections[i].sessionsecret_key, | 512 | crypto_connections[i].sessionsecret_key, |
519 | crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); | 513 | crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); |
520 | uint32_t zero = 0; | 514 | uint32_t zero = 0; |
521 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { | 515 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { |
522 | increment_nonce(crypto_connections[i].recv_nonce); | 516 | increment_nonce(crypto_connections[i].recv_nonce); |
523 | crypto_connections[i].status = 3; | 517 | crypto_connections[i].status = 3; |
524 | 518 | ||
525 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ | 519 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ |
526 | kill_connection_in(crypto_connections[i].number, 3000000); | 520 | kill_connection_in(crypto_connections[i].number, 3000000); |
527 | } | 521 | } else |
528 | else | ||
529 | crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does | 522 | crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does |
530 | } | 523 | } else if(id_packet(crypto_connections[i].number) != -1) |
531 | else if(id_packet(crypto_connections[i].number) != -1) | ||
532 | /* This should not happen | 524 | /* This should not happen |
533 | kill the connection if it does */ | 525 | kill the connection if it does */ |
534 | crypto_kill(crypto_connections[i].number); | 526 | crypto_kill(crypto_connections[i].number); |
diff --git a/core/net_crypto.h b/core/net_crypto.h index d4fe1313..0eb2ad6d 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* net_crypto.h | 1 | /* net_crypto.h |
2 | * | 2 | * |
3 | * Functions for the core network crypto. | 3 | * Functions for the core network crypto. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
@@ -18,11 +18,11 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef NET_CRYPTO_H | 24 | #ifndef NET_CRYPTO_H |
25 | #define NET_CRYPTO_H | 25 | #define NET_CRYPTO_H |
26 | 26 | ||
27 | #include "Lossless_UDP.h" | 27 | #include "Lossless_UDP.h" |
28 | 28 | ||
@@ -30,102 +30,102 @@ | |||
30 | extern "C" { | 30 | extern "C" { |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | /* Our public key. */ | 33 | /* Our public key. */ |
34 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 34 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; |
35 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | 35 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; |
36 | 36 | ||
37 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) | 37 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) |
38 | 38 | ||
39 | /* encrypts plain of length length to encrypted of length + 16 using the | 39 | /* encrypts plain of length length to encrypted of length + 16 using the |
40 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | 40 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce |
41 | return -1 if there was a problem. | 41 | return -1 if there was a problem. |
42 | return length of encrypted data if everything was fine. */ | 42 | return length of encrypted data if everything was fine. */ |
43 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 43 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, |
44 | uint8_t *plain, uint32_t length, uint8_t *encrypted); | 44 | uint8_t *plain, uint32_t length, uint8_t *encrypted); |
45 | 45 | ||
46 | 46 | ||
47 | /* decrypts encrypted of length length to plain of length length - 16 using the | 47 | /* decrypts encrypted of length length to plain of length length - 16 using the |
48 | public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce | 48 | public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce |
49 | return -1 if there was a problem(decryption failed) | 49 | return -1 if there was a problem(decryption failed) |
50 | return length of plain data if everything was fine. */ | 50 | return length of plain data if everything was fine. */ |
51 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | 51 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, |
52 | uint8_t *encrypted, uint32_t length, uint8_t *plain); | 52 | uint8_t *encrypted, uint32_t length, uint8_t *plain); |
53 | 53 | ||
54 | 54 | ||
55 | /* fill the given nonce with random bytes. */ | 55 | /* fill the given nonce with random bytes. */ |
56 | void random_nonce(uint8_t *nonce); | 56 | void random_nonce(uint8_t *nonce); |
57 | 57 | ||
58 | /* return 0 if there is no received data in the buffer | 58 | /* return 0 if there is no received data in the buffer |
59 | return -1 if the packet was discarded. | 59 | return -1 if the packet was discarded. |
60 | return length of received data if successful */ | 60 | return length of received data if successful */ |
61 | int read_cryptpacket(int crypt_connection_id, uint8_t *data); | 61 | int read_cryptpacket(int crypt_connection_id, uint8_t *data); |
62 | 62 | ||
63 | /* return 0 if data could not be put in packet queue | 63 | /* return 0 if data could not be put in packet queue |
64 | return 1 if data was put into the queue */ | 64 | return 1 if data was put into the queue */ |
65 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); | 65 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); |
66 | 66 | ||
67 | /* create a request to peer with public_key. | 67 | /* create a request to peer with public_key. |
68 | packet must be an array of MAX_DATA_SIZE big. | 68 | packet must be an array of MAX_DATA_SIZE big. |
69 | Data represents the data we send with the request with length being the length of the data. | 69 | Data represents the data we send with the request with length being the length of the data. |
70 | request_id is the id of the request (32 = friend request, 254 = ping request) | 70 | request_id is the id of the request (32 = friend request, 254 = ping request) |
71 | returns -1 on failure | 71 | returns -1 on failure |
72 | returns the length of the created packet on success */ | 72 | returns the length of the created packet on success */ |
73 | int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); | 73 | int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); |
74 | 74 | ||
75 | /* puts the senders public key in the request in public_key, the data from the request | 75 | /* puts the senders public key in the request in public_key, the data from the request |
76 | in data if a friend or ping request was sent to us and returns the length of the data. | 76 | in data if a friend or ping request was sent to us and returns the length of the data. |
77 | packet is the request packet and length is its length | 77 | packet is the request packet and length is its length |
78 | return -1 if not valid request. */ | 78 | return -1 if not valid request. */ |
79 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length); | 79 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length); |
80 | 80 | ||
81 | /* Start a secure connection with other peer who has public_key and ip_port | 81 | /* Start a secure connection with other peer who has public_key and ip_port |
82 | returns -1 if failure | 82 | returns -1 if failure |
83 | returns crypt_connection_id of the initialized connection if everything went well. */ | 83 | returns crypt_connection_id of the initialized connection if everything went well. */ |
84 | int crypto_connect(uint8_t *public_key, IP_Port ip_port); | 84 | int crypto_connect(uint8_t *public_key, IP_Port ip_port); |
85 | 85 | ||
86 | /* kill a crypto connection | 86 | /* kill a crypto connection |
87 | return 0 if killed successfully | 87 | return 0 if killed successfully |
88 | return 1 if there was a problem. */ | 88 | return 1 if there was a problem. */ |
89 | int crypto_kill(int crypt_connection_id); | 89 | int crypto_kill(int crypt_connection_id); |
90 | 90 | ||
91 | /* handle an incoming connection | 91 | /* handle an incoming connection |
92 | return -1 if no crypto inbound connection | 92 | return -1 if no crypto inbound connection |
93 | return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection | 93 | return incoming connection id (Lossless_UDP one) if there is an incoming crypto connection |
94 | Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce | 94 | Put the public key of the peer in public_key, the secret_nonce from the handshake into secret_nonce |
95 | and the session public key for the connection in session_key | 95 | and the session public key for the connection in session_key |
96 | to accept it see: accept_crypto_inbound(...) | 96 | to accept it see: accept_crypto_inbound(...) |
97 | to refuse it just call kill_connection(...) on the connection id */ | 97 | to refuse it just call kill_connection(...) on the connection id */ |
98 | int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); | 98 | int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); |
99 | 99 | ||
100 | /* accept an incoming connection using the parameters provided by crypto_inbound | 100 | /* accept an incoming connection using the parameters provided by crypto_inbound |
101 | return -1 if not successful | 101 | return -1 if not successful |
102 | returns the crypt_connection_id if successful */ | 102 | returns the crypt_connection_id if successful */ |
103 | int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); | 103 | int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); |
104 | 104 | ||
105 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | 105 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet |
106 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 106 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
107 | 4 if the connection is timed out and waiting to be killed */ | 107 | 4 if the connection is timed out and waiting to be killed */ |
108 | int is_cryptoconnected(int crypt_connection_id); | 108 | int is_cryptoconnected(int crypt_connection_id); |
109 | 109 | ||
110 | 110 | ||
111 | /* Generate our public and private keys | 111 | /* Generate our public and private keys |
112 | Only call this function the first time the program starts. */ | 112 | Only call this function the first time the program starts. */ |
113 | void new_keys(); | 113 | void new_keys(); |
114 | 114 | ||
115 | /* save the public and private keys to the keys array | 115 | /* save the public and private keys to the keys array |
116 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 116 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
117 | void save_keys(uint8_t * keys); | 117 | void save_keys(uint8_t * keys); |
118 | 118 | ||
119 | /* load the public and private keys from the keys array | 119 | /* load the public and private keys from the keys array |
120 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 120 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
121 | void load_keys(uint8_t * keys); | 121 | void load_keys(uint8_t * keys); |
122 | 122 | ||
123 | /* run this to (re)initialize net_crypto | 123 | /* run this to (re)initialize net_crypto |
124 | sets all the global connection variables to their default values. */ | 124 | sets all the global connection variables to their default values. */ |
125 | void initNetCrypto(); | 125 | void initNetCrypto(); |
126 | 126 | ||
127 | /* main loop */ | 127 | /* main loop */ |
128 | void doNetCrypto(); | 128 | void doNetCrypto(); |
129 | 129 | ||
130 | #ifdef __cplusplus | 130 | #ifdef __cplusplus |
131 | } | 131 | } |
diff --git a/core/network.c b/core/network.c index 8804ab4e..aa16bda9 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* network.h | 1 | /* network.h |
2 | * | 2 | * |
3 | * Functions for the core networking. | 3 | * Functions for the core networking. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "network.h" | 24 | #include "network.h" |
@@ -27,7 +27,7 @@ | |||
27 | uint64_t current_time() | 27 | uint64_t current_time() |
28 | { | 28 | { |
29 | uint64_t time; | 29 | uint64_t time; |
30 | #ifdef WIN32 | 30 | #ifdef WIN32 |
31 | /* This probably works fine */ | 31 | /* This probably works fine */ |
32 | FILETIME ft; | 32 | FILETIME ft; |
33 | GetSystemTimeAsFileTime(&ft); | 33 | GetSystemTimeAsFileTime(&ft); |
@@ -36,24 +36,24 @@ uint64_t current_time() | |||
36 | time |= ft.dwLowDateTime; | 36 | time |= ft.dwLowDateTime; |
37 | time -= 116444736000000000UL; | 37 | time -= 116444736000000000UL; |
38 | return time/10; | 38 | return time/10; |
39 | #else | 39 | #else |
40 | struct timeval a; | 40 | struct timeval a; |
41 | gettimeofday(&a, NULL); | 41 | gettimeofday(&a, NULL); |
42 | time = 1000000UL*a.tv_sec + a.tv_usec; | 42 | time = 1000000UL*a.tv_sec + a.tv_usec; |
43 | return time; | 43 | return time; |
44 | #endif | 44 | #endif |
45 | } | 45 | } |
46 | 46 | ||
47 | /* return a random number | 47 | /* return a random number |
48 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ | 48 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ |
49 | uint32_t random_int() | 49 | uint32_t random_int() |
50 | { | 50 | { |
51 | #ifndef VANILLA_NACL | 51 | #ifndef VANILLA_NACL |
52 | //NOTE: this function comes from libsodium | 52 | //NOTE: this function comes from libsodium |
53 | return randombytes_random(); | 53 | return randombytes_random(); |
54 | #else | 54 | #else |
55 | return random(); | 55 | return random(); |
56 | #endif | 56 | #endif |
57 | } | 57 | } |
58 | 58 | ||
59 | /* our UDP socket, a global variable. */ | 59 | /* our UDP socket, a global variable. */ |
@@ -63,7 +63,7 @@ static int sock; | |||
63 | Function to send packet(data) of length length to ip_port */ | 63 | Function to send packet(data) of length length to ip_port */ |
64 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) | 64 | int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) |
65 | { | 65 | { |
66 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; | 66 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; |
67 | return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | 67 | return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); |
68 | } | 68 | } |
69 | 69 | ||
@@ -74,15 +74,15 @@ int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) | |||
74 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | 74 | int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) |
75 | { | 75 | { |
76 | ADDR addr; | 76 | ADDR addr; |
77 | #ifdef WIN32 | 77 | #ifdef WIN32 |
78 | int addrlen = sizeof(addr); | 78 | int addrlen = sizeof(addr); |
79 | #else | 79 | #else |
80 | uint32_t addrlen = sizeof(addr); | 80 | uint32_t addrlen = sizeof(addr); |
81 | #endif | 81 | #endif |
82 | (*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen); | 82 | (*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen); |
83 | if (*(int32_t*)length <= 0) | 83 | if (*(int32_t*)length <= 0) |
84 | return -1; /* nothing received or empty packet */ | 84 | return -1; /* nothing received or empty packet */ |
85 | 85 | ||
86 | ip_port->ip = addr.ip; | 86 | ip_port->ip = addr.ip; |
87 | ip_port->port = addr.port; | 87 | ip_port->port = addr.port; |
88 | return 0; | 88 | return 0; |
@@ -92,30 +92,30 @@ int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) | |||
92 | bind to ip and port | 92 | bind to ip and port |
93 | ip must be in network order EX: 127.0.0.1 = (7F000001) | 93 | ip must be in network order EX: 127.0.0.1 = (7F000001) |
94 | port is in host byte order (this means don't worry about it) | 94 | port is in host byte order (this means don't worry about it) |
95 | returns 0 if no problems | 95 | returns 0 if no problems |
96 | returns -1 if there are problems */ | 96 | returns -1 if there are problems */ |
97 | int init_networking(IP ip, uint16_t port) | 97 | int init_networking(IP ip, uint16_t port) |
98 | { | 98 | { |
99 | #ifdef WIN32 | 99 | #ifdef WIN32 |
100 | WSADATA wsaData; | 100 | WSADATA wsaData; |
101 | if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) | 101 | if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) |
102 | return -1; | 102 | return -1; |
103 | #else | 103 | #else |
104 | srandom((uint32_t)current_time()); | 104 | srandom((uint32_t)current_time()); |
105 | #endif | 105 | #endif |
106 | srand((uint32_t)current_time()); | 106 | srand((uint32_t)current_time()); |
107 | 107 | ||
108 | /* initialize our socket */ | 108 | /* initialize our socket */ |
109 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | 109 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
110 | 110 | ||
111 | /* Check for socket error */ | 111 | /* Check for socket error */ |
112 | #ifdef WIN32 | 112 | #ifdef WIN32 |
113 | if (sock == INVALID_SOCKET) /* MSDN recommends this */ | 113 | if (sock == INVALID_SOCKET) /* MSDN recommends this */ |
114 | return -1; | 114 | return -1; |
115 | #else | 115 | #else |
116 | if (sock < 0) | 116 | if (sock < 0) |
117 | return -1; | 117 | return -1; |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | /* Functions to increase the size of the send and receive UDP buffers | 120 | /* Functions to increase the size of the send and receive UDP buffers |
121 | NOTE: uncomment if necessary */ | 121 | NOTE: uncomment if necessary */ |
@@ -129,23 +129,23 @@ int init_networking(IP ip, uint16_t port) | |||
129 | if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1) | 129 | if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&n, sizeof(n)) == -1) |
130 | return -1; | 130 | return -1; |
131 | */ | 131 | */ |
132 | 132 | ||
133 | /* Enable broadcast on socket */ | 133 | /* Enable broadcast on socket */ |
134 | int broadcast = 1; | 134 | int broadcast = 1; |
135 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)); | 135 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)); |
136 | 136 | ||
137 | /* Set socket nonblocking */ | 137 | /* Set socket nonblocking */ |
138 | #ifdef WIN32 | 138 | #ifdef WIN32 |
139 | /* I think this works for windows */ | 139 | /* I think this works for windows */ |
140 | u_long mode = 1; | 140 | u_long mode = 1; |
141 | /* ioctl(sock, FIONBIO, &mode); */ | 141 | /* ioctl(sock, FIONBIO, &mode); */ |
142 | ioctlsocket(sock, FIONBIO, &mode); | 142 | ioctlsocket(sock, FIONBIO, &mode); |
143 | #else | 143 | #else |
144 | fcntl(sock, F_SETFL, O_NONBLOCK, 1); | 144 | fcntl(sock, F_SETFL, O_NONBLOCK, 1); |
145 | #endif | 145 | #endif |
146 | 146 | ||
147 | /* Bind our socket to port PORT and address 0.0.0.0 */ | 147 | /* Bind our socket to port PORT and address 0.0.0.0 */ |
148 | ADDR addr = {AF_INET, htons(port), ip}; | 148 | ADDR addr = {AF_INET, htons(port), ip}; |
149 | bind(sock, (struct sockaddr*)&addr, sizeof(addr)); | 149 | bind(sock, (struct sockaddr*)&addr, sizeof(addr)); |
150 | 150 | ||
151 | return 0; | 151 | return 0; |
@@ -155,12 +155,12 @@ int init_networking(IP ip, uint16_t port) | |||
155 | /* function to cleanup networking stuff */ | 155 | /* function to cleanup networking stuff */ |
156 | void shutdown_networking() | 156 | void shutdown_networking() |
157 | { | 157 | { |
158 | #ifdef WIN32 | 158 | #ifdef WIN32 |
159 | closesocket(sock); | 159 | closesocket(sock); |
160 | WSACleanup(); | 160 | WSACleanup(); |
161 | #else | 161 | #else |
162 | close(sock); | 162 | close(sock); |
163 | #endif | 163 | #endif |
164 | return; | 164 | return; |
165 | } | 165 | } |
166 | 166 | ||
diff --git a/core/network.h b/core/network.h index a59d7c38..c8b8e355 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* network.h | 1 | /* network.h |
2 | * | 2 | * |
3 | * Datatypes, functions and includes for the core networking. | 3 | * Datatypes, functions and includes for the core networking. |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
@@ -18,11 +18,11 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef NETWORK_H | 24 | #ifndef NETWORK_H |
25 | #define NETWORK_H | 25 | #define NETWORK_H |
26 | 26 | ||
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | #include <stdio.h> | 28 | #include <stdio.h> |
@@ -46,7 +46,7 @@ | |||
46 | #include <netinet/in.h> | 46 | #include <netinet/in.h> |
47 | #include <errno.h> | 47 | #include <errno.h> |
48 | #include <sys/time.h> | 48 | #include <sys/time.h> |
49 | #include <sys/types.h> | 49 | #include <sys/types.h> |
50 | #include <netdb.h> | 50 | #include <netdb.h> |
51 | #include <unistd.h> | 51 | #include <unistd.h> |
52 | 52 | ||
@@ -69,63 +69,63 @@ extern "C" { | |||
69 | 69 | ||
70 | #define MAX_UDP_PACKET_SIZE 65507 | 70 | #define MAX_UDP_PACKET_SIZE 65507 |
71 | 71 | ||
72 | typedef union { | 72 | typedef union { |
73 | uint8_t c[4]; | 73 | uint8_t c[4]; |
74 | uint16_t s[2]; | 74 | uint16_t s[2]; |
75 | uint32_t i; | 75 | uint32_t i; |
76 | } IP; | 76 | } IP; |
77 | 77 | ||
78 | typedef struct { | 78 | typedef struct { |
79 | IP ip; | 79 | IP ip; |
80 | uint16_t port; | 80 | uint16_t port; |
81 | /* not used for anything right now */ | 81 | /* not used for anything right now */ |
82 | uint16_t padding; | 82 | uint16_t padding; |
83 | } IP_Port; | 83 | } IP_Port; |
84 | 84 | ||
85 | typedef struct { | 85 | typedef struct { |
86 | int16_t family; | 86 | int16_t family; |
87 | uint16_t port; | 87 | uint16_t port; |
88 | IP ip; | 88 | IP ip; |
89 | uint8_t zeroes[8]; | 89 | uint8_t zeroes[8]; |
90 | #ifdef ENABLE_IPV6 | 90 | #ifdef ENABLE_IPV6 |
91 | uint8_t zeroes2[12]; | 91 | uint8_t zeroes2[12]; |
92 | #endif | 92 | #endif |
93 | } ADDR; | 93 | } ADDR; |
94 | 94 | ||
95 | /* returns current time in milleseconds since the epoch. */ | 95 | /* returns current time in milleseconds since the epoch. */ |
96 | uint64_t current_time(); | 96 | uint64_t current_time(); |
97 | 97 | ||
98 | /* return a random number | 98 | /* return a random number |
99 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ | 99 | NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary */ |
100 | uint32_t random_int(); | 100 | uint32_t random_int(); |
101 | 101 | ||
102 | /* Basic network functions: */ | 102 | /* Basic network functions: */ |
103 | 103 | ||
104 | /* Function to send packet(data) of length length to ip_port */ | 104 | /* Function to send packet(data) of length length to ip_port */ |
105 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); | 105 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); |
106 | 106 | ||
107 | /* Function to receive data, ip and port of sender is put into ip_port | 107 | /* Function to receive data, ip and port of sender is put into ip_port |
108 | the packet data into data | 108 | the packet data into data |
109 | the packet length into length. */ | 109 | the packet length into length. */ |
110 | int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length); | 110 | int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length); |
111 | 111 | ||
112 | /* initialize networking | 112 | /* initialize networking |
113 | bind to ip and port | 113 | bind to ip and port |
114 | ip must be in network order EX: 127.0.0.1 = (7F000001) | 114 | ip must be in network order EX: 127.0.0.1 = (7F000001) |
115 | port is in host byte order (this means don't worry about it) | 115 | port is in host byte order (this means don't worry about it) |
116 | returns 0 if no problems | 116 | returns 0 if no problems |
117 | returns -1 if there were problems */ | 117 | returns -1 if there were problems */ |
118 | int init_networking(IP ip, uint16_t port); | 118 | int init_networking(IP ip, uint16_t port); |
119 | 119 | ||
120 | /* function to cleanup networking stuff(doesn't do much right now) */ | 120 | /* function to cleanup networking stuff(doesn't do much right now) */ |
121 | void shutdown_networking(); | 121 | void shutdown_networking(); |
122 | 122 | ||
123 | /* resolves provided address to a binary data in network byte order | 123 | /* resolves provided address to a binary data in network byte order |
124 | address is ASCII null terminated string | 124 | address is ASCII null terminated string |
125 | address should represent IPv4, IPv6 or a hostname | 125 | address should represent IPv4, IPv6 or a hostname |
126 | on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i | 126 | on success returns a data in network byte order that can be used to set IP.i or IP_Port.ip.i |
127 | on failure returns -1 */ | 127 | on failure returns -1 */ |
128 | int resolve_addr(char *address); | 128 | int resolve_addr(char *address); |
129 | 129 | ||
130 | #ifdef __cplusplus | 130 | #ifdef __cplusplus |
131 | } | 131 | } |