diff options
37 files changed, 1476 insertions, 1372 deletions
diff --git a/auto_tests/friends_test.c b/auto_tests/friends_test.c index dd2db3e3..b6223489 100644 --- a/auto_tests/friends_test.c +++ b/auto_tests/friends_test.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #define c_sleep(x) usleep(1000*x) | 44 | #define c_sleep(x) usleep(1000*x) |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #define PORT 33445 | ||
48 | |||
47 | static Messenger *m; | 49 | static Messenger *m; |
48 | 50 | ||
49 | uint8_t *parent_id = NULL; | 51 | uint8_t *parent_id = NULL; |
@@ -52,13 +54,13 @@ uint8_t *child_id = NULL; | |||
52 | pid_t child_pid = 0; | 54 | pid_t child_pid = 0; |
53 | int request_flags = 0; | 55 | int request_flags = 0; |
54 | 56 | ||
55 | void do_tox(void) | 57 | void do_tox(DHT *dht) |
56 | { | 58 | { |
57 | static int dht_on = 0; | 59 | static int dht_on = 0; |
58 | 60 | ||
59 | if (!dht_on && DHT_isconnected()) { | 61 | if (!dht_on && DHT_isconnected(dht)) { |
60 | dht_on = 1; | 62 | dht_on = 1; |
61 | } else if (dht_on && !DHT_isconnected()) { | 63 | } else if (dht_on && !DHT_isconnected(dht)) { |
62 | dht_on = 0; | 64 | dht_on = 0; |
63 | } | 65 | } |
64 | 66 | ||
@@ -77,7 +79,7 @@ void parent_confirm_status(Messenger *m, int num, uint8_t *data, uint16_t length | |||
77 | request_flags |= FIRST_FLAG; | 79 | request_flags |= FIRST_FLAG; |
78 | } | 80 | } |
79 | 81 | ||
80 | int parent_friend_request(void) | 82 | int parent_friend_request(DHT *dht) |
81 | { | 83 | { |
82 | char *message = "Watson, come here, I need you."; | 84 | char *message = "Watson, come here, I need you."; |
83 | int len = strlen(message); | 85 | int len = strlen(message); |
@@ -90,7 +92,7 @@ int parent_friend_request(void) | |||
90 | 92 | ||
91 | /* wait on the status change */ | 93 | /* wait on the status change */ |
92 | for (i = 0; i < WAIT_COUNT; i++) { | 94 | for (i = 0; i < WAIT_COUNT; i++) { |
93 | do_tox(); | 95 | do_tox(dht); |
94 | 96 | ||
95 | if (request_flags & FIRST_FLAG) | 97 | if (request_flags & FIRST_FLAG) |
96 | break; | 98 | break; |
@@ -123,7 +125,7 @@ void child_got_statuschange(Messenger *m, int friend_num, uint8_t *string, uint1 | |||
123 | request_flags |= SECOND_FLAG; | 125 | request_flags |= SECOND_FLAG; |
124 | } | 126 | } |
125 | 127 | ||
126 | int parent_wait_for_message(void) | 128 | int parent_wait_for_message(DHT *dht) |
127 | { | 129 | { |
128 | int i = 0; | 130 | int i = 0; |
129 | 131 | ||
@@ -131,7 +133,7 @@ int parent_wait_for_message(void) | |||
131 | fflush(stdout); | 133 | fflush(stdout); |
132 | 134 | ||
133 | for (i = 0; i < WAIT_COUNT; i++) { | 135 | for (i = 0; i < WAIT_COUNT; i++) { |
134 | do_tox(); | 136 | do_tox(dht); |
135 | 137 | ||
136 | if (request_flags & SECOND_FLAG) | 138 | if (request_flags & SECOND_FLAG) |
137 | break; | 139 | break; |
@@ -185,16 +187,16 @@ int main(int argc, char *argv[]) | |||
185 | 187 | ||
186 | /* wait on the friend request */ | 188 | /* wait on the friend request */ |
187 | while (!(request_flags & FIRST_FLAG)) | 189 | while (!(request_flags & FIRST_FLAG)) |
188 | do_tox(); | 190 | do_tox(m->dht); |
189 | 191 | ||
190 | /* wait for the status change */ | 192 | /* wait for the status change */ |
191 | while (!(request_flags & SECOND_FLAG)) | 193 | while (!(request_flags & SECOND_FLAG)) |
192 | do_tox(); | 194 | do_tox(m->dht); |
193 | 195 | ||
194 | for (i = 0; i < 6; i++) { | 196 | for (i = 0; i < 6; i++) { |
195 | /* send the message six times, just to be sure */ | 197 | /* send the message six times, just to be sure */ |
196 | m_sendmessage(m, 0, (uint8_t *)message, strlen(message)); | 198 | m_sendmessage(m, 0, (uint8_t *)message, strlen(message)); |
197 | do_tox(); | 199 | do_tox(m->dht); |
198 | } | 200 | } |
199 | 201 | ||
200 | cleanupMessenger(m); | 202 | cleanupMessenger(m); |
@@ -220,10 +222,10 @@ int main(int argc, char *argv[]) | |||
220 | 222 | ||
221 | Messenger_save(m, parent_id); | 223 | Messenger_save(m, parent_id); |
222 | 224 | ||
223 | if (parent_friend_request() == -1) | 225 | if (parent_friend_request(m->dht) == -1) |
224 | return -1; | 226 | return -1; |
225 | 227 | ||
226 | if (parent_wait_for_message() == -1) | 228 | if (parent_wait_for_message(m->dht) == -1) |
227 | return -1; | 229 | return -1; |
228 | 230 | ||
229 | wait(NULL); | 231 | wait(NULL); |
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index ad6eea01..55a41912 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt | |||
@@ -10,8 +10,7 @@ set(core_sources | |||
10 | LAN_discovery.c | 10 | LAN_discovery.c |
11 | Messenger.c | 11 | Messenger.c |
12 | util.c | 12 | util.c |
13 | ping.c | 13 | ping.c) |
14 | timer.c) | ||
15 | 14 | ||
16 | if(SHARED_TOXCORE) | 15 | if(SHARED_TOXCORE) |
17 | add_library(toxcore SHARED ${core_sources}) | 16 | add_library(toxcore SHARED ${core_sources}) |
@@ -27,17 +27,6 @@ | |||
27 | #include "packets.h" | 27 | #include "packets.h" |
28 | #include "ping.h" | 28 | #include "ping.h" |
29 | 29 | ||
30 | /* maximum number of clients stored per friend. */ | ||
31 | #define MAX_FRIEND_CLIENTS 8 | ||
32 | |||
33 | /* A list of the clients mathematically closest to ours. */ | ||
34 | #define LCLIENT_LIST 32 | ||
35 | |||
36 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | ||
37 | #define LPING_ARRAY 256 | ||
38 | |||
39 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | ||
40 | |||
41 | /* the number of seconds for a non responsive node to become bad. */ | 30 | /* the number of seconds for a non responsive node to become bad. */ |
42 | #define BAD_NODE_TIMEOUT 70 | 31 | #define BAD_NODE_TIMEOUT 70 |
43 | 32 | ||
@@ -61,59 +50,13 @@ | |||
61 | /*Interval in seconds between punching attempts*/ | 50 | /*Interval in seconds between punching attempts*/ |
62 | #define PUNCH_INTERVAL 10 | 51 | #define PUNCH_INTERVAL 10 |
63 | 52 | ||
64 | /*Maximum newly announced nodes to ping per TIME_TOPING seconds*/ | 53 | /*Ping newly announced nodes to ping per TIME_TOPING seconds*/ |
65 | #define MAX_TOPING 16 | ||
66 | |||
67 | #define TIME_TOPING 5 | 54 | #define TIME_TOPING 5 |
68 | /*----------------------------------------------------------------------------------*/ | ||
69 | |||
70 | typedef struct { | ||
71 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
72 | Client_data client_list[MAX_FRIEND_CLIENTS]; | ||
73 | |||
74 | /* time at which the last get_nodes request was sent. */ | ||
75 | uint64_t lastgetnode; | ||
76 | |||
77 | /* Symetric NAT hole punching stuff */ | ||
78 | |||
79 | /* 1 if currently hole punching, otherwise 0 */ | ||
80 | uint8_t hole_punching; | ||
81 | uint32_t punching_index; | ||
82 | uint64_t punching_timestamp; | ||
83 | uint64_t recvNATping_timestamp; | ||
84 | uint64_t NATping_id; | ||
85 | uint64_t NATping_timestamp; | ||
86 | } Friend; | ||
87 | |||
88 | typedef struct { | ||
89 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
90 | IP_Port ip_port; | ||
91 | } Node_format; | ||
92 | |||
93 | typedef struct { | ||
94 | IP_Port ip_port; | ||
95 | uint64_t ping_id; | ||
96 | uint64_t timestamp; | ||
97 | } Pinged; | ||
98 | |||
99 | /*----------------------------------------------------------------------------------*/ | ||
100 | 55 | ||
101 | /* Our client id/public key */ | ||
102 | uint8_t self_public_key[CLIENT_ID_SIZE]; | ||
103 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
104 | static Client_data close_clientlist[LCLIENT_LIST]; | ||
105 | static Friend *friends_list; | ||
106 | static uint16_t num_friends; | ||
107 | static Pinged send_nodes[LSEND_NODES_ARRAY]; | ||
108 | static Node_format toping[MAX_TOPING]; | ||
109 | static uint64_t last_toping; | ||
110 | 56 | ||
111 | /*----------------------------------------------------------------------------------*/ | 57 | Client_data *DHT_get_close_list(DHT *dht) |
112 | |||
113 | |||
114 | Client_data *DHT_get_close_list(void) | ||
115 | { | 58 | { |
116 | return close_clientlist; | 59 | return dht->close_clientlist; |
117 | } | 60 | } |
118 | 61 | ||
119 | /* Compares client_id1 and client_id2 with client_id | 62 | /* Compares client_id1 and client_id2 with client_id |
@@ -203,12 +146,12 @@ static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *clien | |||
203 | 146 | ||
204 | /* Returns the friend number from the client_id, or -1 if a failure occurs | 147 | /* Returns the friend number from the client_id, or -1 if a failure occurs |
205 | */ | 148 | */ |
206 | static int friend_number(uint8_t *client_id) | 149 | static int friend_number(DHT *dht, uint8_t *client_id) |
207 | { | 150 | { |
208 | uint32_t i; | 151 | uint32_t i; |
209 | 152 | ||
210 | for (i = 0; i < num_friends; ++i) { | 153 | for (i = 0; i < dht->num_friends; ++i) { |
211 | if (id_equal(friends_list[i].client_id, client_id)) | 154 | if (id_equal(dht->friends_list[i].client_id, client_id)) |
212 | return i; | 155 | return i; |
213 | } | 156 | } |
214 | 157 | ||
@@ -220,15 +163,15 @@ static int friend_number(uint8_t *client_id) | |||
220 | * | 163 | * |
221 | * TODO: For the love of based Allah make this function cleaner and much more efficient. | 164 | * TODO: For the love of based Allah make this function cleaner and much more efficient. |
222 | */ | 165 | */ |
223 | static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | 166 | static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list) |
224 | { | 167 | { |
225 | uint32_t i, j, k; | 168 | uint32_t i, j, k; |
226 | uint64_t temp_time = unix_time(); | 169 | uint64_t temp_time = unix_time(); |
227 | int num_nodes = 0, closest, tout, inlist; | 170 | int num_nodes = 0, closest, tout, inlist; |
228 | 171 | ||
229 | for (i = 0; i < LCLIENT_LIST; ++i) { | 172 | for (i = 0; i < LCLIENT_LIST; ++i) { |
230 | tout = is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); | 173 | tout = is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT); |
231 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); | 174 | inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, dht->close_clientlist[i].client_id); |
232 | 175 | ||
233 | /* if node isn't good or is already in list. */ | 176 | /* if node isn't good or is already in list. */ |
234 | if (tout || inlist) | 177 | if (tout || inlist) |
@@ -237,10 +180,10 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
237 | if (num_nodes < MAX_SENT_NODES) { | 180 | if (num_nodes < MAX_SENT_NODES) { |
238 | 181 | ||
239 | memcpy( nodes_list[num_nodes].client_id, | 182 | memcpy( nodes_list[num_nodes].client_id, |
240 | close_clientlist[i].client_id, | 183 | dht->close_clientlist[i].client_id, |
241 | CLIENT_ID_SIZE ); | 184 | CLIENT_ID_SIZE ); |
242 | 185 | ||
243 | nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; | 186 | nodes_list[num_nodes].ip_port = dht->close_clientlist[i].ip_port; |
244 | num_nodes++; | 187 | num_nodes++; |
245 | 188 | ||
246 | } else { | 189 | } else { |
@@ -248,27 +191,27 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
248 | for (j = 0; j < MAX_SENT_NODES; ++j) { | 191 | for (j = 0; j < MAX_SENT_NODES; ++j) { |
249 | closest = id_closest( client_id, | 192 | closest = id_closest( client_id, |
250 | nodes_list[j].client_id, | 193 | nodes_list[j].client_id, |
251 | close_clientlist[i].client_id ); | 194 | dht->close_clientlist[i].client_id ); |
252 | 195 | ||
253 | if (closest == 2) { | 196 | if (closest == 2) { |
254 | memcpy( nodes_list[j].client_id, | 197 | memcpy( nodes_list[j].client_id, |
255 | close_clientlist[i].client_id, | 198 | dht->close_clientlist[i].client_id, |
256 | CLIENT_ID_SIZE); | 199 | CLIENT_ID_SIZE); |
257 | 200 | ||
258 | nodes_list[j].ip_port = close_clientlist[i].ip_port; | 201 | nodes_list[j].ip_port = dht->close_clientlist[i].ip_port; |
259 | break; | 202 | break; |
260 | } | 203 | } |
261 | } | 204 | } |
262 | } | 205 | } |
263 | } | 206 | } |
264 | 207 | ||
265 | for (i = 0; i < num_friends; ++i) { | 208 | for (i = 0; i < dht->num_friends; ++i) { |
266 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 209 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
267 | 210 | ||
268 | tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); | 211 | tout = is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); |
269 | inlist = client_in_nodelist( nodes_list, | 212 | inlist = client_in_nodelist( nodes_list, |
270 | MAX_SENT_NODES, | 213 | MAX_SENT_NODES, |
271 | friends_list[i].client_list[j].client_id); | 214 | dht->friends_list[i].client_list[j].client_id); |
272 | 215 | ||
273 | /* if node isn't good or is already in list. */ | 216 | /* if node isn't good or is already in list. */ |
274 | if (tout || inlist) | 217 | if (tout || inlist) |
@@ -277,24 +220,24 @@ static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list) | |||
277 | if (num_nodes < MAX_SENT_NODES) { | 220 | if (num_nodes < MAX_SENT_NODES) { |
278 | 221 | ||
279 | memcpy( nodes_list[num_nodes].client_id, | 222 | memcpy( nodes_list[num_nodes].client_id, |
280 | friends_list[i].client_list[j].client_id, | 223 | dht->friends_list[i].client_list[j].client_id, |
281 | CLIENT_ID_SIZE); | 224 | CLIENT_ID_SIZE); |
282 | 225 | ||
283 | nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; | 226 | nodes_list[num_nodes].ip_port = dht->friends_list[i].client_list[j].ip_port; |
284 | num_nodes++; | 227 | num_nodes++; |
285 | } else { | 228 | } else { |
286 | for (k = 0; k < MAX_SENT_NODES; ++k) { | 229 | for (k = 0; k < MAX_SENT_NODES; ++k) { |
287 | 230 | ||
288 | closest = id_closest( client_id, | 231 | closest = id_closest( client_id, |
289 | nodes_list[k].client_id, | 232 | nodes_list[k].client_id, |
290 | friends_list[i].client_list[j].client_id ); | 233 | dht->friends_list[i].client_list[j].client_id ); |
291 | 234 | ||
292 | if (closest == 2) { | 235 | if (closest == 2) { |
293 | memcpy( nodes_list[k].client_id, | 236 | memcpy( nodes_list[k].client_id, |
294 | friends_list[i].client_list[j].client_id, | 237 | dht->friends_list[i].client_list[j].client_id, |
295 | CLIENT_ID_SIZE ); | 238 | CLIENT_ID_SIZE ); |
296 | 239 | ||
297 | nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; | 240 | nodes_list[k].ip_port = dht->friends_list[i].client_list[j].ip_port; |
298 | break; | 241 | break; |
299 | } | 242 | } |
300 | } | 243 | } |
@@ -387,40 +330,40 @@ static int replace_good( Client_data *list, | |||
387 | /* Attempt to add client with ip_port and client_id to the friends client list | 330 | /* Attempt to add client with ip_port and client_id to the friends client list |
388 | * and close_clientlist | 331 | * and close_clientlist |
389 | */ | 332 | */ |
390 | void addto_lists(IP_Port ip_port, uint8_t *client_id) | 333 | void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id) |
391 | { | 334 | { |
392 | uint32_t i; | 335 | uint32_t i; |
393 | 336 | ||
394 | /* NOTE: current behavior if there are two clients with the same id is | 337 | /* NOTE: current behavior if there are two clients with the same id is |
395 | * to replace the first ip by the second. | 338 | * to replace the first ip by the second. |
396 | */ | 339 | */ |
397 | if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 340 | if (!client_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
398 | if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { | 341 | if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { |
399 | /* if we can't replace bad nodes we try replacing good ones */ | 342 | /* if we can't replace bad nodes we try replacing good ones */ |
400 | replace_good( close_clientlist, | 343 | replace_good( dht->close_clientlist, |
401 | LCLIENT_LIST, | 344 | LCLIENT_LIST, |
402 | client_id, | 345 | client_id, |
403 | ip_port, | 346 | ip_port, |
404 | self_public_key ); | 347 | dht->c->self_public_key ); |
405 | } | 348 | } |
406 | } | 349 | } |
407 | 350 | ||
408 | for (i = 0; i < num_friends; ++i) { | 351 | for (i = 0; i < dht->num_friends; ++i) { |
409 | if (!client_in_list( friends_list[i].client_list, | 352 | if (!client_in_list( dht->friends_list[i].client_list, |
410 | MAX_FRIEND_CLIENTS, | 353 | MAX_FRIEND_CLIENTS, |
411 | client_id, | 354 | client_id, |
412 | ip_port )) { | 355 | ip_port )) { |
413 | 356 | ||
414 | if (replace_bad( friends_list[i].client_list, | 357 | if (replace_bad( dht->friends_list[i].client_list, |
415 | MAX_FRIEND_CLIENTS, | 358 | MAX_FRIEND_CLIENTS, |
416 | client_id, | 359 | client_id, |
417 | ip_port )) { | 360 | ip_port )) { |
418 | /* if we can't replace bad nodes we try replacing good ones. */ | 361 | /* if we can't replace bad nodes we try replacing good ones. */ |
419 | replace_good( friends_list[i].client_list, | 362 | replace_good( dht->friends_list[i].client_list, |
420 | MAX_FRIEND_CLIENTS, | 363 | MAX_FRIEND_CLIENTS, |
421 | client_id, | 364 | client_id, |
422 | ip_port, | 365 | ip_port, |
423 | friends_list[i].client_id ); | 366 | dht->friends_list[i].client_id ); |
424 | } | 367 | } |
425 | } | 368 | } |
426 | } | 369 | } |
@@ -429,30 +372,30 @@ void addto_lists(IP_Port ip_port, uint8_t *client_id) | |||
429 | /* If client_id is a friend or us, update ret_ip_port | 372 | /* If client_id is a friend or us, update ret_ip_port |
430 | * nodeclient_id is the id of the node that sent us this info | 373 | * nodeclient_id is the id of the node that sent us this info |
431 | */ | 374 | */ |
432 | static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) | 375 | static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id) |
433 | { | 376 | { |
434 | uint32_t i, j; | 377 | uint32_t i, j; |
435 | uint64_t temp_time = unix_time(); | 378 | uint64_t temp_time = unix_time(); |
436 | 379 | ||
437 | if (id_equal(client_id, self_public_key)) { | 380 | if (id_equal(client_id, dht->c->self_public_key)) { |
438 | 381 | ||
439 | for (i = 0; i < LCLIENT_LIST; ++i) { | 382 | for (i = 0; i < LCLIENT_LIST; ++i) { |
440 | if (id_equal(nodeclient_id, close_clientlist[i].client_id)) { | 383 | if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { |
441 | close_clientlist[i].ret_ip_port = ip_port; | 384 | dht->close_clientlist[i].ret_ip_port = ip_port; |
442 | close_clientlist[i].ret_timestamp = temp_time; | 385 | dht->close_clientlist[i].ret_timestamp = temp_time; |
443 | return; | 386 | return; |
444 | } | 387 | } |
445 | } | 388 | } |
446 | 389 | ||
447 | } else { | 390 | } else { |
448 | 391 | ||
449 | for (i = 0; i < num_friends; ++i) { | 392 | for (i = 0; i < dht->num_friends; ++i) { |
450 | if (id_equal(client_id, friends_list[i].client_id)) { | 393 | if (id_equal(client_id, dht->friends_list[i].client_id)) { |
451 | 394 | ||
452 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 395 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
453 | if (id_equal(nodeclient_id, friends_list[i].client_list[j].client_id)) { | 396 | if (id_equal(nodeclient_id, dht->friends_list[i].client_list[j].client_id)) { |
454 | friends_list[i].client_list[j].ret_ip_port = ip_port; | 397 | dht->friends_list[i].client_list[j].ret_ip_port = ip_port; |
455 | friends_list[i].client_list[j].ret_timestamp = temp_time; | 398 | dht->friends_list[i].client_list[j].ret_timestamp = temp_time; |
456 | return; | 399 | return; |
457 | } | 400 | } |
458 | } | 401 | } |
@@ -463,20 +406,20 @@ static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodec | |||
463 | } | 406 | } |
464 | 407 | ||
465 | /* Same as last function but for get_node requests. */ | 408 | /* Same as last function but for get_node requests. */ |
466 | static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | 409 | static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) |
467 | { | 410 | { |
468 | uint32_t i; | 411 | uint32_t i; |
469 | uint8_t pinging; | 412 | uint8_t pinging; |
470 | uint64_t temp_time = unix_time(); | 413 | uint64_t temp_time = unix_time(); |
471 | 414 | ||
472 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { | 415 | for (i = 0; i < LSEND_NODES_ARRAY; ++i ) { |
473 | if (!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) { | 416 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { |
474 | pinging = 0; | 417 | pinging = 0; |
475 | 418 | ||
476 | if (ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port)) | 419 | if (ip_port.ip.i != 0 && ipport_equal(dht->send_nodes[i].ip_port, ip_port)) |
477 | ++pinging; | 420 | ++pinging; |
478 | 421 | ||
479 | if (ping_id != 0 && send_nodes[i].ping_id == ping_id) | 422 | if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) |
480 | ++pinging; | 423 | ++pinging; |
481 | 424 | ||
482 | if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) | 425 | if (pinging == (ping_id != 0) + (ip_port.ip.i != 0)) |
@@ -488,7 +431,7 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | |||
488 | } | 431 | } |
489 | 432 | ||
490 | /* Same but for get node requests */ | 433 | /* Same but for get node requests */ |
491 | static uint64_t add_gettingnodes(IP_Port ip_port) | 434 | static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port) |
492 | { | 435 | { |
493 | uint32_t i, j; | 436 | uint32_t i, j; |
494 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); | 437 | uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); |
@@ -496,10 +439,10 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
496 | 439 | ||
497 | for (i = 0; i < PING_TIMEOUT; ++i ) { | 440 | for (i = 0; i < PING_TIMEOUT; ++i ) { |
498 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { | 441 | for (j = 0; j < LSEND_NODES_ARRAY; ++j ) { |
499 | if (is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) { | 442 | if (is_timeout(temp_time, dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) { |
500 | send_nodes[j].timestamp = temp_time; | 443 | dht->send_nodes[j].timestamp = temp_time; |
501 | send_nodes[j].ip_port = ip_port; | 444 | dht->send_nodes[j].ip_port = ip_port; |
502 | send_nodes[j].ping_id = ping_id; | 445 | dht->send_nodes[j].ping_id = ping_id; |
503 | return ping_id; | 446 | return ping_id; |
504 | } | 447 | } |
505 | } | 448 | } |
@@ -509,13 +452,13 @@ static uint64_t add_gettingnodes(IP_Port ip_port) | |||
509 | } | 452 | } |
510 | 453 | ||
511 | /* send a getnodes request */ | 454 | /* send a getnodes request */ |
512 | static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | 455 | static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) |
513 | { | 456 | { |
514 | /* check if packet is gonna be sent to ourself */ | 457 | /* check if packet is gonna be sent to ourself */ |
515 | if (id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0)) | 458 | if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) |
516 | return 1; | 459 | return 1; |
517 | 460 | ||
518 | uint64_t ping_id = add_gettingnodes(ip_port); | 461 | uint64_t ping_id = add_gettingnodes(dht, ip_port); |
519 | 462 | ||
520 | if (ping_id == 0) | 463 | if (ping_id == 0) |
521 | return 1; | 464 | return 1; |
@@ -530,7 +473,7 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
530 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); | 473 | memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); |
531 | 474 | ||
532 | int len = encrypt_data( public_key, | 475 | int len = encrypt_data( public_key, |
533 | self_secret_key, | 476 | dht->c->self_secret_key, |
534 | nonce, | 477 | nonce, |
535 | plain, | 478 | plain, |
536 | sizeof(ping_id) + CLIENT_ID_SIZE, | 479 | sizeof(ping_id) + CLIENT_ID_SIZE, |
@@ -540,25 +483,25 @@ static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) | |||
540 | return -1; | 483 | return -1; |
541 | 484 | ||
542 | data[0] = 2; | 485 | data[0] = 2; |
543 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 486 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); |
544 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 487 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
545 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 488 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
546 | 489 | ||
547 | return sendpacket(ip_port, data, sizeof(data)); | 490 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, sizeof(data)); |
548 | } | 491 | } |
549 | 492 | ||
550 | /* send a send nodes response */ | 493 | /* send a send nodes response */ |
551 | static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) | 494 | static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) |
552 | { | 495 | { |
553 | /* check if packet is gonna be sent to ourself */ | 496 | /* check if packet is gonna be sent to ourself */ |
554 | if (id_equal(public_key, self_public_key)) | 497 | if (id_equal(public_key, dht->c->self_public_key)) |
555 | return 1; | 498 | return 1; |
556 | 499 | ||
557 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) | 500 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) |
558 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; | 501 | + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING]; |
559 | 502 | ||
560 | Node_format nodes_list[MAX_SENT_NODES]; | 503 | Node_format nodes_list[MAX_SENT_NODES]; |
561 | int num_nodes = get_close_nodes(client_id, nodes_list); | 504 | int num_nodes = get_close_nodes(dht, client_id, nodes_list); |
562 | 505 | ||
563 | if (num_nodes == 0) | 506 | if (num_nodes == 0) |
564 | return 0; | 507 | return 0; |
@@ -572,7 +515,7 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
572 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); | 515 | memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); |
573 | 516 | ||
574 | int len = encrypt_data( public_key, | 517 | int len = encrypt_data( public_key, |
575 | self_secret_key, | 518 | dht->c->self_secret_key, |
576 | nonce, | 519 | nonce, |
577 | plain, | 520 | plain, |
578 | sizeof(ping_id) + num_nodes * sizeof(Node_format), | 521 | sizeof(ping_id) + num_nodes * sizeof(Node_format), |
@@ -582,15 +525,16 @@ static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, u | |||
582 | return -1; | 525 | return -1; |
583 | 526 | ||
584 | data[0] = 3; | 527 | data[0] = 3; |
585 | memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); | 528 | memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); |
586 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | 529 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); |
587 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | 530 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); |
588 | 531 | ||
589 | return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | 532 | return sendpacket(dht->c->lossless_udp->net->sock, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); |
590 | } | 533 | } |
591 | 534 | ||
592 | static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length) | 535 | static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
593 | { | 536 | { |
537 | DHT *dht = object; | ||
594 | uint64_t ping_id; | 538 | uint64_t ping_id; |
595 | 539 | ||
596 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | 540 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
@@ -598,13 +542,13 @@ static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length) | |||
598 | return 1; | 542 | return 1; |
599 | 543 | ||
600 | /* check if packet is from ourself. */ | 544 | /* check if packet is from ourself. */ |
601 | if (id_equal(packet + 1, self_public_key)) | 545 | if (id_equal(packet + 1, dht->c->self_public_key)) |
602 | return 1; | 546 | return 1; |
603 | 547 | ||
604 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; | 548 | uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; |
605 | 549 | ||
606 | int len = decrypt_data( packet + 1, | 550 | int len = decrypt_data( packet + 1, |
607 | self_secret_key, | 551 | dht->c->self_secret_key, |
608 | packet + 1 + CLIENT_ID_SIZE, | 552 | packet + 1 + CLIENT_ID_SIZE, |
609 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 553 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
610 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, | 554 | sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, |
@@ -614,15 +558,16 @@ static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length) | |||
614 | return 1; | 558 | return 1; |
615 | 559 | ||
616 | memcpy(&ping_id, plain, sizeof(ping_id)); | 560 | memcpy(&ping_id, plain, sizeof(ping_id)); |
617 | sendnodes(source, packet + 1, plain + sizeof(ping_id), ping_id); | 561 | sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); |
618 | 562 | ||
619 | //send_ping_request(source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ | 563 | //send_ping_request(dht, source, (clientid_t*) (packet + 1)); /* TODO: make this smarter? */ |
620 | 564 | ||
621 | return 0; | 565 | return 0; |
622 | } | 566 | } |
623 | 567 | ||
624 | static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length) | 568 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
625 | { | 569 | { |
570 | DHT *dht = object; | ||
626 | uint64_t ping_id; | 571 | uint64_t ping_id; |
627 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; | 572 | uint32_t cid_size = 1 + CLIENT_ID_SIZE; |
628 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; | 573 | cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; |
@@ -637,7 +582,7 @@ static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length) | |||
637 | 582 | ||
638 | int len = decrypt_data( | 583 | int len = decrypt_data( |
639 | packet + 1, | 584 | packet + 1, |
640 | self_secret_key, | 585 | dht->c->self_secret_key, |
641 | packet + 1 + CLIENT_ID_SIZE, | 586 | packet + 1 + CLIENT_ID_SIZE, |
642 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 587 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
643 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); | 588 | sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); |
@@ -647,19 +592,19 @@ static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length) | |||
647 | 592 | ||
648 | memcpy(&ping_id, plain, sizeof(ping_id)); | 593 | memcpy(&ping_id, plain, sizeof(ping_id)); |
649 | 594 | ||
650 | if (!is_gettingnodes(source, ping_id)) | 595 | if (!is_gettingnodes(dht, source, ping_id)) |
651 | return 1; | 596 | return 1; |
652 | 597 | ||
653 | Node_format nodes_list[MAX_SENT_NODES]; | 598 | Node_format nodes_list[MAX_SENT_NODES]; |
654 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); | 599 | memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); |
655 | 600 | ||
656 | addto_lists(source, packet + 1); | 601 | addto_lists(dht, source, packet + 1); |
657 | 602 | ||
658 | uint32_t i; | 603 | uint32_t i; |
659 | 604 | ||
660 | for (i = 0; i < num_nodes; ++i) { | 605 | for (i = 0; i < num_nodes; ++i) { |
661 | send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); | 606 | send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id); |
662 | returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 607 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
663 | } | 608 | } |
664 | 609 | ||
665 | return 0; | 610 | return 0; |
@@ -668,54 +613,54 @@ static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length) | |||
668 | /*----------------------------------------------------------------------------------*/ | 613 | /*----------------------------------------------------------------------------------*/ |
669 | /*------------------------END of packet handling functions--------------------------*/ | 614 | /*------------------------END of packet handling functions--------------------------*/ |
670 | 615 | ||
671 | int DHT_addfriend(uint8_t *client_id) | 616 | int DHT_addfriend(DHT *dht, uint8_t *client_id) |
672 | { | 617 | { |
673 | if (friend_number(client_id) != -1) /*Is friend already in DHT?*/ | 618 | if (friend_number(dht, client_id) != -1) /*Is friend already in DHT?*/ |
674 | return 1; | 619 | return 1; |
675 | 620 | ||
676 | Friend *temp; | 621 | DHT_Friend *temp; |
677 | temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); | 622 | temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); |
678 | 623 | ||
679 | if (temp == NULL) | 624 | if (temp == NULL) |
680 | return 1; | 625 | return 1; |
681 | 626 | ||
682 | friends_list = temp; | 627 | dht->friends_list = temp; |
683 | memset(&friends_list[num_friends], 0, sizeof(Friend)); | 628 | memset(&dht->friends_list[dht->num_friends], 0, sizeof(DHT_Friend)); |
684 | memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); | 629 | memcpy(dht->friends_list[dht->num_friends].client_id, client_id, CLIENT_ID_SIZE); |
685 | 630 | ||
686 | friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); | 631 | dht->friends_list[dht->num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); |
687 | ++num_friends; | 632 | ++dht->num_friends; |
688 | return 0; | 633 | return 0; |
689 | } | 634 | } |
690 | 635 | ||
691 | int DHT_delfriend(uint8_t *client_id) | 636 | int DHT_delfriend(DHT *dht, uint8_t *client_id) |
692 | { | 637 | { |
693 | uint32_t i; | 638 | uint32_t i; |
694 | Friend *temp; | 639 | DHT_Friend *temp; |
695 | 640 | ||
696 | for (i = 0; i < num_friends; ++i) { | 641 | for (i = 0; i < dht->num_friends; ++i) { |
697 | /* Equal */ | 642 | /* Equal */ |
698 | if (id_equal(friends_list[i].client_id, client_id)) { | 643 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
699 | --num_friends; | 644 | --dht->num_friends; |
700 | 645 | ||
701 | if (num_friends != i) { | 646 | if (dht->num_friends != i) { |
702 | memcpy( friends_list[i].client_id, | 647 | memcpy( dht->friends_list[i].client_id, |
703 | friends_list[num_friends].client_id, | 648 | dht->friends_list[dht->num_friends].client_id, |
704 | CLIENT_ID_SIZE ); | 649 | CLIENT_ID_SIZE ); |
705 | } | 650 | } |
706 | 651 | ||
707 | if (num_friends == 0) { | 652 | if (dht->num_friends == 0) { |
708 | free(friends_list); | 653 | free(dht->friends_list); |
709 | friends_list = NULL; | 654 | dht->friends_list = NULL; |
710 | return 0; | 655 | return 0; |
711 | } | 656 | } |
712 | 657 | ||
713 | temp = realloc(friends_list, sizeof(Friend) * (num_friends)); | 658 | temp = realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends)); |
714 | 659 | ||
715 | if (temp == NULL) | 660 | if (temp == NULL) |
716 | return 1; | 661 | return 1; |
717 | 662 | ||
718 | friends_list = temp; | 663 | dht->friends_list = temp; |
719 | return 0; | 664 | return 0; |
720 | } | 665 | } |
721 | } | 666 | } |
@@ -724,19 +669,19 @@ int DHT_delfriend(uint8_t *client_id) | |||
724 | } | 669 | } |
725 | 670 | ||
726 | /* TODO: Optimize this. */ | 671 | /* TODO: Optimize this. */ |
727 | IP_Port DHT_getfriendip(uint8_t *client_id) | 672 | IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id) |
728 | { | 673 | { |
729 | uint32_t i, j; | 674 | uint32_t i, j; |
730 | uint64_t temp_time = unix_time(); | 675 | uint64_t temp_time = unix_time(); |
731 | IP_Port empty = {{{0}}, 0}; | 676 | IP_Port empty = {{{0}}, 0}; |
732 | 677 | ||
733 | for (i = 0; i < num_friends; ++i) { | 678 | for (i = 0; i < dht->num_friends; ++i) { |
734 | /* Equal */ | 679 | /* Equal */ |
735 | if (id_equal(friends_list[i].client_id, client_id)) { | 680 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
736 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 681 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
737 | if (id_equal(friends_list[i].client_list[j].client_id, client_id) | 682 | if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) |
738 | && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) | 683 | && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) |
739 | return friends_list[i].client_list[j].ip_port; | 684 | return dht->friends_list[i].client_list[j].ip_port; |
740 | } | 685 | } |
741 | 686 | ||
742 | return empty; | 687 | return empty; |
@@ -750,49 +695,47 @@ IP_Port DHT_getfriendip(uint8_t *client_id) | |||
750 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request | 695 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request |
751 | * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. | 696 | * every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list. |
752 | */ | 697 | */ |
753 | static void doDHTFriends(void) | 698 | static void do_DHT_friends(DHT *dht) |
754 | { | 699 | { |
755 | uint32_t i, j; | 700 | uint32_t i, j; |
756 | uint64_t temp_time = unix_time(); | 701 | uint64_t temp_time = unix_time(); |
757 | uint32_t rand_node; | 702 | uint32_t rand_node; |
758 | uint32_t index[MAX_FRIEND_CLIENTS]; | 703 | uint32_t index[MAX_FRIEND_CLIENTS]; |
759 | 704 | ||
760 | for (i = 0; i < num_friends; ++i) { | 705 | for (i = 0; i < dht->num_friends; ++i) { |
761 | uint32_t num_nodes = 0; | 706 | uint32_t num_nodes = 0; |
762 | 707 | ||
763 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 708 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
764 | /* if node is not dead. */ | 709 | /* if node is not dead. */ |
765 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { | 710 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { |
766 | if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { | 711 | if ((dht->friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { |
767 | send_ping_request( friends_list[i].client_list[j].ip_port, | 712 | send_ping_request(dht->ping, dht->c, dht->friends_list[i].client_list[j].ip_port, |
768 | (clientid_t *) &friends_list[i].client_list[j].client_id ); | 713 | (clientid_t *) &dht->friends_list[i].client_list[j].client_id ); |
769 | friends_list[i].client_list[j].last_pinged = temp_time; | 714 | dht->friends_list[i].client_list[j].last_pinged = temp_time; |
770 | } | 715 | } |
771 | 716 | ||
772 | /* if node is good. */ | 717 | /* if node is good. */ |
773 | if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { | 718 | if (!is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { |
774 | index[num_nodes] = j; | 719 | index[num_nodes] = j; |
775 | ++num_nodes; | 720 | ++num_nodes; |
776 | } | 721 | } |
777 | } | 722 | } |
778 | } | 723 | } |
779 | 724 | ||
780 | if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 725 | if (dht->friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
781 | rand_node = rand() % num_nodes; | 726 | rand_node = rand() % num_nodes; |
782 | getnodes( friends_list[i].client_list[index[rand_node]].ip_port, | 727 | getnodes(dht, dht->friends_list[i].client_list[index[rand_node]].ip_port, |
783 | friends_list[i].client_list[index[rand_node]].client_id, | 728 | dht->friends_list[i].client_list[index[rand_node]].client_id, |
784 | friends_list[i].client_id ); | 729 | dht->friends_list[i].client_id ); |
785 | friends_list[i].lastgetnode = temp_time; | 730 | dht->friends_list[i].lastgetnode = temp_time; |
786 | } | 731 | } |
787 | } | 732 | } |
788 | } | 733 | } |
789 | 734 | ||
790 | static uint64_t close_lastgetnodes; | ||
791 | |||
792 | /* Ping each client in the close nodes list every PING_INTERVAL seconds. | 735 | /* Ping each client in the close nodes list every PING_INTERVAL seconds. |
793 | * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. | 736 | * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. |
794 | */ | 737 | */ |
795 | static void doClose(void) | 738 | static void do_Close(DHT *dht) |
796 | { | 739 | { |
797 | uint32_t i; | 740 | uint32_t i; |
798 | uint64_t temp_time = unix_time(); | 741 | uint64_t temp_time = unix_time(); |
@@ -802,46 +745,46 @@ static void doClose(void) | |||
802 | 745 | ||
803 | for (i = 0; i < LCLIENT_LIST; ++i) { | 746 | for (i = 0; i < LCLIENT_LIST; ++i) { |
804 | /* if node is not dead. */ | 747 | /* if node is not dead. */ |
805 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { | 748 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { |
806 | if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { | 749 | if ((dht->close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { |
807 | send_ping_request( close_clientlist[i].ip_port, | 750 | send_ping_request(dht->ping, dht->c, dht->close_clientlist[i].ip_port, |
808 | (clientid_t *) &close_clientlist[i].client_id ); | 751 | (clientid_t *) &dht->close_clientlist[i].client_id ); |
809 | close_clientlist[i].last_pinged = temp_time; | 752 | dht->close_clientlist[i].last_pinged = temp_time; |
810 | } | 753 | } |
811 | 754 | ||
812 | /* if node is good. */ | 755 | /* if node is good. */ |
813 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { | 756 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { |
814 | index[num_nodes] = i; | 757 | index[num_nodes] = i; |
815 | ++num_nodes; | 758 | ++num_nodes; |
816 | } | 759 | } |
817 | } | 760 | } |
818 | } | 761 | } |
819 | 762 | ||
820 | if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { | 763 | if (dht->close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { |
821 | rand_node = rand() % num_nodes; | 764 | rand_node = rand() % num_nodes; |
822 | getnodes( close_clientlist[index[rand_node]].ip_port, | 765 | getnodes(dht, dht->close_clientlist[index[rand_node]].ip_port, |
823 | close_clientlist[index[rand_node]].client_id, | 766 | dht->close_clientlist[index[rand_node]].client_id, |
824 | self_public_key ); | 767 | dht->c->self_public_key ); |
825 | close_lastgetnodes = temp_time; | 768 | dht->close_lastgetnodes = temp_time; |
826 | } | 769 | } |
827 | } | 770 | } |
828 | 771 | ||
829 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key) | 772 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) |
830 | { | 773 | { |
831 | getnodes(ip_port, public_key, self_public_key); | 774 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); |
832 | send_ping_request(ip_port, (clientid_t *) public_key); | 775 | send_ping_request(dht->ping, dht->c, ip_port, (clientid_t *) public_key); |
833 | } | 776 | } |
834 | 777 | ||
835 | /* send the given packet to node with client_id | 778 | /* send the given packet to node with client_id |
836 | * returns -1 if failure | 779 | * returns -1 if failure |
837 | */ | 780 | */ |
838 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | 781 | int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length) |
839 | { | 782 | { |
840 | uint32_t i; | 783 | uint32_t i; |
841 | 784 | ||
842 | for (i = 0; i < LCLIENT_LIST; ++i) { | 785 | for (i = 0; i < LCLIENT_LIST; ++i) { |
843 | if (id_equal(client_id, close_clientlist[i].client_id)) | 786 | if (id_equal(client_id, dht->close_clientlist[i].client_id)) |
844 | return sendpacket(close_clientlist[i].ip_port, packet, length); | 787 | return sendpacket(dht->c->lossless_udp->net->sock, dht->close_clientlist[i].ip_port, packet, length); |
845 | } | 788 | } |
846 | 789 | ||
847 | return -1; | 790 | return -1; |
@@ -853,16 +796,16 @@ int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length) | |||
853 | * return 0 if we are connected to friend or if no ips were found. | 796 | * return 0 if we are connected to friend or if no ips were found. |
854 | * returns -1 if no such friend | 797 | * returns -1 if no such friend |
855 | */ | 798 | */ |
856 | static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | 799 | static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) |
857 | { | 800 | { |
858 | int num_ips = 0; | 801 | int num_ips = 0; |
859 | uint32_t i; | 802 | uint32_t i; |
860 | uint64_t temp_time = unix_time(); | 803 | uint64_t temp_time = unix_time(); |
861 | 804 | ||
862 | if (friend_num >= num_friends) | 805 | if (friend_num >= dht->num_friends) |
863 | return -1; | 806 | return -1; |
864 | 807 | ||
865 | Friend *friend = &friends_list[friend_num]; | 808 | DHT_Friend *friend = &dht->friends_list[friend_num]; |
866 | Client_data *client; | 809 | Client_data *client; |
867 | 810 | ||
868 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 811 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
@@ -888,9 +831,9 @@ static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num) | |||
888 | * | 831 | * |
889 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. | 832 | * Only works if more than (MAX_FRIEND_CLIENTS / 2) return an ip for friend. |
890 | */ | 833 | */ |
891 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | 834 | int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
892 | { | 835 | { |
893 | int num = friend_number(friend_id); | 836 | int num = friend_number(dht, friend_id); |
894 | 837 | ||
895 | if (num == -1) | 838 | if (num == -1) |
896 | return 0; | 839 | return 0; |
@@ -898,13 +841,13 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
898 | uint32_t i, sent = 0; | 841 | uint32_t i, sent = 0; |
899 | 842 | ||
900 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 843 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
901 | int ip_num = friend_iplist(ip_list, num); | 844 | int ip_num = friend_iplist(dht, ip_list, num); |
902 | 845 | ||
903 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) | 846 | if (ip_num < (MAX_FRIEND_CLIENTS / 2)) |
904 | return 0; | 847 | return 0; |
905 | 848 | ||
906 | uint64_t temp_time = unix_time(); | 849 | uint64_t temp_time = unix_time(); |
907 | Friend *friend = &friends_list[num]; | 850 | DHT_Friend *friend = &dht->friends_list[num]; |
908 | Client_data *client; | 851 | Client_data *client; |
909 | 852 | ||
910 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { | 853 | for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { |
@@ -912,7 +855,7 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
912 | 855 | ||
913 | /*If ip is not zero and node is good */ | 856 | /*If ip is not zero and node is good */ |
914 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 857 | if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
915 | if (sendpacket(client->ip_port, packet, length) == length) | 858 | if (sendpacket(dht->c->lossless_udp->net->sock, client->ip_port, packet, length) == length) |
916 | ++sent; | 859 | ++sent; |
917 | } | 860 | } |
918 | } | 861 | } |
@@ -923,14 +866,14 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | |||
923 | /* Send the following packet to one random person who tells us they are connected to friend_id | 866 | /* Send the following packet to one random person who tells us they are connected to friend_id |
924 | * returns the number of nodes it sent the packet to | 867 | * returns the number of nodes it sent the packet to |
925 | */ | 868 | */ |
926 | static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length) | 869 | static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
927 | { | 870 | { |
928 | int num = friend_number(friend_id); | 871 | int num = friend_number(dht, friend_id); |
929 | 872 | ||
930 | if (num == -1) | 873 | if (num == -1) |
931 | return 0; | 874 | return 0; |
932 | 875 | ||
933 | Friend *friend = &friends_list[num]; | 876 | DHT_Friend *friend = &dht->friends_list[num]; |
934 | Client_data *client; | 877 | Client_data *client; |
935 | 878 | ||
936 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 879 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
@@ -951,7 +894,7 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
951 | if (n < 1) | 894 | if (n < 1) |
952 | return 0; | 895 | return 0; |
953 | 896 | ||
954 | if (sendpacket(ip_list[rand() % n], packet, length) == length) | 897 | if (sendpacket(dht->c->lossless_udp->net->sock, ip_list[rand() % n], packet, length) == length) |
955 | return 1; | 898 | return 1; |
956 | 899 | ||
957 | return 0; | 900 | return 0; |
@@ -963,14 +906,14 @@ static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
963 | * return 0 if we are connected to friend or if no ips were found. | 906 | * return 0 if we are connected to friend or if no ips were found. |
964 | * returns -1 if no such friend | 907 | * returns -1 if no such friend |
965 | */ | 908 | */ |
966 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) | 909 | int friend_ips(DHT *dht, IP_Port *ip_portlist, uint8_t *friend_id) |
967 | { | 910 | { |
968 | uint32_t i; | 911 | uint32_t i; |
969 | 912 | ||
970 | for (i = 0; i < num_friends; ++i) { | 913 | for (i = 0; i < dht->num_friends; ++i) { |
971 | /* Equal */ | 914 | /* Equal */ |
972 | if (id_equal(friends_list[i].client_id, friend_id)) | 915 | if (id_equal(dht->friends_list[i].client_id, friend_id)) |
973 | return friend_iplist(ip_portlist, i); | 916 | return friend_iplist(dht, ip_portlist, i); |
974 | } | 917 | } |
975 | 918 | ||
976 | return -1; | 919 | return -1; |
@@ -979,7 +922,7 @@ int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id) | |||
979 | /*----------------------------------------------------------------------------------*/ | 922 | /*----------------------------------------------------------------------------------*/ |
980 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ | 923 | /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ |
981 | 924 | ||
982 | static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | 925 | static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) |
983 | { | 926 | { |
984 | uint8_t data[sizeof(uint64_t) + 1]; | 927 | uint8_t data[sizeof(uint64_t) + 1]; |
985 | uint8_t packet[MAX_DATA_SIZE]; | 928 | uint8_t packet[MAX_DATA_SIZE]; |
@@ -989,15 +932,16 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
989 | data[0] = type; | 932 | data[0] = type; |
990 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); | 933 | memcpy(data + 1, &ping_id, sizeof(uint64_t)); |
991 | /* 254 is NAT ping request packet id */ | 934 | /* 254 is NAT ping request packet id */ |
992 | int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); | 935 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data, |
936 | sizeof(uint64_t) + 1, 254); | ||
993 | 937 | ||
994 | if (len == -1) | 938 | if (len == -1) |
995 | return -1; | 939 | return -1; |
996 | 940 | ||
997 | if (type == 0) /*If packet is request use many people to route it*/ | 941 | if (type == 0) /*If packet is request use many people to route it*/ |
998 | num = route_tofriend(public_key, packet, len); | 942 | num = route_tofriend(dht, public_key, packet, len); |
999 | else if (type == 1) /*If packet is response use only one person to route it*/ | 943 | else if (type == 1) /*If packet is response use only one person to route it*/ |
1000 | num = routeone_tofriend(public_key, packet, len); | 944 | num = routeone_tofriend(dht, public_key, packet, len); |
1001 | 945 | ||
1002 | if (num == 0) | 946 | if (num == 0) |
1003 | return -1; | 947 | return -1; |
@@ -1006,21 +950,22 @@ static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type) | |||
1006 | } | 950 | } |
1007 | 951 | ||
1008 | /* Handle a received ping request for */ | 952 | /* Handle a received ping request for */ |
1009 | static int handle_NATping(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 953 | static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) |
1010 | { | 954 | { |
955 | DHT *dht = object; | ||
1011 | uint64_t ping_id; | 956 | uint64_t ping_id; |
1012 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); | 957 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); |
1013 | 958 | ||
1014 | int friendnumber = friend_number(source_pubkey); | 959 | int friendnumber = friend_number(dht, source_pubkey); |
1015 | 960 | ||
1016 | if (friendnumber == -1) | 961 | if (friendnumber == -1) |
1017 | return 1; | 962 | return 1; |
1018 | 963 | ||
1019 | Friend *friend = &friends_list[friendnumber]; | 964 | DHT_Friend *friend = &dht->friends_list[friendnumber]; |
1020 | 965 | ||
1021 | if (packet[0] == 0) { | 966 | if (packet[0] == 0) { |
1022 | /* 1 is reply */ | 967 | /* 1 is reply */ |
1023 | send_NATping(source_pubkey, ping_id, 1); | 968 | send_NATping(dht, source_pubkey, ping_id, 1); |
1024 | friend->recvNATping_timestamp = unix_time(); | 969 | friend->recvNATping_timestamp = unix_time(); |
1025 | return 0; | 970 | return 0; |
1026 | } else if (packet[0] == 1) { | 971 | } else if (packet[0] == 1) { |
@@ -1082,45 +1027,45 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t | |||
1082 | return num; | 1027 | return num; |
1083 | } | 1028 | } |
1084 | 1029 | ||
1085 | static void punch_holes(IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) | 1030 | static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) |
1086 | { | 1031 | { |
1087 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) | 1032 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) |
1088 | return; | 1033 | return; |
1089 | 1034 | ||
1090 | uint32_t i; | 1035 | uint32_t i; |
1091 | uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; | 1036 | uint32_t top = dht->friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; |
1092 | 1037 | ||
1093 | for (i = friends_list[friend_num].punching_index; i != top; i++) { | 1038 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { |
1094 | /*TODO: improve port guessing algorithm*/ | 1039 | /*TODO: improve port guessing algorithm*/ |
1095 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); | 1040 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); |
1096 | IP_Port pinging = {ip, htons(port)}; | 1041 | IP_Port pinging = {ip, htons(port)}; |
1097 | send_ping_request(pinging, (clientid_t *) &friends_list[friend_num].client_id); | 1042 | send_ping_request(dht->ping, dht->c, pinging, (clientid_t *) &dht->friends_list[friend_num].client_id); |
1098 | } | 1043 | } |
1099 | 1044 | ||
1100 | friends_list[friend_num].punching_index = i; | 1045 | dht->friends_list[friend_num].punching_index = i; |
1101 | } | 1046 | } |
1102 | 1047 | ||
1103 | static void doNAT(void) | 1048 | static void do_NAT(DHT *dht) |
1104 | { | 1049 | { |
1105 | uint32_t i; | 1050 | uint32_t i; |
1106 | uint64_t temp_time = unix_time(); | 1051 | uint64_t temp_time = unix_time(); |
1107 | 1052 | ||
1108 | for (i = 0; i < num_friends; ++i) { | 1053 | for (i = 0; i < dht->num_friends; ++i) { |
1109 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; | 1054 | IP_Port ip_list[MAX_FRIEND_CLIENTS]; |
1110 | int num = friend_iplist(ip_list, i); | 1055 | int num = friend_iplist(dht, ip_list, i); |
1111 | 1056 | ||
1112 | /*If already connected or friend is not online don't try to hole punch*/ | 1057 | /*If already connected or friend is not online don't try to hole punch*/ |
1113 | if (num < MAX_FRIEND_CLIENTS / 2) | 1058 | if (num < MAX_FRIEND_CLIENTS / 2) |
1114 | continue; | 1059 | continue; |
1115 | 1060 | ||
1116 | if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { | 1061 | if (dht->friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { |
1117 | send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ | 1062 | send_NATping(dht, dht->friends_list[i].client_id, dht->friends_list[i].NATping_id, 0); /*0 is request*/ |
1118 | friends_list[i].NATping_timestamp = temp_time; | 1063 | dht->friends_list[i].NATping_timestamp = temp_time; |
1119 | } | 1064 | } |
1120 | 1065 | ||
1121 | if (friends_list[i].hole_punching == 1 && | 1066 | if (dht->friends_list[i].hole_punching == 1 && |
1122 | friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && | 1067 | dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && |
1123 | friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { | 1068 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { |
1124 | 1069 | ||
1125 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); | 1070 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); |
1126 | 1071 | ||
@@ -1129,10 +1074,10 @@ static void doNAT(void) | |||
1129 | 1074 | ||
1130 | uint16_t port_list[MAX_FRIEND_CLIENTS]; | 1075 | uint16_t port_list[MAX_FRIEND_CLIENTS]; |
1131 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); | 1076 | uint16_t numports = NAT_getports(port_list, ip_list, num, ip); |
1132 | punch_holes(ip, port_list, numports, i); | 1077 | punch_holes(dht, ip, port_list, numports, i); |
1133 | 1078 | ||
1134 | friends_list[i].punching_timestamp = temp_time; | 1079 | dht->friends_list[i].punching_timestamp = temp_time; |
1135 | friends_list[i].hole_punching = 0; | 1080 | dht->friends_list[i].hole_punching = 0; |
1136 | } | 1081 | } |
1137 | } | 1082 | } |
1138 | } | 1083 | } |
@@ -1149,7 +1094,7 @@ static void doNAT(void) | |||
1149 | network while preventing amplification attacks. | 1094 | network while preventing amplification attacks. |
1150 | return 0 if node was added | 1095 | return 0 if node was added |
1151 | return -1 if node was not added */ | 1096 | return -1 if node was not added */ |
1152 | int add_toping(uint8_t *client_id, IP_Port ip_port) | 1097 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) |
1153 | { | 1098 | { |
1154 | if (ip_port.ip.i == 0) | 1099 | if (ip_port.ip.i == 0) |
1155 | return -1; | 1100 | return -1; |
@@ -1157,19 +1102,19 @@ int add_toping(uint8_t *client_id, IP_Port ip_port) | |||
1157 | uint32_t i; | 1102 | uint32_t i; |
1158 | 1103 | ||
1159 | for (i = 0; i < MAX_TOPING; ++i) { | 1104 | for (i = 0; i < MAX_TOPING; ++i) { |
1160 | if (toping[i].ip_port.ip.i == 0) { | 1105 | if (dht->toping[i].ip_port.ip.i == 0) { |
1161 | memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1106 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1162 | toping[i].ip_port.ip.i = ip_port.ip.i; | 1107 | dht->toping[i].ip_port.ip.i = ip_port.ip.i; |
1163 | toping[i].ip_port.port = ip_port.port; | 1108 | dht->toping[i].ip_port.port = ip_port.port; |
1164 | return 0; | 1109 | return 0; |
1165 | } | 1110 | } |
1166 | } | 1111 | } |
1167 | 1112 | ||
1168 | for (i = 0; i < MAX_TOPING; ++i) { | 1113 | for (i = 0; i < MAX_TOPING; ++i) { |
1169 | if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) { | 1114 | if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { |
1170 | memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1115 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1171 | toping[i].ip_port.ip.i = ip_port.ip.i; | 1116 | dht->toping[i].ip_port.ip.i = ip_port.ip.i; |
1172 | toping[i].ip_port.port = ip_port.port; | 1117 | dht->toping[i].ip_port.port = ip_port.port; |
1173 | return 0; | 1118 | return 0; |
1174 | } | 1119 | } |
1175 | } | 1120 | } |
@@ -1179,68 +1124,89 @@ int add_toping(uint8_t *client_id, IP_Port ip_port) | |||
1179 | 1124 | ||
1180 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds | 1125 | /*Ping all the valid nodes in the toping list every TIME_TOPING seconds |
1181 | this function must be run at least once every TIME_TOPING seconds*/ | 1126 | this function must be run at least once every TIME_TOPING seconds*/ |
1182 | static void do_toping() | 1127 | static void do_toping(DHT *dht) |
1183 | { | 1128 | { |
1184 | uint64_t temp_time = unix_time(); | 1129 | uint64_t temp_time = unix_time(); |
1185 | 1130 | ||
1186 | if (!is_timeout(temp_time, last_toping, TIME_TOPING)) | 1131 | if (!is_timeout(temp_time, dht->last_toping, TIME_TOPING)) |
1187 | return; | 1132 | return; |
1188 | 1133 | ||
1189 | last_toping = temp_time; | 1134 | dht->last_toping = temp_time; |
1190 | uint32_t i; | 1135 | uint32_t i; |
1191 | 1136 | ||
1192 | for (i = 0; i < MAX_TOPING; ++i) { | 1137 | for (i = 0; i < MAX_TOPING; ++i) { |
1193 | if (toping[i].ip_port.ip.i == 0) | 1138 | if (dht->toping[i].ip_port.ip.i == 0) |
1194 | return; | 1139 | return; |
1195 | 1140 | ||
1196 | send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id); | 1141 | send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, (clientid_t *) dht->toping[i].client_id); |
1197 | toping[i].ip_port.ip.i = 0; | 1142 | dht->toping[i].ip_port.ip.i = 0; |
1198 | } | 1143 | } |
1199 | } | 1144 | } |
1200 | 1145 | ||
1201 | 1146 | ||
1202 | void DHT_init(void) | 1147 | DHT *new_DHT(Net_Crypto *c) |
1203 | { | 1148 | { |
1204 | networking_registerhandler(0, &handle_ping_request); | 1149 | if (c == NULL) |
1205 | networking_registerhandler(1, &handle_ping_response); | 1150 | return NULL; |
1206 | networking_registerhandler(2, &handle_getnodes); | 1151 | |
1207 | networking_registerhandler(3, &handle_sendnodes); | 1152 | DHT *temp = calloc(1, sizeof(DHT)); |
1208 | cryptopacket_registerhandler(254, &handle_NATping); | 1153 | |
1154 | if (temp == NULL) | ||
1155 | return NULL; | ||
1156 | |||
1157 | temp->ping = new_ping(); | ||
1158 | |||
1159 | if (temp->ping == NULL) { | ||
1160 | kill_DHT(temp); | ||
1161 | return NULL; | ||
1162 | } | ||
1163 | |||
1164 | temp->c = c; | ||
1165 | networking_registerhandler(c->lossless_udp->net, 0, &handle_ping_request, temp); | ||
1166 | networking_registerhandler(c->lossless_udp->net, 1, &handle_ping_response, temp); | ||
1167 | networking_registerhandler(c->lossless_udp->net, 2, &handle_getnodes, temp); | ||
1168 | networking_registerhandler(c->lossless_udp->net, 3, &handle_sendnodes, temp); | ||
1169 | cryptopacket_registerhandler(c, 254, &handle_NATping, temp); | ||
1170 | return temp; | ||
1209 | } | 1171 | } |
1210 | 1172 | ||
1211 | void doDHT(void) | 1173 | void do_DHT(DHT *dht) |
1212 | { | 1174 | { |
1213 | doClose(); | 1175 | do_Close(dht); |
1214 | doDHTFriends(); | 1176 | do_DHT_friends(dht); |
1215 | doNAT(); | 1177 | do_NAT(dht); |
1216 | do_toping(); | 1178 | do_toping(dht); |
1179 | } | ||
1180 | void kill_DHT(DHT *dht) | ||
1181 | { | ||
1182 | kill_ping(dht->ping); | ||
1183 | free(dht->friends_list); | ||
1184 | free(dht); | ||
1217 | } | 1185 | } |
1218 | 1186 | ||
1219 | /* get the size of the DHT (for saving) */ | 1187 | /* get the size of the DHT (for saving) */ |
1220 | uint32_t DHT_size(void) | 1188 | uint32_t DHT_size(DHT *dht) |
1221 | { | 1189 | { |
1222 | return sizeof(close_clientlist) + sizeof(Friend) * num_friends; | 1190 | return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends; |
1223 | } | 1191 | } |
1224 | 1192 | ||
1225 | /* save the DHT in data where data is an array of size DHT_size() */ | 1193 | /* save the DHT in data where data is an array of size DHT_size() */ |
1226 | void DHT_save(uint8_t *data) | 1194 | void DHT_save(DHT *dht, uint8_t *data) |
1227 | { | 1195 | { |
1228 | memcpy(data, close_clientlist, sizeof(close_clientlist)); | 1196 | memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist)); |
1229 | memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends); | 1197 | memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); |
1230 | } | 1198 | } |
1231 | 1199 | ||
1232 | /* load the DHT from data of size size; | 1200 | /* load the DHT from data of size size; |
1233 | * return -1 if failure | 1201 | * return -1 if failure |
1234 | * return 0 if success | 1202 | * return 0 if success |
1235 | */ | 1203 | */ |
1236 | int DHT_load(uint8_t *data, uint32_t size) | 1204 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size) |
1237 | { | 1205 | { |
1238 | init_ping(); | 1206 | if (size < sizeof(dht->close_clientlist)) |
1239 | |||
1240 | if (size < sizeof(close_clientlist)) | ||
1241 | return -1; | 1207 | return -1; |
1242 | 1208 | ||
1243 | if ((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) | 1209 | if ((size - sizeof(dht->close_clientlist)) % sizeof(DHT_Friend) != 0) |
1244 | return -1; | 1210 | return -1; |
1245 | 1211 | ||
1246 | uint32_t i, j; | 1212 | uint32_t i, j; |
@@ -1249,19 +1215,19 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1249 | 1215 | ||
1250 | Client_data *client; | 1216 | Client_data *client; |
1251 | 1217 | ||
1252 | temp = (size - sizeof(close_clientlist)) / sizeof(Friend); | 1218 | temp = (size - sizeof(dht->close_clientlist)) / sizeof(DHT_Friend); |
1253 | 1219 | ||
1254 | if (temp != 0) { | 1220 | if (temp != 0) { |
1255 | Friend *tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); | 1221 | DHT_Friend *tempfriends_list = (DHT_Friend *)(data + sizeof(dht->close_clientlist)); |
1256 | 1222 | ||
1257 | for (i = 0; i < temp; ++i) { | 1223 | for (i = 0; i < temp; ++i) { |
1258 | DHT_addfriend(tempfriends_list[i].client_id); | 1224 | DHT_addfriend(dht, tempfriends_list[i].client_id); |
1259 | 1225 | ||
1260 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 1226 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
1261 | client = &tempfriends_list[i].client_list[j]; | 1227 | client = &tempfriends_list[i].client_list[j]; |
1262 | 1228 | ||
1263 | if (client->timestamp != 0) | 1229 | if (client->timestamp != 0) |
1264 | getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id); | 1230 | getnodes(dht, client->ip_port, client->client_id, tempfriends_list[i].client_id); |
1265 | } | 1231 | } |
1266 | } | 1232 | } |
1267 | } | 1233 | } |
@@ -1270,8 +1236,8 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1270 | 1236 | ||
1271 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1237 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1272 | if (tempclose_clientlist[i].timestamp != 0) | 1238 | if (tempclose_clientlist[i].timestamp != 0) |
1273 | DHT_bootstrap( tempclose_clientlist[i].ip_port, | 1239 | DHT_bootstrap(dht, tempclose_clientlist[i].ip_port, |
1274 | tempclose_clientlist[i].client_id ); | 1240 | tempclose_clientlist[i].client_id ); |
1275 | } | 1241 | } |
1276 | 1242 | ||
1277 | return 0; | 1243 | return 0; |
@@ -1280,13 +1246,13 @@ int DHT_load(uint8_t *data, uint32_t size) | |||
1280 | /* returns 0 if we are not connected to the DHT | 1246 | /* returns 0 if we are not connected to the DHT |
1281 | * returns 1 if we are | 1247 | * returns 1 if we are |
1282 | */ | 1248 | */ |
1283 | int DHT_isconnected(void) | 1249 | int DHT_isconnected(DHT *dht) |
1284 | { | 1250 | { |
1285 | uint32_t i; | 1251 | uint32_t i; |
1286 | uint64_t temp_time = unix_time(); | 1252 | uint64_t temp_time = unix_time(); |
1287 | 1253 | ||
1288 | for (i = 0; i < LCLIENT_LIST; ++i) { | 1254 | for (i = 0; i < LCLIENT_LIST; ++i) { |
1289 | if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) | 1255 | if (!is_timeout(temp_time, dht->close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) |
1290 | return 1; | 1256 | return 1; |
1291 | } | 1257 | } |
1292 | 1258 | ||
@@ -34,6 +34,20 @@ extern "C" { | |||
34 | /* size of the client_id in bytes */ | 34 | /* size of the client_id in bytes */ |
35 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES | 35 | #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES |
36 | 36 | ||
37 | /* maximum number of clients stored per friend. */ | ||
38 | #define MAX_FRIEND_CLIENTS 8 | ||
39 | |||
40 | /* A list of the clients mathematically closest to ours. */ | ||
41 | #define LCLIENT_LIST 32 | ||
42 | |||
43 | /* The list of ip ports along with the ping_id of what we sent them and a timestamp */ | ||
44 | #define LPING_ARRAY 256 //NOTE Deprecated (doesn't do anything) | ||
45 | |||
46 | #define LSEND_NODES_ARRAY LPING_ARRAY/2 | ||
47 | |||
48 | /*Maximum newly announced nodes to ping per TIME_TOPING seconds*/ | ||
49 | #define MAX_TOPING 16 | ||
50 | |||
37 | typedef struct { | 51 | typedef struct { |
38 | uint8_t client_id[CLIENT_ID_SIZE]; | 52 | uint8_t client_id[CLIENT_ID_SIZE]; |
39 | IP_Port ip_port; | 53 | IP_Port ip_port; |
@@ -45,19 +59,64 @@ typedef struct { | |||
45 | uint64_t ret_timestamp; | 59 | uint64_t ret_timestamp; |
46 | } Client_data; | 60 | } Client_data; |
47 | 61 | ||
48 | Client_data *DHT_get_close_list(void); | 62 | /*----------------------------------------------------------------------------------*/ |
63 | |||
64 | typedef struct { | ||
65 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
66 | Client_data client_list[MAX_FRIEND_CLIENTS]; | ||
67 | |||
68 | /* time at which the last get_nodes request was sent. */ | ||
69 | uint64_t lastgetnode; | ||
70 | |||
71 | /* Symetric NAT hole punching stuff */ | ||
72 | |||
73 | /* 1 if currently hole punching, otherwise 0 */ | ||
74 | uint8_t hole_punching; | ||
75 | uint32_t punching_index; | ||
76 | uint64_t punching_timestamp; | ||
77 | uint64_t recvNATping_timestamp; | ||
78 | uint64_t NATping_id; | ||
79 | uint64_t NATping_timestamp; | ||
80 | } DHT_Friend; | ||
81 | |||
82 | typedef struct { | ||
83 | uint8_t client_id[CLIENT_ID_SIZE]; | ||
84 | IP_Port ip_port; | ||
85 | } Node_format; | ||
86 | |||
87 | typedef struct { | ||
88 | IP_Port ip_port; | ||
89 | uint64_t ping_id; | ||
90 | uint64_t timestamp; | ||
91 | } Pinged; | ||
92 | |||
93 | /*----------------------------------------------------------------------------------*/ | ||
94 | typedef struct { | ||
95 | Net_Crypto *c; | ||
96 | Client_data close_clientlist[LCLIENT_LIST]; | ||
97 | DHT_Friend *friends_list; | ||
98 | uint16_t num_friends; | ||
99 | Pinged send_nodes[LSEND_NODES_ARRAY]; | ||
100 | Node_format toping[MAX_TOPING]; | ||
101 | uint64_t last_toping; | ||
102 | uint64_t close_lastgetnodes; | ||
103 | void *ping; | ||
104 | } DHT; | ||
105 | /*----------------------------------------------------------------------------------*/ | ||
106 | |||
107 | Client_data *DHT_get_close_list(DHT *dht); | ||
49 | 108 | ||
50 | /* Add a new friend to the friends list | 109 | /* Add a new friend to the friends list |
51 | client_id must be CLIENT_ID_SIZE bytes long. | 110 | client_id must be CLIENT_ID_SIZE bytes long. |
52 | returns 0 if success | 111 | returns 0 if success |
53 | returns 1 if failure (friends list is full) */ | 112 | returns 1 if failure (friends list is full) */ |
54 | int DHT_addfriend(uint8_t *client_id); | 113 | int DHT_addfriend(DHT *dht, uint8_t *client_id); |
55 | 114 | ||
56 | /* Delete a friend from the friends list | 115 | /* Delete a friend from the friends list |
57 | client_id must be CLIENT_ID_SIZE bytes long. | 116 | client_id must be CLIENT_ID_SIZE bytes long. |
58 | returns 0 if success | 117 | returns 0 if success |
59 | returns 1 if failure (client_id not in friends list) */ | 118 | returns 1 if failure (client_id not in friends list) */ |
60 | int DHT_delfriend(uint8_t *client_id); | 119 | int DHT_delfriend(DHT *dht, uint8_t *client_id); |
61 | 120 | ||
62 | /* Get ip of friend | 121 | /* Get ip of friend |
63 | client_id must be CLIENT_ID_SIZE bytes long. | 122 | client_id must be CLIENT_ID_SIZE bytes long. |
@@ -66,14 +125,14 @@ int DHT_delfriend(uint8_t *client_id); | |||
66 | returns ip if success | 125 | returns ip if success |
67 | returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) | 126 | returns ip of 0 if failure (This means the friend is either offline or we have not found him yet.) |
68 | returns ip of 1 if friend is not in list. */ | 127 | returns ip of 1 if friend is not in list. */ |
69 | IP_Port DHT_getfriendip(uint8_t *client_id); | 128 | IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id); |
70 | 129 | ||
71 | /* Run this function at least a couple times per second (It's the main loop) */ | 130 | /* Run this function at least a couple times per second (It's the main loop) */ |
72 | void doDHT(void); | 131 | void do_DHT(DHT *dht); |
73 | 132 | ||
74 | /* Use this function to bootstrap the client | 133 | /* Use this function to bootstrap the client |
75 | Sends a get nodes request to the given node with ip port and public_key */ | 134 | Sends a get nodes request to the given node with ip port and public_key */ |
76 | void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); | 135 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); |
77 | 136 | ||
78 | /* Add nodes to the toping list | 137 | /* Add nodes to the toping list |
79 | all nodes in this list are pinged every TIME_TOPING seconds | 138 | all nodes in this list are pinged every TIME_TOPING seconds |
@@ -83,17 +142,17 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key); | |||
83 | network while preventing amplification attacks. | 142 | network while preventing amplification attacks. |
84 | return 0 if node was added | 143 | return 0 if node was added |
85 | return -1 if node was not added */ | 144 | return -1 if node was not added */ |
86 | int add_toping(uint8_t *client_id, IP_Port ip_port); | 145 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port); |
87 | 146 | ||
88 | /* ROUTING FUNCTIONS */ | 147 | /* ROUTING FUNCTIONS */ |
89 | 148 | ||
90 | /* send the given packet to node with client_id | 149 | /* send the given packet to node with client_id |
91 | returns -1 if failure */ | 150 | returns -1 if failure */ |
92 | int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length); | 151 | int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length); |
93 | 152 | ||
94 | /* Send the following packet to everyone who tells us they are connected to friend_id | 153 | /* Send the following packet to everyone who tells us they are connected to friend_id |
95 | returns the number of nodes it sent the packet to */ | 154 | returns the number of nodes it sent the packet to */ |
96 | int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); | 155 | int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length); |
97 | 156 | ||
98 | /* NAT PUNCHING FUNCTIONS */ | 157 | /* NAT PUNCHING FUNCTIONS */ |
99 | 158 | ||
@@ -101,29 +160,31 @@ int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length); | |||
101 | ip_portlist must be at least MAX_FRIEND_CLIENTS big | 160 | ip_portlist must be at least MAX_FRIEND_CLIENTS big |
102 | returns the number of ips returned | 161 | returns the number of ips returned |
103 | returns -1 if no such friend*/ | 162 | returns -1 if no such friend*/ |
104 | int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id); | 163 | int friend_ips(DHT *dht, IP_Port *ip_portlist, uint8_t *friend_id); |
105 | 164 | ||
106 | /* SAVE/LOAD functions */ | 165 | /* SAVE/LOAD functions */ |
107 | 166 | ||
108 | /* get the size of the DHT (for saving) */ | 167 | /* get the size of the DHT (for saving) */ |
109 | uint32_t DHT_size(void); | 168 | uint32_t DHT_size(DHT *dht); |
110 | 169 | ||
111 | /* save the DHT in data where data is an array of size DHT_size() */ | 170 | /* save the DHT in data where data is an array of size DHT_size() */ |
112 | void DHT_save(uint8_t *data); | 171 | void DHT_save(DHT *dht, uint8_t *data); |
113 | 172 | ||
114 | /* init DHT */ | 173 | /* init DHT */ |
115 | void DHT_init(void); | 174 | DHT *new_DHT(Net_Crypto *c); |
175 | |||
176 | void kill_DHT(DHT *dht); | ||
116 | 177 | ||
117 | /* load the DHT from data of size size; | 178 | /* load the DHT from data of size size; |
118 | return -1 if failure | 179 | return -1 if failure |
119 | return 0 if success */ | 180 | return 0 if success */ |
120 | int DHT_load(uint8_t *data, uint32_t size); | 181 | int DHT_load(DHT *dht, uint8_t *data, uint32_t size); |
121 | 182 | ||
122 | /* returns 0 if we are not connected to the DHT | 183 | /* returns 0 if we are not connected to the DHT |
123 | returns 1 if we are */ | 184 | returns 1 if we are */ |
124 | int DHT_isconnected(); | 185 | int DHT_isconnected(DHT *dht); |
125 | 186 | ||
126 | void addto_lists(IP_Port ip_port, uint8_t *client_id); | 187 | void addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id); |
127 | 188 | ||
128 | #ifdef __cplusplus | 189 | #ifdef __cplusplus |
129 | } | 190 | } |
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c index ad1337ef..cbbb384b 100644 --- a/core/LAN_discovery.c +++ b/core/LAN_discovery.c | |||
@@ -121,30 +121,32 @@ static int LAN_ip(IP ip) | |||
121 | return -1; | 121 | return -1; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int handle_LANdiscovery(IP_Port source, uint8_t *packet, uint32_t length) | 124 | static int handle_LANdiscovery(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
125 | { | 125 | { |
126 | DHT *dht = object; | ||
127 | |||
126 | if (LAN_ip(source.ip) == -1) | 128 | if (LAN_ip(source.ip) == -1) |
127 | return 1; | 129 | return 1; |
128 | 130 | ||
129 | if (length != crypto_box_PUBLICKEYBYTES + 1) | 131 | if (length != crypto_box_PUBLICKEYBYTES + 1) |
130 | return 1; | 132 | return 1; |
131 | 133 | ||
132 | DHT_bootstrap(source, packet + 1); | 134 | DHT_bootstrap(dht, source, packet + 1); |
133 | return 0; | 135 | return 0; |
134 | } | 136 | } |
135 | 137 | ||
136 | 138 | ||
137 | int send_LANdiscovery(uint16_t port) | 139 | int send_LANdiscovery(uint16_t port, Net_Crypto *c) |
138 | { | 140 | { |
139 | uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; | 141 | uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; |
140 | data[0] = 33; | 142 | data[0] = 33; |
141 | memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 143 | memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); |
142 | IP_Port ip_port = {broadcast_ip(), port}; | 144 | IP_Port ip_port = {broadcast_ip(), port}; |
143 | return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); | 145 | return sendpacket(c->lossless_udp->net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); |
144 | } | 146 | } |
145 | 147 | ||
146 | 148 | ||
147 | void LANdiscovery_init(void) | 149 | void LANdiscovery_init(DHT *dht) |
148 | { | 150 | { |
149 | networking_registerhandler(33, &handle_LANdiscovery); | 151 | networking_registerhandler(dht->c->lossless_udp->net, 33, &handle_LANdiscovery, dht); |
150 | } | 152 | } |
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h index 6b5b8c75..5a790331 100644 --- a/core/LAN_discovery.h +++ b/core/LAN_discovery.h | |||
@@ -40,11 +40,11 @@ extern "C" { | |||
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /*Send a LAN discovery pcaket to the broadcast address with port port*/ | 42 | /*Send a LAN discovery pcaket to the broadcast address with port port*/ |
43 | int send_LANdiscovery(uint16_t port); | 43 | int send_LANdiscovery(uint16_t port, Net_Crypto *c); |
44 | 44 | ||
45 | 45 | ||
46 | /* sets up packet handlers */ | 46 | /* sets up packet handlers */ |
47 | void LANdiscovery_init(void); | 47 | void LANdiscovery_init(DHT *dht); |
48 | 48 | ||
49 | 49 | ||
50 | 50 | ||
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index 506a06eb..15e8dea3 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -28,97 +28,6 @@ | |||
28 | 28 | ||
29 | #include "Lossless_UDP.h" | 29 | #include "Lossless_UDP.h" |
30 | 30 | ||
31 | /* maximum data packets in sent and receive queues. */ | ||
32 | #define MAX_QUEUE_NUM 16 | ||
33 | |||
34 | /* maximum number of data packets in the buffer */ | ||
35 | #define BUFFER_PACKET_NUM (16-1) | ||
36 | |||
37 | /* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ | ||
38 | #define CONNEXION_TIMEOUT 5 | ||
39 | |||
40 | /* initial amount of sync/hanshake packets to send per second. */ | ||
41 | #define SYNC_RATE 2 | ||
42 | |||
43 | /* initial send rate of data. */ | ||
44 | #define DATA_SYNC_RATE 30 | ||
45 | |||
46 | typedef struct { | ||
47 | uint8_t data[MAX_DATA_SIZE]; | ||
48 | uint16_t size; | ||
49 | } Data; | ||
50 | |||
51 | typedef struct { | ||
52 | IP_Port ip_port; | ||
53 | |||
54 | /* | ||
55 | * 0 if connection is dead, 1 if attempting handshake, | ||
56 | * 2 if handshake is done (we start sending SYNC packets) | ||
57 | * 3 if we are sending SYNC packets and can send data | ||
58 | * 4 if the connection has timed out. | ||
59 | */ | ||
60 | uint8_t status; | ||
61 | |||
62 | /* | ||
63 | * 1 or 2 if connection was initiated by someone else, 0 if not. | ||
64 | * 2 if incoming_connection() has not returned it yet, 1 if it has. | ||
65 | */ | ||
66 | uint8_t inbound; | ||
67 | |||
68 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | ||
69 | uint16_t data_rate; /* current data packet send rate packets per second. */ | ||
70 | |||
71 | uint64_t last_SYNC; /* time our last SYNC packet was sent. */ | ||
72 | uint64_t last_sent; /* time our last data or handshake packet was sent. */ | ||
73 | uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */ | ||
74 | uint64_t last_recvdata; /* time we last received a DATA packet from the other */ | ||
75 | uint64_t killat; /* time to kill the connection */ | ||
76 | |||
77 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | ||
78 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | ||
79 | |||
80 | uint32_t handshake_id1; | ||
81 | uint32_t handshake_id2; | ||
82 | |||
83 | /* number of data packets received (also used as handshake_id1) */ | ||
84 | uint32_t recv_packetnum; | ||
85 | |||
86 | /* number of packets received by the other peer */ | ||
87 | uint32_t orecv_packetnum; | ||
88 | |||
89 | /* number of data packets sent */ | ||
90 | uint32_t sent_packetnum; | ||
91 | |||
92 | /* number of packets sent by the other peer. */ | ||
93 | uint32_t osent_packetnum; | ||
94 | |||
95 | /* number of latest packet written onto the sendbuffer */ | ||
96 | uint32_t sendbuff_packetnum; | ||
97 | |||
98 | /* we know all packets before that number were successfully sent */ | ||
99 | uint32_t successful_sent; | ||
100 | |||
101 | /* packet number of last packet read with the read_packet function */ | ||
102 | uint32_t successful_read; | ||
103 | |||
104 | /* list of currently requested packet numbers(by the other person) */ | ||
105 | uint32_t req_packets[BUFFER_PACKET_NUM]; | ||
106 | |||
107 | /* total number of currently requested packets(by the other person) */ | ||
108 | uint16_t num_req_paquets; | ||
109 | |||
110 | uint8_t recv_counter; | ||
111 | uint8_t send_counter; | ||
112 | uint8_t timeout; /* connection timeout in seconds. */ | ||
113 | } Connection; | ||
114 | |||
115 | |||
116 | static Connection *connections; | ||
117 | |||
118 | static uint32_t connections_length; /* Length of connections array */ | ||
119 | static uint32_t connections_number; /* Number of connections in connections array */ | ||
120 | |||
121 | #define MAX_CONNECTIONS connections_length | ||
122 | 31 | ||
123 | /* Functions */ | 32 | /* Functions */ |
124 | 33 | ||
@@ -127,22 +36,20 @@ static uint32_t connections_number; /* Number of connections in connections arra | |||
127 | * Return -1 if there are no connections like we are looking for | 36 | * Return -1 if there are no connections like we are looking for |
128 | * Return id if it found it | 37 | * Return id if it found it |
129 | */ | 38 | */ |
130 | int getconnection_id(IP_Port ip_port) | 39 | int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) |
131 | { | 40 | { |
132 | uint32_t i; | 41 | uint32_t i; |
133 | 42 | ||
134 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 43 | for (i = 0; i < ludp->connections_length; ++i) { |
135 | if (connections[i].ip_port.ip.i == ip_port.ip.i && | 44 | if (ludp->connections[i].ip_port.ip.i == ip_port.ip.i && |
136 | connections[i].ip_port.port == ip_port.port && | 45 | ludp->connections[i].ip_port.port == ip_port.port && |
137 | connections[i].status > 0) | 46 | ludp->connections[i].status > 0) |
138 | return i; | 47 | return i; |
139 | } | 48 | } |
140 | 49 | ||
141 | return -1; | 50 | return -1; |
142 | } | 51 | } |
143 | 52 | ||
144 | /* table of random numbers used below. */ | ||
145 | static uint32_t randtable[6][256]; | ||
146 | 53 | ||
147 | /* | 54 | /* |
148 | * Generate a handshake_id which depends on the ip_port. | 55 | * Generate a handshake_id which depends on the ip_port. |
@@ -150,15 +57,15 @@ static uint32_t randtable[6][256]; | |||
150 | * | 57 | * |
151 | * TODO: make this better | 58 | * TODO: make this better |
152 | */ | 59 | */ |
153 | static uint32_t handshake_id(IP_Port source) | 60 | static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) |
154 | { | 61 | { |
155 | uint32_t id = 0, i; | 62 | uint32_t id = 0, i; |
156 | 63 | ||
157 | for (i = 0; i < 6; ++i) { | 64 | for (i = 0; i < 6; ++i) { |
158 | if (randtable[i][((uint8_t *)&source)[i]] == 0) | 65 | if (ludp->randtable[i][((uint8_t *)&source)[i]] == 0) |
159 | randtable[i][((uint8_t *)&source)[i]] = random_int(); | 66 | ludp->randtable[i][((uint8_t *)&source)[i]] = random_int(); |
160 | 67 | ||
161 | id ^= randtable[i][((uint8_t *)&source)[i]]; | 68 | id ^= ludp->randtable[i][((uint8_t *)&source)[i]]; |
162 | } | 69 | } |
163 | 70 | ||
164 | if (id == 0) /* id can't be zero */ | 71 | if (id == 0) /* id can't be zero */ |
@@ -172,10 +79,10 @@ static uint32_t handshake_id(IP_Port source) | |||
172 | * | 79 | * |
173 | * TODO: make this better | 80 | * TODO: make this better |
174 | */ | 81 | */ |
175 | static void change_handshake(IP_Port source) | 82 | static void change_handshake(Lossless_UDP *ludp, IP_Port source) |
176 | { | 83 | { |
177 | uint8_t rand = random_int() % 4; | 84 | uint8_t rand = random_int() % 4; |
178 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); | 85 | ludp->randtable[rand][((uint8_t *)&source)[rand]] = random_int(); |
179 | } | 86 | } |
180 | 87 | ||
181 | /* | 88 | /* |
@@ -184,33 +91,33 @@ static void change_handshake(IP_Port source) | |||
184 | * Return -1 if it could not initialize the connectiont | 91 | * Return -1 if it could not initialize the connectiont |
185 | * If there already was an existing connection to that ip_port return its number. | 92 | * If there already was an existing connection to that ip_port return its number. |
186 | */ | 93 | */ |
187 | int new_connection(IP_Port ip_port) | 94 | int new_connection(Lossless_UDP *ludp, IP_Port ip_port) |
188 | { | 95 | { |
189 | int connect = getconnection_id(ip_port); | 96 | int connect = getconnection_id(ludp, ip_port); |
190 | 97 | ||
191 | if (connect != -1) | 98 | if (connect != -1) |
192 | return connect; | 99 | return connect; |
193 | 100 | ||
194 | if (connections_number == connections_length) { | 101 | if (ludp->connections_number == ludp->connections_length) { |
195 | Connection *temp; | 102 | Connection *temp; |
196 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 103 | temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1)); |
197 | 104 | ||
198 | if (temp == NULL) | 105 | if (temp == NULL) |
199 | return -1; | 106 | return -1; |
200 | 107 | ||
201 | memset(&temp[connections_length], 0, sizeof(Connection)); | 108 | memset(&temp[ludp->connections_length], 0, sizeof(Connection)); |
202 | ++connections_length; | 109 | ++ludp->connections_length; |
203 | connections = temp; | 110 | ludp->connections = temp; |
204 | } | 111 | } |
205 | 112 | ||
206 | uint32_t i; | 113 | uint32_t i; |
207 | 114 | ||
208 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 115 | for (i = 0; i < ludp->connections_length; ++i) { |
209 | if (connections[i].status == 0) { | 116 | if (ludp->connections[i].status == 0) { |
210 | memset(&connections[i], 0, sizeof(Connection)); | 117 | memset(&ludp->connections[i], 0, sizeof(Connection)); |
211 | uint32_t handshake_id1 = handshake_id(ip_port); | 118 | uint32_t handshake_id1 = handshake_id(ludp, ip_port); |
212 | 119 | ||
213 | connections[i] = (Connection) { | 120 | ludp->connections[i] = (Connection) { |
214 | .ip_port = ip_port, | 121 | .ip_port = ip_port, |
215 | .status = 1, | 122 | .status = 1, |
216 | .inbound = 0, | 123 | .inbound = 0, |
@@ -227,7 +134,7 @@ int new_connection(IP_Port ip_port) | |||
227 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 134 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ |
228 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT | 135 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT |
229 | }; | 136 | }; |
230 | ++connections_number; | 137 | ++ludp->connections_number; |
231 | 138 | ||
232 | return i; | 139 | return i; |
233 | } | 140 | } |
@@ -241,31 +148,31 @@ int new_connection(IP_Port ip_port) | |||
241 | * Returns an integer corresponding to the connection id. | 148 | * Returns an integer corresponding to the connection id. |
242 | * Return -1 if it could not initialize the connection. | 149 | * Return -1 if it could not initialize the connection. |
243 | */ | 150 | */ |
244 | static int new_inconnection(IP_Port ip_port) | 151 | static int new_inconnection(Lossless_UDP *ludp, IP_Port ip_port) |
245 | { | 152 | { |
246 | if (getconnection_id(ip_port) != -1) | 153 | if (getconnection_id(ludp, ip_port) != -1) |
247 | return -1; | 154 | return -1; |
248 | 155 | ||
249 | if (connections_number == connections_length) { | 156 | if (ludp->connections_number == ludp->connections_length) { |
250 | Connection *temp; | 157 | Connection *temp; |
251 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 158 | temp = realloc(ludp->connections, sizeof(Connection) * (ludp->connections_length + 1)); |
252 | 159 | ||
253 | if (temp == NULL) | 160 | if (temp == NULL) |
254 | return -1; | 161 | return -1; |
255 | 162 | ||
256 | memset(&temp[connections_length], 0, sizeof(Connection)); | 163 | memset(&temp[ludp->connections_length], 0, sizeof(Connection)); |
257 | ++connections_length; | 164 | ++ludp->connections_length; |
258 | connections = temp; | 165 | ludp->connections = temp; |
259 | } | 166 | } |
260 | 167 | ||
261 | uint32_t i; | 168 | uint32_t i; |
262 | 169 | ||
263 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 170 | for (i = 0; i < ludp->connections_length; ++i) { |
264 | if (connections[i].status == 0) { | 171 | if (ludp->connections[i].status == 0) { |
265 | memset(&connections[i], 0, sizeof(Connection)); | 172 | memset(&ludp->connections[i], 0, sizeof(Connection)); |
266 | uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 173 | uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; |
267 | 174 | ||
268 | connections[i] = (Connection) { | 175 | ludp->connections[i] = (Connection) { |
269 | .ip_port = ip_port, | 176 | .ip_port = ip_port, |
270 | .status = 2, | 177 | .status = 2, |
271 | .inbound = 2, | 178 | .inbound = 2, |
@@ -281,7 +188,7 @@ static int new_inconnection(IP_Port ip_port) | |||
281 | /* if this connection isn't handled within the timeout kill it. */ | 188 | /* if this connection isn't handled within the timeout kill it. */ |
282 | .killat = current_time() + 1000000UL * timeout | 189 | .killat = current_time() + 1000000UL * timeout |
283 | }; | 190 | }; |
284 | ++connections_number; | 191 | ++ludp->connections_number; |
285 | return i; | 192 | return i; |
286 | } | 193 | } |
287 | } | 194 | } |
@@ -293,13 +200,13 @@ static int new_inconnection(IP_Port ip_port) | |||
293 | * Returns an integer corresponding to the next connection in our incoming connection list. | 200 | * Returns an integer corresponding to the next connection in our incoming connection list. |
294 | * Return -1 if there are no new incoming connections in the list. | 201 | * Return -1 if there are no new incoming connections in the list. |
295 | */ | 202 | */ |
296 | int incoming_connection(void) | 203 | int incoming_connection(Lossless_UDP *ludp) |
297 | { | 204 | { |
298 | uint32_t i; | 205 | uint32_t i; |
299 | 206 | ||
300 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 207 | for (i = 0; i < ludp->connections_length; ++i) { |
301 | if (connections[i].inbound == 2) { | 208 | if (ludp->connections[i].inbound == 2) { |
302 | connections[i].inbound = 1; | 209 | ludp->connections[i].inbound = 1; |
303 | return i; | 210 | return i; |
304 | } | 211 | } |
305 | } | 212 | } |
@@ -308,46 +215,46 @@ int incoming_connection(void) | |||
308 | } | 215 | } |
309 | 216 | ||
310 | /* Try to free some memory from the connections array. */ | 217 | /* Try to free some memory from the connections array. */ |
311 | static void free_connections(void) | 218 | static void free_connections(Lossless_UDP *ludp) |
312 | { | 219 | { |
313 | uint32_t i; | 220 | uint32_t i; |
314 | 221 | ||
315 | for (i = connections_length; i != 0; --i) | 222 | for (i = ludp->connections_length; i != 0; --i) |
316 | if (connections[i - 1].status != 0) | 223 | if (ludp->connections[i - 1].status != 0) |
317 | break; | 224 | break; |
318 | 225 | ||
319 | if (connections_length == i) | 226 | if (ludp->connections_length == i) |
320 | return; | 227 | return; |
321 | 228 | ||
322 | if (i == 0) { | 229 | if (i == 0) { |
323 | free(connections); | 230 | free(ludp->connections); |
324 | connections = NULL; | 231 | ludp->connections = NULL; |
325 | connections_length = i; | 232 | ludp->connections_length = i; |
326 | return; | 233 | return; |
327 | } | 234 | } |
328 | 235 | ||
329 | Connection *temp; | 236 | Connection *temp; |
330 | temp = realloc(connections, sizeof(Connection) * i); | 237 | temp = realloc(ludp->connections, sizeof(Connection) * i); |
331 | 238 | ||
332 | if (temp == NULL && i != 0) | 239 | if (temp == NULL && i != 0) |
333 | return; | 240 | return; |
334 | 241 | ||
335 | connections = temp; | 242 | ludp->connections = temp; |
336 | connections_length = i; | 243 | ludp->connections_length = i; |
337 | } | 244 | } |
338 | 245 | ||
339 | /* | 246 | /* |
340 | * Return -1 if it could not kill the connection. | 247 | * Return -1 if it could not kill the connection. |
341 | * Return 0 if killed successfully | 248 | * Return 0 if killed successfully |
342 | */ | 249 | */ |
343 | int kill_connection(int connection_id) | 250 | int kill_connection(Lossless_UDP *ludp, int connection_id) |
344 | { | 251 | { |
345 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 252 | if (connection_id >= 0 && connection_id < ludp->connections_length) { |
346 | if (connections[connection_id].status > 0) { | 253 | if (ludp->connections[connection_id].status > 0) { |
347 | connections[connection_id].status = 0; | 254 | ludp->connections[connection_id].status = 0; |
348 | change_handshake(connections[connection_id].ip_port); | 255 | change_handshake(ludp, ludp->connections[connection_id].ip_port); |
349 | --connections_number; | 256 | --ludp->connections_number; |
350 | free_connections(); | 257 | free_connections(ludp); |
351 | return 0; | 258 | return 0; |
352 | } | 259 | } |
353 | } | 260 | } |
@@ -360,11 +267,11 @@ int kill_connection(int connection_id) | |||
360 | * Return -1 if it can not kill the connection. | 267 | * Return -1 if it can not kill the connection. |
361 | * Return 0 if it will kill it. | 268 | * Return 0 if it will kill it. |
362 | */ | 269 | */ |
363 | int kill_connection_in(int connection_id, uint32_t seconds) | 270 | int kill_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds) |
364 | { | 271 | { |
365 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 272 | if (connection_id >= 0 && connection_id < ludp->connections_length) { |
366 | if (connections[connection_id].status > 0) { | 273 | if (ludp->connections[connection_id].status > 0) { |
367 | connections[connection_id].killat = current_time() + 1000000UL * seconds; | 274 | ludp->connections[connection_id].killat = current_time() + 1000000UL * seconds; |
368 | return 0; | 275 | return 0; |
369 | } | 276 | } |
370 | } | 277 | } |
@@ -380,65 +287,66 @@ int kill_connection_in(int connection_id, uint32_t seconds) | |||
380 | * Return 3 if fully connected. | 287 | * Return 3 if fully connected. |
381 | * Return 4 if timed out and waiting to be killed. | 288 | * Return 4 if timed out and waiting to be killed. |
382 | */ | 289 | */ |
383 | int is_connected(int connection_id) | 290 | int is_connected(Lossless_UDP *ludp, int connection_id) |
384 | { | 291 | { |
385 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 292 | if (connection_id >= 0 && connection_id < ludp->connections_length) |
386 | return connections[connection_id].status; | 293 | return ludp->connections[connection_id].status; |
387 | 294 | ||
388 | return 0; | 295 | return 0; |
389 | } | 296 | } |
390 | 297 | ||
391 | /* returns the ip_port of the corresponding connection. */ | 298 | /* returns the ip_port of the corresponding connection. */ |
392 | IP_Port connection_ip(int connection_id) | 299 | IP_Port connection_ip(Lossless_UDP *ludp, int connection_id) |
393 | { | 300 | { |
394 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 301 | if (connection_id >= 0 && connection_id < ludp->connections_length) |
395 | return connections[connection_id].ip_port; | 302 | return ludp->connections[connection_id].ip_port; |
396 | 303 | ||
397 | IP_Port zero = {{{0}}, 0}; | 304 | IP_Port zero = {{{0}}, 0}; |
398 | return zero; | 305 | return zero; |
399 | } | 306 | } |
400 | 307 | ||
401 | /* returns the number of packets in the queue waiting to be successfully sent. */ | 308 | /* returns the number of packets in the queue waiting to be successfully sent. */ |
402 | uint32_t sendqueue(int connection_id) | 309 | uint32_t sendqueue(Lossless_UDP *ludp, int connection_id) |
403 | { | 310 | { |
404 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 311 | if (connection_id < 0 || connection_id >= ludp->connections_length) |
405 | return 0; | 312 | return 0; |
406 | 313 | ||
407 | return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; | 314 | return ludp->connections[connection_id].sendbuff_packetnum - ludp->connections[connection_id].successful_sent; |
408 | } | 315 | } |
409 | 316 | ||
410 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ | 317 | /* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ |
411 | uint32_t recvqueue(int connection_id) | 318 | uint32_t recvqueue(Lossless_UDP *ludp, int connection_id) |
412 | { | 319 | { |
413 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 320 | if (connection_id < 0 || connection_id >= ludp->connections_length) |
414 | return 0; | 321 | return 0; |
415 | 322 | ||
416 | return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; | 323 | return ludp->connections[connection_id].recv_packetnum - ludp->connections[connection_id].successful_read; |
417 | } | 324 | } |
418 | 325 | ||
419 | /* returns the id of the next packet in the queue | 326 | /* returns the id of the next packet in the queue |
420 | return -1 if no packet in queue */ | 327 | return -1 if no packet in queue */ |
421 | char id_packet(int connection_id) | 328 | char id_packet(Lossless_UDP *ludp, int connection_id) |
422 | { | 329 | { |
423 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 330 | if (connection_id < 0 || connection_id >= ludp->connections_length) |
424 | return -1; | 331 | return -1; |
425 | 332 | ||
426 | if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) | 333 | if (recvqueue(ludp, connection_id) != 0 && ludp->connections[connection_id].status != 0) |
427 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; | 334 | return ludp->connections[connection_id].recvbuffer[ludp->connections[connection_id].successful_read % |
335 | MAX_QUEUE_NUM].data[0]; | ||
428 | 336 | ||
429 | return -1; | 337 | return -1; |
430 | } | 338 | } |
431 | 339 | ||
432 | /* return 0 if there is no received data in the buffer. | 340 | /* return 0 if there is no received data in the buffer. |
433 | return length of received packet if successful */ | 341 | return length of received packet if successful */ |
434 | int read_packet(int connection_id, uint8_t *data) | 342 | int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data) |
435 | { | 343 | { |
436 | if (recvqueue(connection_id) != 0) { | 344 | if (recvqueue(ludp, connection_id) != 0) { |
437 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; | 345 | uint16_t index = ludp->connections[connection_id].successful_read % MAX_QUEUE_NUM; |
438 | uint16_t size = connections[connection_id].recvbuffer[index].size; | 346 | uint16_t size = ludp->connections[connection_id].recvbuffer[index].size; |
439 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); | 347 | memcpy(data, ludp->connections[connection_id].recvbuffer[index].data, size); |
440 | ++connections[connection_id].successful_read; | 348 | ++ludp->connections[connection_id].successful_read; |
441 | connections[connection_id].recvbuffer[index].size = 0; | 349 | ludp->connections[connection_id].recvbuffer[index].size = 0; |
442 | return size; | 350 | return size; |
443 | } | 351 | } |
444 | 352 | ||
@@ -449,16 +357,16 @@ int read_packet(int connection_id, uint8_t *data) | |||
449 | * Return 0 if data could not be put in packet queue | 357 | * Return 0 if data could not be put in packet queue |
450 | * Return 1 if data was put into the queue | 358 | * Return 1 if data was put into the queue |
451 | */ | 359 | */ |
452 | int write_packet(int connection_id, uint8_t *data, uint32_t length) | 360 | int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t length) |
453 | { | 361 | { |
454 | if (length > MAX_DATA_SIZE || length == 0) | 362 | if (length > MAX_DATA_SIZE || length == 0) |
455 | return 0; | 363 | return 0; |
456 | 364 | ||
457 | if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { | 365 | if (sendqueue(ludp, connection_id) < BUFFER_PACKET_NUM) { |
458 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | 366 | uint32_t index = ludp->connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; |
459 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | 367 | memcpy(ludp->connections[connection_id].sendbuffer[index].data, data, length); |
460 | connections[connection_id].sendbuffer[index].size = length; | 368 | ludp->connections[connection_id].sendbuffer[index].size = length; |
461 | connections[connection_id].sendbuff_packetnum++; | 369 | ludp->connections[connection_id].sendbuff_packetnum++; |
462 | return 1; | 370 | return 1; |
463 | } | 371 | } |
464 | 372 | ||
@@ -466,18 +374,18 @@ int write_packet(int connection_id, uint8_t *data, uint32_t length) | |||
466 | } | 374 | } |
467 | 375 | ||
468 | /* put the packet numbers the we are missing in requested and return the number */ | 376 | /* put the packet numbers the we are missing in requested and return the number */ |
469 | uint32_t missing_packets(int connection_id, uint32_t *requested) | 377 | uint32_t missing_packets(Lossless_UDP *ludp, int connection_id, uint32_t *requested) |
470 | { | 378 | { |
471 | uint32_t number = 0; | 379 | uint32_t number = 0; |
472 | uint32_t i; | 380 | uint32_t i; |
473 | uint32_t temp; | 381 | uint32_t temp; |
474 | 382 | ||
475 | /* don't request packets if the buffer is full. */ | 383 | /* don't request packets if the buffer is full. */ |
476 | if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) | 384 | if (recvqueue(ludp, connection_id) >= (BUFFER_PACKET_NUM - 1)) |
477 | return 0; | 385 | return 0; |
478 | 386 | ||
479 | for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { | 387 | for (i = ludp->connections[connection_id].recv_packetnum; i != ludp->connections[connection_id].osent_packetnum; i++) { |
480 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { | 388 | if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { |
481 | temp = htonl(i); | 389 | temp = htonl(i); |
482 | memcpy(requested + number, &temp, 4); | 390 | memcpy(requested + number, &temp, 4); |
483 | ++number; | 391 | ++number; |
@@ -485,7 +393,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested) | |||
485 | } | 393 | } |
486 | 394 | ||
487 | if (number == 0) | 395 | if (number == 0) |
488 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; | 396 | ludp->connections[connection_id].recv_packetnum = ludp->connections[connection_id].osent_packetnum; |
489 | 397 | ||
490 | return number; | 398 | return number; |
491 | } | 399 | } |
@@ -496,7 +404,7 @@ uint32_t missing_packets(int connection_id, uint32_t *requested) | |||
496 | * see http://wiki.tox.im/index.php/Lossless_UDP for more information. | 404 | * see http://wiki.tox.im/index.php/Lossless_UDP for more information. |
497 | */ | 405 | */ |
498 | 406 | ||
499 | static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 407 | static int send_handshake(Lossless_UDP *ludp, IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) |
500 | { | 408 | { |
501 | uint8_t packet[1 + 4 + 4]; | 409 | uint8_t packet[1 + 4 + 4]; |
502 | uint32_t temp; | 410 | uint32_t temp; |
@@ -507,21 +415,21 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand | |||
507 | temp = htonl(handshake_id2); | 415 | temp = htonl(handshake_id2); |
508 | memcpy(packet + 5, &temp, 4); | 416 | memcpy(packet + 5, &temp, 4); |
509 | 417 | ||
510 | return sendpacket(ip_port, packet, sizeof(packet)); | 418 | return sendpacket(ludp->net->sock, ip_port, packet, sizeof(packet)); |
511 | } | 419 | } |
512 | 420 | ||
513 | static int send_SYNC(uint32_t connection_id) | 421 | static int send_SYNC(Lossless_UDP *ludp, uint32_t connection_id) |
514 | { | 422 | { |
515 | uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; | 423 | uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)]; |
516 | uint16_t index = 0; | 424 | uint16_t index = 0; |
517 | 425 | ||
518 | IP_Port ip_port = connections[connection_id].ip_port; | 426 | IP_Port ip_port = ludp->connections[connection_id].ip_port; |
519 | uint8_t counter = connections[connection_id].send_counter; | 427 | uint8_t counter = ludp->connections[connection_id].send_counter; |
520 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); | 428 | uint32_t recv_packetnum = htonl(ludp->connections[connection_id].recv_packetnum); |
521 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); | 429 | uint32_t sent_packetnum = htonl(ludp->connections[connection_id].sent_packetnum); |
522 | 430 | ||
523 | uint32_t requested[BUFFER_PACKET_NUM]; | 431 | uint32_t requested[BUFFER_PACKET_NUM]; |
524 | uint32_t number = missing_packets(connection_id, requested); | 432 | uint32_t number = missing_packets(ludp, connection_id, requested); |
525 | 433 | ||
526 | packet[0] = 17; | 434 | packet[0] = 17; |
527 | index += 1; | 435 | index += 1; |
@@ -533,11 +441,11 @@ static int send_SYNC(uint32_t connection_id) | |||
533 | index += 4; | 441 | index += 4; |
534 | memcpy(packet + index, requested, 4 * number); | 442 | memcpy(packet + index, requested, 4 * number); |
535 | 443 | ||
536 | return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2)); | 444 | return sendpacket(ludp->net->sock, ip_port, packet, (number * 4 + 4 + 4 + 2)); |
537 | 445 | ||
538 | } | 446 | } |
539 | 447 | ||
540 | static int send_data_packet(uint32_t connection_id, uint32_t packet_num) | 448 | static int send_data_packet(Lossless_UDP *ludp, uint32_t connection_id, uint32_t packet_num) |
541 | { | 449 | { |
542 | uint32_t index = packet_num % MAX_QUEUE_NUM; | 450 | uint32_t index = packet_num % MAX_QUEUE_NUM; |
543 | uint32_t temp; | 451 | uint32_t temp; |
@@ -545,29 +453,29 @@ static int send_data_packet(uint32_t connection_id, uint32_t packet_num) | |||
545 | packet[0] = 18; | 453 | packet[0] = 18; |
546 | temp = htonl(packet_num); | 454 | temp = htonl(packet_num); |
547 | memcpy(packet + 1, &temp, 4); | 455 | memcpy(packet + 1, &temp, 4); |
548 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, | 456 | memcpy(packet + 5, ludp->connections[connection_id].sendbuffer[index].data, |
549 | connections[connection_id].sendbuffer[index].size); | 457 | ludp->connections[connection_id].sendbuffer[index].size); |
550 | return sendpacket(connections[connection_id].ip_port, packet, | 458 | return sendpacket(ludp->net->sock, ludp->connections[connection_id].ip_port, packet, |
551 | 1 + 4 + connections[connection_id].sendbuffer[index].size); | 459 | 1 + 4 + ludp->connections[connection_id].sendbuffer[index].size); |
552 | } | 460 | } |
553 | 461 | ||
554 | /* sends 1 data packet */ | 462 | /* sends 1 data packet */ |
555 | static int send_DATA(uint32_t connection_id) | 463 | static int send_DATA(Lossless_UDP *ludp, uint32_t connection_id) |
556 | { | 464 | { |
557 | int ret; | 465 | int ret; |
558 | uint32_t buffer[BUFFER_PACKET_NUM]; | 466 | uint32_t buffer[BUFFER_PACKET_NUM]; |
559 | 467 | ||
560 | if (connections[connection_id].num_req_paquets > 0) { | 468 | if (ludp->connections[connection_id].num_req_paquets > 0) { |
561 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); | 469 | ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].req_packets[0]); |
562 | connections[connection_id].num_req_paquets--; | 470 | ludp->connections[connection_id].num_req_paquets--; |
563 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); | 471 | memcpy(buffer, ludp->connections[connection_id].req_packets + 1, ludp->connections[connection_id].num_req_paquets * 4); |
564 | memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); | 472 | memcpy(ludp->connections[connection_id].req_packets, buffer, ludp->connections[connection_id].num_req_paquets * 4); |
565 | return ret; | 473 | return ret; |
566 | } | 474 | } |
567 | 475 | ||
568 | if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { | 476 | if (ludp->connections[connection_id].sendbuff_packetnum != ludp->connections[connection_id].sent_packetnum) { |
569 | ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); | 477 | ret = send_data_packet(ludp, connection_id, ludp->connections[connection_id].sent_packetnum); |
570 | connections[connection_id].sent_packetnum++; | 478 | ludp->connections[connection_id].sent_packetnum++; |
571 | return ret; | 479 | return ret; |
572 | } | 480 | } |
573 | 481 | ||
@@ -584,37 +492,39 @@ static int send_DATA(uint32_t connection_id) | |||
584 | 492 | ||
585 | 493 | ||
586 | /* Return 0 if handled correctly, 1 if packet is bad. */ | 494 | /* Return 0 if handled correctly, 1 if packet is bad. */ |
587 | static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length) | 495 | static int handle_handshake(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
588 | { | 496 | { |
497 | Lossless_UDP *ludp = object; | ||
498 | |||
589 | if (length != (1 + 4 + 4)) | 499 | if (length != (1 + 4 + 4)) |
590 | return 1; | 500 | return 1; |
591 | 501 | ||
592 | uint32_t temp; | 502 | uint32_t temp; |
593 | uint32_t handshake_id1, handshake_id2; | 503 | uint32_t handshake_id1, handshake_id2; |
594 | 504 | ||
595 | int connection = getconnection_id(source); | 505 | int connection = getconnection_id(ludp, source); |
596 | memcpy(&temp, packet + 1, 4); | 506 | memcpy(&temp, packet + 1, 4); |
597 | handshake_id1 = ntohl(temp); | 507 | handshake_id1 = ntohl(temp); |
598 | memcpy(&temp, packet + 5, 4); | 508 | memcpy(&temp, packet + 5, 4); |
599 | handshake_id2 = ntohl(temp); | 509 | handshake_id2 = ntohl(temp); |
600 | 510 | ||
601 | if (handshake_id2 == 0 && is_connected(connection) < 3) { | 511 | if (handshake_id2 == 0 && is_connected(ludp, connection) < 3) { |
602 | send_handshake(source, handshake_id(source), handshake_id1); | 512 | send_handshake(ludp, source, handshake_id(ludp, source), handshake_id1); |
603 | return 0; | 513 | return 0; |
604 | } | 514 | } |
605 | 515 | ||
606 | if (is_connected(connection) != 1) | 516 | if (is_connected(ludp, connection) != 1) |
607 | return 1; | 517 | return 1; |
608 | 518 | ||
609 | /* if handshake_id2 is what we sent previously as handshake_id1 */ | 519 | /* if handshake_id2 is what we sent previously as handshake_id1 */ |
610 | if (handshake_id2 == connections[connection].handshake_id1) { | 520 | if (handshake_id2 == ludp->connections[connection].handshake_id1) { |
611 | connections[connection].status = 2; | 521 | ludp->connections[connection].status = 2; |
612 | /* NOTE: is this necessary? | 522 | /* NOTE: is this necessary? |
613 | connections[connection].handshake_id2 = handshake_id1; */ | 523 | ludp->connections[connection].handshake_id2 = handshake_id1; */ |
614 | connections[connection].orecv_packetnum = handshake_id2; | 524 | ludp->connections[connection].orecv_packetnum = handshake_id2; |
615 | connections[connection].osent_packetnum = handshake_id1; | 525 | ludp->connections[connection].osent_packetnum = handshake_id1; |
616 | connections[connection].recv_packetnum = handshake_id1; | 526 | ludp->connections[connection].recv_packetnum = handshake_id1; |
617 | connections[connection].successful_read = handshake_id1; | 527 | ludp->connections[connection].successful_read = handshake_id1; |
618 | } | 528 | } |
619 | 529 | ||
620 | return 0; | 530 | return 0; |
@@ -634,19 +544,19 @@ static int SYNC_valid(uint32_t length) | |||
634 | } | 544 | } |
635 | 545 | ||
636 | /* case 1 in handle_SYNC: */ | 546 | /* case 1 in handle_SYNC: */ |
637 | static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 547 | static int handle_SYNC1(Lossless_UDP *ludp, IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) |
638 | { | 548 | { |
639 | if (handshake_id(source) == recv_packetnum) { | 549 | if (handshake_id(ludp, source) == recv_packetnum) { |
640 | int x = new_inconnection(source); | 550 | int x = new_inconnection(ludp, source); |
641 | 551 | ||
642 | if (x != -1) { | 552 | if (x != -1) { |
643 | connections[x].orecv_packetnum = recv_packetnum; | 553 | ludp->connections[x].orecv_packetnum = recv_packetnum; |
644 | connections[x].sent_packetnum = recv_packetnum; | 554 | ludp->connections[x].sent_packetnum = recv_packetnum; |
645 | connections[x].sendbuff_packetnum = recv_packetnum; | 555 | ludp->connections[x].sendbuff_packetnum = recv_packetnum; |
646 | connections[x].successful_sent = recv_packetnum; | 556 | ludp->connections[x].successful_sent = recv_packetnum; |
647 | connections[x].osent_packetnum = sent_packetnum; | 557 | ludp->connections[x].osent_packetnum = sent_packetnum; |
648 | connections[x].recv_packetnum = sent_packetnum; | 558 | ludp->connections[x].recv_packetnum = sent_packetnum; |
649 | connections[x].successful_read = sent_packetnum; | 559 | ludp->connections[x].successful_read = sent_packetnum; |
650 | 560 | ||
651 | return x; | 561 | return x; |
652 | } | 562 | } |
@@ -656,63 +566,66 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p | |||
656 | } | 566 | } |
657 | 567 | ||
658 | /* case 2 in handle_SYNC: */ | 568 | /* case 2 in handle_SYNC: */ |
659 | static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 569 | static int handle_SYNC2(Lossless_UDP *ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, |
660 | { | 570 | uint32_t sent_packetnum) |
661 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { | 571 | { |
662 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ | 572 | if (recv_packetnum == ludp->connections[connection_id].orecv_packetnum) { |
663 | connections[connection_id].status = 3; | 573 | /* && sent_packetnum == ludp->connections[connection_id].osent_packetnum) */ |
664 | connections[connection_id].recv_counter = counter; | 574 | ludp->connections[connection_id].status = 3; |
665 | ++connections[connection_id].send_counter; | 575 | ludp->connections[connection_id].recv_counter = counter; |
666 | send_SYNC(connection_id); | 576 | ++ludp->connections[connection_id].send_counter; |
577 | send_SYNC(ludp, connection_id); | ||
667 | return 0; | 578 | return 0; |
668 | } | 579 | } |
669 | 580 | ||
670 | return 1; | 581 | return 1; |
671 | } | 582 | } |
672 | /* case 3 in handle_SYNC: */ | 583 | /* case 3 in handle_SYNC: */ |
673 | static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, | 584 | static int handle_SYNC3(Lossless_UDP *ludp, int connection_id, uint8_t counter, uint32_t recv_packetnum, |
585 | uint32_t sent_packetnum, | ||
674 | uint32_t *req_packets, | 586 | uint32_t *req_packets, |
675 | uint16_t number) | 587 | uint16_t number) |
676 | { | 588 | { |
677 | uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); | 589 | uint8_t comp_counter = (counter - ludp->connections[connection_id].recv_counter ); |
678 | uint32_t i, temp; | 590 | uint32_t i, temp; |
679 | /* uint32_t comp_1 = (recv_packetnum - connections[connection_id].successful_sent); | 591 | /* uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].successful_sent); |
680 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ | 592 | uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].successful_read); */ |
681 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); | 593 | uint32_t comp_1 = (recv_packetnum - ludp->connections[connection_id].orecv_packetnum); |
682 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); | 594 | uint32_t comp_2 = (sent_packetnum - ludp->connections[connection_id].osent_packetnum); |
683 | 595 | ||
684 | /* packet valid */ | 596 | /* packet valid */ |
685 | if (comp_1 <= BUFFER_PACKET_NUM && | 597 | if (comp_1 <= BUFFER_PACKET_NUM && |
686 | comp_2 <= BUFFER_PACKET_NUM && | 598 | comp_2 <= BUFFER_PACKET_NUM && |
687 | comp_counter < 10 && comp_counter != 0) { | 599 | comp_counter < 10 && comp_counter != 0) { |
688 | 600 | ||
689 | connections[connection_id].orecv_packetnum = recv_packetnum; | 601 | ludp->connections[connection_id].orecv_packetnum = recv_packetnum; |
690 | connections[connection_id].osent_packetnum = sent_packetnum; | 602 | ludp->connections[connection_id].osent_packetnum = sent_packetnum; |
691 | connections[connection_id].successful_sent = recv_packetnum; | 603 | ludp->connections[connection_id].successful_sent = recv_packetnum; |
692 | connections[connection_id].last_recvSYNC = current_time(); | 604 | ludp->connections[connection_id].last_recvSYNC = current_time(); |
693 | connections[connection_id].recv_counter = counter; | 605 | ludp->connections[connection_id].recv_counter = counter; |
694 | 606 | ||
695 | ++connections[connection_id].send_counter; | 607 | ++ludp->connections[connection_id].send_counter; |
696 | 608 | ||
697 | for (i = 0; i < number; ++i) { | 609 | for (i = 0; i < number; ++i) { |
698 | temp = ntohl(req_packets[i]); | 610 | temp = ntohl(req_packets[i]); |
699 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); | 611 | memcpy(ludp->connections[connection_id].req_packets + i, &temp, 4 * number); |
700 | } | 612 | } |
701 | 613 | ||
702 | connections[connection_id].num_req_paquets = number; | 614 | ludp->connections[connection_id].num_req_paquets = number; |
703 | return 0; | 615 | return 0; |
704 | } | 616 | } |
705 | 617 | ||
706 | return 1; | 618 | return 1; |
707 | } | 619 | } |
708 | 620 | ||
709 | static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | 621 | static int handle_SYNC(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
710 | { | 622 | { |
623 | Lossless_UDP *ludp = object; | ||
711 | 624 | ||
712 | if (!SYNC_valid(length)) | 625 | if (!SYNC_valid(length)) |
713 | return 1; | 626 | return 1; |
714 | 627 | ||
715 | int connection = getconnection_id(source); | 628 | int connection = getconnection_id(ludp, source); |
716 | uint8_t counter; | 629 | uint8_t counter; |
717 | uint32_t temp; | 630 | uint32_t temp; |
718 | uint32_t recv_packetnum, sent_packetnum; | 631 | uint32_t recv_packetnum, sent_packetnum; |
@@ -729,14 +642,14 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | |||
729 | memcpy(req_packets, packet + 10, 4 * number); | 642 | memcpy(req_packets, packet + 10, 4 * number); |
730 | 643 | ||
731 | if (connection == -1) | 644 | if (connection == -1) |
732 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); | 645 | return handle_SYNC1(ludp, source, recv_packetnum, sent_packetnum); |
733 | 646 | ||
734 | if (connections[connection].status == 2) | 647 | if (ludp->connections[connection].status == 2) |
735 | return handle_SYNC2(connection, counter, | 648 | return handle_SYNC2(ludp, connection, counter, |
736 | recv_packetnum, sent_packetnum); | 649 | recv_packetnum, sent_packetnum); |
737 | 650 | ||
738 | if (connections[connection].status == 3) | 651 | if (ludp->connections[connection].status == 3) |
739 | return handle_SYNC3(connection, counter, recv_packetnum, | 652 | return handle_SYNC3(ludp, connection, counter, recv_packetnum, |
740 | sent_packetnum, req_packets, number); | 653 | sent_packetnum, req_packets, number); |
741 | 654 | ||
742 | return 0; | 655 | return 0; |
@@ -746,33 +659,33 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length) | |||
746 | * Add a packet to the received buffer and set the recv_packetnum of the | 659 | * Add a packet to the received buffer and set the recv_packetnum of the |
747 | * connection to its proper value. Return 1 if data was too big, 0 if not. | 660 | * connection to its proper value. Return 1 if data was too big, 0 if not. |
748 | */ | 661 | */ |
749 | static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | 662 | static int add_recv(Lossless_UDP *ludp, int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) |
750 | { | 663 | { |
751 | if (size > MAX_DATA_SIZE) | 664 | if (size > MAX_DATA_SIZE) |
752 | return 1; | 665 | return 1; |
753 | 666 | ||
754 | uint32_t i; | 667 | uint32_t i; |
755 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 668 | uint32_t maxnum = ludp->connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
756 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 669 | uint32_t sent_packet = data_num - ludp->connections[connection_id].osent_packetnum; |
757 | 670 | ||
758 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 671 | for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
759 | if (i == data_num) { | 672 | if (i == data_num) { |
760 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 673 | memcpy(ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
761 | 674 | ||
762 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 675 | ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
763 | connections[connection_id].last_recvdata = current_time(); | 676 | ludp->connections[connection_id].last_recvdata = current_time(); |
764 | 677 | ||
765 | if (sent_packet < BUFFER_PACKET_NUM) { | 678 | if (sent_packet < BUFFER_PACKET_NUM) { |
766 | connections[connection_id].osent_packetnum = data_num; | 679 | ludp->connections[connection_id].osent_packetnum = data_num; |
767 | } | 680 | } |
768 | 681 | ||
769 | break; | 682 | break; |
770 | } | 683 | } |
771 | } | 684 | } |
772 | 685 | ||
773 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 686 | for (i = ludp->connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
774 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 687 | if (ludp->connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
775 | connections[connection_id].recv_packetnum = i; | 688 | ludp->connections[connection_id].recv_packetnum = i; |
776 | else | 689 | else |
777 | break; | 690 | break; |
778 | } | 691 | } |
@@ -780,15 +693,16 @@ static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_ | |||
780 | return 0; | 693 | return 0; |
781 | } | 694 | } |
782 | 695 | ||
783 | static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) | 696 | static int handle_data(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
784 | { | 697 | { |
785 | int connection = getconnection_id(source); | 698 | Lossless_UDP *ludp = object; |
699 | int connection = getconnection_id(ludp, source); | ||
786 | 700 | ||
787 | if (connection == -1) | 701 | if (connection == -1) |
788 | return 1; | 702 | return 1; |
789 | 703 | ||
790 | /* Drop the data packet if connection is not connected. */ | 704 | /* Drop the data packet if connection is not connected. */ |
791 | if (connections[connection].status != 3) | 705 | if (ludp->connections[connection].status != 3) |
792 | return 1; | 706 | return 1; |
793 | 707 | ||
794 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) | 708 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) |
@@ -801,76 +715,86 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length) | |||
801 | memcpy(&temp, packet + 1, 4); | 715 | memcpy(&temp, packet + 1, 4); |
802 | number = ntohl(temp); | 716 | number = ntohl(temp); |
803 | 717 | ||
804 | return add_recv(connection, number, packet + 5, size); | 718 | return add_recv(ludp, connection, number, packet + 5, size); |
805 | } | 719 | } |
806 | 720 | ||
807 | /* | 721 | /* |
808 | * END of packet handling functions | 722 | * END of packet handling functions |
809 | */ | 723 | */ |
810 | 724 | ||
811 | void LosslessUDP_init(void) | 725 | Lossless_UDP *new_lossless_udp(Networking_Core *net) |
812 | { | 726 | { |
813 | networking_registerhandler(16, &handle_handshake); | 727 | if (net == NULL) |
814 | networking_registerhandler(17, &handle_SYNC); | 728 | return NULL; |
815 | networking_registerhandler(18, &handle_data); | 729 | |
730 | Lossless_UDP *temp = calloc(1, sizeof(Lossless_UDP)); | ||
731 | |||
732 | if (temp == NULL) | ||
733 | return NULL; | ||
734 | |||
735 | temp->net = net; | ||
736 | networking_registerhandler(net, 16, &handle_handshake, temp); | ||
737 | networking_registerhandler(net, 17, &handle_SYNC, temp); | ||
738 | networking_registerhandler(net, 18, &handle_data, temp); | ||
739 | return temp; | ||
816 | } | 740 | } |
817 | 741 | ||
818 | /* | 742 | /* |
819 | * Send handshake requests | 743 | * Send handshake requests |
820 | * handshake packets are sent at the same rate as SYNC packets | 744 | * handshake packets are sent at the same rate as SYNC packets |
821 | */ | 745 | */ |
822 | static void doNew(void) | 746 | static void do_new(Lossless_UDP *ludp) |
823 | { | 747 | { |
824 | uint32_t i; | 748 | uint32_t i; |
825 | uint64_t temp_time = current_time(); | 749 | uint64_t temp_time = current_time(); |
826 | 750 | ||
827 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 751 | for (i = 0; i < ludp->connections_length; ++i) { |
828 | if (connections[i].status == 1) | 752 | if (ludp->connections[i].status == 1) |
829 | if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { | 753 | if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) { |
830 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); | 754 | send_handshake(ludp, ludp->connections[i].ip_port, ludp->connections[i].handshake_id1, 0); |
831 | connections[i].last_sent = temp_time; | 755 | ludp->connections[i].last_sent = temp_time; |
832 | } | 756 | } |
833 | 757 | ||
834 | /* kill all timed out connections */ | 758 | /* kill all timed out connections */ |
835 | if (connections[i].status > 0 && | 759 | if (ludp->connections[i].status > 0 && |
836 | (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 760 | (ludp->connections[i].last_recvSYNC + ludp->connections[i].timeout * 1000000UL) < temp_time && |
837 | connections[i].status != 4) { | 761 | ludp->connections[i].status != 4) { |
838 | connections[i].status = 4; | 762 | ludp->connections[i].status = 4; |
839 | /* kill_connection(i); */ | 763 | /* kill_connection(i); */ |
840 | } | 764 | } |
841 | 765 | ||
842 | if (connections[i].status > 0 && connections[i].killat < temp_time) | 766 | if (ludp->connections[i].status > 0 && ludp->connections[i].killat < temp_time) |
843 | kill_connection(i); | 767 | kill_connection(ludp, i); |
844 | } | 768 | } |
845 | } | 769 | } |
846 | 770 | ||
847 | static void doSYNC(void) | 771 | static void do_SYNC(Lossless_UDP *ludp) |
848 | { | 772 | { |
849 | uint32_t i; | 773 | uint32_t i; |
850 | uint64_t temp_time = current_time(); | 774 | uint64_t temp_time = current_time(); |
851 | 775 | ||
852 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 776 | for (i = 0; i < ludp->connections_length; ++i) { |
853 | if (connections[i].status == 2 || connections[i].status == 3) | 777 | if (ludp->connections[i].status == 2 || ludp->connections[i].status == 3) |
854 | if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) { | 778 | if ((ludp->connections[i].last_SYNC + (1000000UL / ludp->connections[i].SYNC_rate)) <= temp_time) { |
855 | send_SYNC(i); | 779 | send_SYNC(ludp, i); |
856 | connections[i].last_SYNC = temp_time; | 780 | ludp->connections[i].last_SYNC = temp_time; |
857 | } | 781 | } |
858 | } | 782 | } |
859 | } | 783 | } |
860 | 784 | ||
861 | static void doData(void) | 785 | static void do_data(Lossless_UDP *ludp) |
862 | { | 786 | { |
863 | uint32_t i; | 787 | uint32_t i; |
864 | uint64_t j; | 788 | uint64_t j; |
865 | uint64_t temp_time = current_time(); | 789 | uint64_t temp_time = current_time(); |
866 | 790 | ||
867 | for (i = 0; i < MAX_CONNECTIONS; ++i) | 791 | for (i = 0; i < ludp->connections_length; ++i) |
868 | if (connections[i].status == 3 && sendqueue(i) != 0) | 792 | if (ludp->connections[i].status == 3 && sendqueue(ludp, i) != 0) |
869 | if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) { | 793 | if ((ludp->connections[i].last_sent + (1000000UL / ludp->connections[i].data_rate)) <= temp_time) { |
870 | for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate)) | 794 | for (j = ludp->connections[i].last_sent; j < temp_time; j += (1000000UL / ludp->connections[i].data_rate)) |
871 | send_DATA(i); | 795 | send_DATA(ludp, i); |
872 | 796 | ||
873 | connections[i].last_sent = temp_time; | 797 | ludp->connections[i].last_sent = temp_time; |
874 | } | 798 | } |
875 | } | 799 | } |
876 | 800 | ||
@@ -881,32 +805,38 @@ static void doData(void) | |||
881 | * | 805 | * |
882 | * TODO: flow control. | 806 | * TODO: flow control. |
883 | */ | 807 | */ |
884 | static void adjustRates(void) | 808 | static void adjust_rates(Lossless_UDP *ludp) |
885 | { | 809 | { |
886 | uint32_t i; | 810 | uint32_t i; |
887 | uint64_t temp_time = current_time(); | 811 | uint64_t temp_time = current_time(); |
888 | 812 | ||
889 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 813 | for (i = 0; i < ludp->connections_length; ++i) { |
890 | if (connections[i].status == 1 || connections[i].status == 2) | 814 | if (ludp->connections[i].status == 1 || ludp->connections[i].status == 2) |
891 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 815 | ludp->connections[i].SYNC_rate = MAX_SYNC_RATE; |
892 | 816 | ||
893 | if (connections[i].status == 3) { | 817 | if (ludp->connections[i].status == 3) { |
894 | if (sendqueue(i) != 0) { | 818 | if (sendqueue(ludp, i) != 0) { |
895 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; | 819 | ludp->connections[i].data_rate = (BUFFER_PACKET_NUM - ludp->connections[i].num_req_paquets) * MAX_SYNC_RATE; |
896 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 820 | ludp->connections[i].SYNC_rate = MAX_SYNC_RATE; |
897 | } else if (connections[i].last_recvdata + 1000000UL > temp_time) | 821 | } else if (ludp->connections[i].last_recvdata + 1000000UL > temp_time) |
898 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 822 | ludp->connections[i].SYNC_rate = MAX_SYNC_RATE; |
899 | else | 823 | else |
900 | connections[i].SYNC_rate = SYNC_RATE; | 824 | ludp->connections[i].SYNC_rate = SYNC_RATE; |
901 | } | 825 | } |
902 | } | 826 | } |
903 | } | 827 | } |
904 | 828 | ||
905 | /* Call this function a couple times per second It's the main loop. */ | 829 | /* Call this function a couple times per second It's the main loop. */ |
906 | void doLossless_UDP(void) | 830 | void do_lossless_udp(Lossless_UDP *ludp) |
907 | { | 831 | { |
908 | doNew(); | 832 | do_new(ludp); |
909 | doSYNC(); | 833 | do_SYNC(ludp); |
910 | doData(); | 834 | do_data(ludp); |
911 | adjustRates(); | 835 | adjust_rates(ludp); |
912 | } | 836 | } |
837 | |||
838 | void kill_lossless_udp(Lossless_UDP *ludp) | ||
839 | { | ||
840 | free(ludp->connections); | ||
841 | free(ludp); | ||
842 | } \ No newline at end of file | ||
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h index bd426ee0..176e86ce 100644 --- a/core/Lossless_UDP.h +++ b/core/Lossless_UDP.h | |||
@@ -33,72 +33,168 @@ extern "C" { | |||
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 | /* maximum data packets in sent and receive queues. */ | ||
37 | #define MAX_QUEUE_NUM 16 | ||
38 | |||
39 | /* maximum number of data packets in the buffer */ | ||
40 | #define BUFFER_PACKET_NUM (16-1) | ||
41 | |||
42 | /* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ | ||
43 | #define CONNEXION_TIMEOUT 5 | ||
44 | |||
45 | /* initial amount of sync/hanshake packets to send per second. */ | ||
46 | #define SYNC_RATE 2 | ||
47 | |||
48 | /* initial send rate of data. */ | ||
49 | #define DATA_SYNC_RATE 30 | ||
50 | |||
51 | typedef struct { | ||
52 | uint8_t data[MAX_DATA_SIZE]; | ||
53 | uint16_t size; | ||
54 | } Data; | ||
55 | |||
56 | typedef struct { | ||
57 | IP_Port ip_port; | ||
58 | |||
59 | /* | ||
60 | * 0 if connection is dead, 1 if attempting handshake, | ||
61 | * 2 if handshake is done (we start sending SYNC packets) | ||
62 | * 3 if we are sending SYNC packets and can send data | ||
63 | * 4 if the connection has timed out. | ||
64 | */ | ||
65 | uint8_t status; | ||
66 | |||
67 | /* | ||
68 | * 1 or 2 if connection was initiated by someone else, 0 if not. | ||
69 | * 2 if incoming_connection() has not returned it yet, 1 if it has. | ||
70 | */ | ||
71 | uint8_t inbound; | ||
72 | |||
73 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | ||
74 | uint16_t data_rate; /* current data packet send rate packets per second. */ | ||
75 | |||
76 | uint64_t last_SYNC; /* time our last SYNC packet was sent. */ | ||
77 | uint64_t last_sent; /* time our last data or handshake packet was sent. */ | ||
78 | uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */ | ||
79 | uint64_t last_recvdata; /* time we last received a DATA packet from the other */ | ||
80 | uint64_t killat; /* time to kill the connection */ | ||
81 | |||
82 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | ||
83 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | ||
84 | |||
85 | uint32_t handshake_id1; | ||
86 | uint32_t handshake_id2; | ||
87 | |||
88 | /* number of data packets received (also used as handshake_id1) */ | ||
89 | uint32_t recv_packetnum; | ||
90 | |||
91 | /* number of packets received by the other peer */ | ||
92 | uint32_t orecv_packetnum; | ||
93 | |||
94 | /* number of data packets sent */ | ||
95 | uint32_t sent_packetnum; | ||
96 | |||
97 | /* number of packets sent by the other peer. */ | ||
98 | uint32_t osent_packetnum; | ||
99 | |||
100 | /* number of latest packet written onto the sendbuffer */ | ||
101 | uint32_t sendbuff_packetnum; | ||
102 | |||
103 | /* we know all packets before that number were successfully sent */ | ||
104 | uint32_t successful_sent; | ||
105 | |||
106 | /* packet number of last packet read with the read_packet function */ | ||
107 | uint32_t successful_read; | ||
108 | |||
109 | /* list of currently requested packet numbers(by the other person) */ | ||
110 | uint32_t req_packets[BUFFER_PACKET_NUM]; | ||
111 | |||
112 | /* total number of currently requested packets(by the other person) */ | ||
113 | uint16_t num_req_paquets; | ||
114 | |||
115 | uint8_t recv_counter; | ||
116 | uint8_t send_counter; | ||
117 | uint8_t timeout; /* connection timeout in seconds. */ | ||
118 | } Connection; | ||
119 | |||
120 | typedef struct { | ||
121 | Networking_Core *net; | ||
122 | Connection *connections; | ||
123 | |||
124 | uint32_t connections_length; /* Length of connections array */ | ||
125 | uint32_t connections_number; /* Number of connections in connections array */ | ||
126 | |||
127 | /* table of random numbers used in handshake_id. */ | ||
128 | uint32_t randtable[6][256]; | ||
129 | |||
130 | } Lossless_UDP; | ||
131 | |||
36 | /* | 132 | /* |
37 | * Initialize a new connection to ip_port | 133 | * Initialize a new connection to ip_port |
38 | * Returns an integer corresponding to the connection id. | 134 | * Returns an integer corresponding to the connection id. |
39 | * Return -1 if it could not initialize the connection. | 135 | * Return -1 if it could not initialize the connection. |
40 | * Return number if there already was an existing connection to that ip_port. | 136 | * Return number if there already was an existing connection to that ip_port. |
41 | */ | 137 | */ |
42 | int new_connection(IP_Port ip_port); | 138 | int new_connection(Lossless_UDP *ludp, IP_Port ip_port); |
43 | 139 | ||
44 | /* | 140 | /* |
45 | * Get connection id from IP_Port. | 141 | * Get connection id from IP_Port. |
46 | * Return -1 if there are no connections like we are looking for. | 142 | * Return -1 if there are no connections like we are looking for. |
47 | * Return id if it found it . | 143 | * Return id if it found it . |
48 | */ | 144 | */ |
49 | int getconnection_id(IP_Port ip_port); | 145 | int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port); |
50 | 146 | ||
51 | /* | 147 | /* |
52 | * Returns an int corresponding to the next connection in our imcoming connection list | 148 | * Returns an int corresponding to the next connection in our imcoming connection list |
53 | * Return -1 if there are no new incoming connections in the list. | 149 | * Return -1 if there are no new incoming connections in the list. |
54 | */ | 150 | */ |
55 | int incoming_connection(void); | 151 | int incoming_connection(Lossless_UDP *ludp); |
56 | 152 | ||
57 | /* | 153 | /* |
58 | * Return -1 if it could not kill the connection. | 154 | * Return -1 if it could not kill the connection. |
59 | * Return 0 if killed successfully | 155 | * Return 0 if killed successfully |
60 | */ | 156 | */ |
61 | int kill_connection(int connection_id); | 157 | int kill_connection(Lossless_UDP *ludp, int connection_id); |
62 | 158 | ||
63 | /* | 159 | /* |
64 | * Kill connection in seconds seconds. | 160 | * Kill connection in seconds seconds. |
65 | * Return -1 if it can not kill the connection. | 161 | * Return -1 if it can not kill the connection. |
66 | * Return 0 if it will kill it | 162 | * Return 0 if it will kill it |
67 | */ | 163 | */ |
68 | int kill_connection_in(int connection_id, uint32_t seconds); | 164 | int kill_connection_in(Lossless_UDP *ludp, int connection_id, uint32_t seconds); |
69 | 165 | ||
70 | /* | 166 | /* |
71 | * Returns the ip_port of the corresponding connection. | 167 | * Returns the ip_port of the corresponding connection. |
72 | * Return 0 if there is no such connection. | 168 | * Return 0 if there is no such connection. |
73 | */ | 169 | */ |
74 | IP_Port connection_ip(int connection_id); | 170 | IP_Port connection_ip(Lossless_UDP *ludp, int connection_id); |
75 | 171 | ||
76 | /* | 172 | /* |
77 | * Returns the id of the next packet in the queue | 173 | * Returns the id of the next packet in the queue |
78 | * Return -1 if no packet in queue | 174 | * Return -1 if no packet in queue |
79 | */ | 175 | */ |
80 | char id_packet(int connection_id); | 176 | char id_packet(Lossless_UDP *ludp, int connection_id); |
81 | 177 | ||
82 | /* | 178 | /* |
83 | * Return 0 if there is no received data in the buffer. | 179 | * Return 0 if there is no received data in the buffer. |
84 | * Return length of received packet if successful | 180 | * Return length of received packet if successful |
85 | */ | 181 | */ |
86 | int read_packet(int connection_id, uint8_t *data); | 182 | int read_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data); |
87 | 183 | ||
88 | /* | 184 | /* |
89 | * Return 0 if data could not be put in packet queue | 185 | * Return 0 if data could not be put in packet queue |
90 | * Return 1 if data was put into the queue | 186 | * Return 1 if data was put into the queue |
91 | */ | 187 | */ |
92 | int write_packet(int connection_id, uint8_t *data, uint32_t length); | 188 | int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t length); |
93 | 189 | ||
94 | /* Returns the number of packets in the queue waiting to be successfully sent. */ | 190 | /* Returns the number of packets in the queue waiting to be successfully sent. */ |
95 | uint32_t sendqueue(int connection_id); | 191 | uint32_t sendqueue(Lossless_UDP *ludp, int connection_id); |
96 | 192 | ||
97 | /* | 193 | /* |
98 | * returns the number of packets in the queue waiting to be successfully | 194 | * returns the number of packets in the queue waiting to be successfully |
99 | * read with read_packet(...) | 195 | * read with read_packet(...) |
100 | */ | 196 | */ |
101 | uint32_t recvqueue(int connection_id); | 197 | uint32_t recvqueue(Lossless_UDP *ludp, int connection_id); |
102 | 198 | ||
103 | /* Check if connection is connected: | 199 | /* Check if connection is connected: |
104 | * Return 0 no. | 200 | * Return 0 no. |
@@ -107,15 +203,17 @@ uint32_t recvqueue(int connection_id); | |||
107 | * Return 3 if fully connected. | 203 | * Return 3 if fully connected. |
108 | * Return 4 if timed out and wating to be killed. | 204 | * Return 4 if timed out and wating to be killed. |
109 | */ | 205 | */ |
110 | int is_connected(int connection_id); | 206 | int is_connected(Lossless_UDP *ludp, int connection_id); |
111 | 207 | ||
112 | /* Call this function a couple times per second It's the main loop. */ | 208 | /* Call this function a couple times per second It's the main loop. */ |
113 | void doLossless_UDP(void); | 209 | void do_lossless_udp(Lossless_UDP *ludp); |
114 | 210 | ||
115 | /* | 211 | /* |
116 | * This function sets up LosslessUDP packet handling. | 212 | * This function sets up LosslessUDP packet handling. |
117 | */ | 213 | */ |
118 | void LosslessUDP_init(void); | 214 | Lossless_UDP *new_lossless_udp(Networking_Core *net); |
215 | |||
216 | void kill_lossless_udp(Lossless_UDP *ludp); | ||
119 | 217 | ||
120 | #ifdef __cplusplus | 218 | #ifdef __cplusplus |
121 | } | 219 | } |
diff --git a/core/Messenger.c b/core/Messenger.c index 7fd6a569..dd24ab09 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -22,7 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "Messenger.h" | 24 | #include "Messenger.h" |
25 | #include "timer.h" | ||
26 | 25 | ||
27 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 26 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
28 | 27 | ||
@@ -108,9 +107,8 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len) | |||
108 | */ | 107 | */ |
109 | void getaddress(Messenger *m, uint8_t *address) | 108 | void getaddress(Messenger *m, uint8_t *address) |
110 | { | 109 | { |
111 | //memcpy(address, m->public_key, crypto_box_PUBLICKEYBYTES); //TODO | 110 | memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES); |
112 | memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES); | 111 | uint32_t nospam = get_nospam(&(m->fr)); |
113 | uint32_t nospam = get_nospam(); | ||
114 | memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); | 112 | memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); |
115 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | 113 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); |
116 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); | 114 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); |
@@ -150,7 +148,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) | |||
150 | if (length < 1) | 148 | if (length < 1) |
151 | return FAERR_NOMESSAGE; | 149 | return FAERR_NOMESSAGE; |
152 | 150 | ||
153 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | 151 | if (memcmp(client_id, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) |
154 | return FAERR_OWNKEY; | 152 | return FAERR_OWNKEY; |
155 | 153 | ||
156 | int friend_id = getfriend_id(m, client_id); | 154 | int friend_id = getfriend_id(m, client_id); |
@@ -176,7 +174,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) | |||
176 | 174 | ||
177 | for (i = 0; i <= m->numfriends; ++i) { | 175 | for (i = 0; i <= m->numfriends; ++i) { |
178 | if (m->friendlist[i].status == NOFRIEND) { | 176 | if (m->friendlist[i].status == NOFRIEND) { |
179 | DHT_addfriend(client_id); | 177 | DHT_addfriend(m->dht, client_id); |
180 | m->friendlist[i].status = FRIEND_ADDED; | 178 | m->friendlist[i].status = FRIEND_ADDED; |
181 | m->friendlist[i].crypt_connection_id = -1; | 179 | m->friendlist[i].crypt_connection_id = -1; |
182 | m->friendlist[i].friendrequest_lastsent = 0; | 180 | m->friendlist[i].friendrequest_lastsent = 0; |
@@ -216,7 +214,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id) | |||
216 | 214 | ||
217 | for (i = 0; i <= m->numfriends; ++i) { | 215 | for (i = 0; i <= m->numfriends; ++i) { |
218 | if (m->friendlist[i].status == NOFRIEND) { | 216 | if (m->friendlist[i].status == NOFRIEND) { |
219 | DHT_addfriend(client_id); | 217 | DHT_addfriend(m->dht, client_id); |
220 | m->friendlist[i].status = FRIEND_CONFIRMED; | 218 | m->friendlist[i].status = FRIEND_CONFIRMED; |
221 | m->friendlist[i].crypt_connection_id = -1; | 219 | m->friendlist[i].crypt_connection_id = -1; |
222 | m->friendlist[i].friendrequest_lastsent = 0; | 220 | m->friendlist[i].friendrequest_lastsent = 0; |
@@ -245,8 +243,8 @@ int m_delfriend(Messenger *m, int friendnumber) | |||
245 | if (friendnumber >= m->numfriends || friendnumber < 0) | 243 | if (friendnumber >= m->numfriends || friendnumber < 0) |
246 | return -1; | 244 | return -1; |
247 | 245 | ||
248 | DHT_delfriend(m->friendlist[friendnumber].client_id); | 246 | DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id); |
249 | crypto_kill(m->friendlist[friendnumber].crypt_connection_id); | 247 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); |
250 | free(m->friendlist[friendnumber].statusmessage); | 248 | free(m->friendlist[friendnumber].statusmessage); |
251 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); | 249 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); |
252 | uint32_t i; | 250 | uint32_t i; |
@@ -522,7 +520,7 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno) | |||
522 | /* set the function that will be executed when a friend request is received. */ | 520 | /* set the function that will be executed when a friend request is received. */ |
523 | void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) | 521 | void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) |
524 | { | 522 | { |
525 | callback_friendrequest(function, userdata); | 523 | callback_friendrequest(&(m->fr), function, userdata); |
526 | } | 524 | } |
527 | 525 | ||
528 | /* set the function that will be executed when a message from a friend is received. */ | 526 | /* set the function that will be executed when a message from a friend is received. */ |
@@ -606,20 +604,20 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint | |||
606 | if (length != 0) | 604 | if (length != 0) |
607 | memcpy(packet + 1, data, length); | 605 | memcpy(packet + 1, data, length); |
608 | 606 | ||
609 | return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); | 607 | return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); |
610 | } | 608 | } |
611 | 609 | ||
612 | |||
613 | /*Interval in seconds between LAN discovery packet sending*/ | 610 | /*Interval in seconds between LAN discovery packet sending*/ |
614 | #define LAN_DISCOVERY_INTERVAL 60 | 611 | #define LAN_DISCOVERY_INTERVAL 60 |
615 | #define PORT 33445 | 612 | #define PORT 33445 |
616 | 613 | ||
617 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ | 614 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ |
618 | int LANdiscovery(timer *t, void *arg) | 615 | static void LANdiscovery(Messenger *m) |
619 | { | 616 | { |
620 | send_LANdiscovery(htons(PORT)); | 617 | if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { |
621 | timer_start(t, LAN_DISCOVERY_INTERVAL); | 618 | send_LANdiscovery(htons(PORT), m->net_crypto); |
622 | return 0; | 619 | m->last_LANdiscovery = unix_time(); |
620 | } | ||
623 | } | 621 | } |
624 | 622 | ||
625 | /* run this at startup */ | 623 | /* run this at startup */ |
@@ -628,25 +626,41 @@ Messenger *initMessenger(void) | |||
628 | Messenger *m = calloc(1, sizeof(Messenger)); | 626 | Messenger *m = calloc(1, sizeof(Messenger)); |
629 | 627 | ||
630 | if ( ! m ) | 628 | if ( ! m ) |
631 | return 0; | 629 | return NULL; |
632 | 630 | ||
633 | new_keys(); | ||
634 | m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); | ||
635 | initNetCrypto(); | ||
636 | IP ip; | 631 | IP ip; |
637 | ip.i = 0; | 632 | ip.i = 0; |
633 | m->net = new_networking(ip, PORT); | ||
638 | 634 | ||
639 | if (init_networking(ip, PORT) == -1) | 635 | if (m->net == NULL) { |
640 | return 0; | 636 | free(m); |
637 | return NULL; | ||
638 | } | ||
639 | |||
640 | m->net_crypto = new_net_crypto(m->net); | ||
641 | 641 | ||
642 | DHT_init(); | 642 | if (m->net_crypto == NULL) { |
643 | LosslessUDP_init(); | 643 | kill_networking(m->net); |
644 | friendreq_init(); | 644 | free(m); |
645 | LANdiscovery_init(); | 645 | return NULL; |
646 | set_nospam(random_int()); | 646 | } |
647 | |||
648 | m->dht = new_DHT(m->net_crypto); | ||
649 | |||
650 | if (m->dht == NULL) { | ||
651 | kill_net_crypto(m->net_crypto); | ||
652 | kill_networking(m->net); | ||
653 | free(m); | ||
654 | return NULL; | ||
655 | } | ||
647 | 656 | ||
648 | send_LANdiscovery(htons(PORT)); | 657 | new_keys(m->net_crypto); |
649 | timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL); | 658 | m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); |
659 | |||
660 | friendreq_init(&(m->fr), m->net_crypto); | ||
661 | LANdiscovery_init(m->dht); | ||
662 | set_nospam(&(m->fr), random_int()); | ||
663 | init_cryptopackets(m->dht); | ||
650 | 664 | ||
651 | return m; | 665 | return m; |
652 | } | 666 | } |
@@ -657,6 +671,9 @@ void cleanupMessenger(Messenger *m) | |||
657 | /* FIXME TODO ideally cleanupMessenger will mirror initMessenger | 671 | /* FIXME TODO ideally cleanupMessenger will mirror initMessenger |
658 | * this requires the other modules to expose cleanup functions | 672 | * this requires the other modules to expose cleanup functions |
659 | */ | 673 | */ |
674 | kill_DHT(m->dht); | ||
675 | kill_net_crypto(m->net_crypto); | ||
676 | kill_networking(m->net); | ||
660 | free(m->friendlist); | 677 | free(m->friendlist); |
661 | free(m); | 678 | free(m); |
662 | } | 679 | } |
@@ -672,7 +689,8 @@ void doFriends(Messenger *m) | |||
672 | 689 | ||
673 | for (i = 0; i < m->numfriends; ++i) { | 690 | for (i = 0; i < m->numfriends; ++i) { |
674 | if (m->friendlist[i].status == FRIEND_ADDED) { | 691 | if (m->friendlist[i].status == FRIEND_ADDED) { |
675 | int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, | 692 | int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, |
693 | m->friendlist[i].info, | ||
676 | m->friendlist[i].info_size); | 694 | m->friendlist[i].info_size); |
677 | 695 | ||
678 | if (fr >= 0) { | 696 | if (fr >= 0) { |
@@ -694,12 +712,12 @@ void doFriends(Messenger *m) | |||
694 | } | 712 | } |
695 | } | 713 | } |
696 | 714 | ||
697 | IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); | 715 | IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id); |
698 | 716 | ||
699 | switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { | 717 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { |
700 | case 0: | 718 | case 0: |
701 | if (friendip.ip.i > 1) | 719 | if (friendip.ip.i > 1) |
702 | m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); | 720 | m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); |
703 | 721 | ||
704 | break; | 722 | break; |
705 | 723 | ||
@@ -712,7 +730,7 @@ void doFriends(Messenger *m) | |||
712 | break; | 730 | break; |
713 | 731 | ||
714 | case 4: | 732 | case 4: |
715 | crypto_kill(m->friendlist[i].crypt_connection_id); | 733 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); |
716 | m->friendlist[i].crypt_connection_id = -1; | 734 | m->friendlist[i].crypt_connection_id = -1; |
717 | break; | 735 | break; |
718 | 736 | ||
@@ -741,7 +759,7 @@ void doFriends(Messenger *m) | |||
741 | send_ping(m, i); | 759 | send_ping(m, i); |
742 | } | 760 | } |
743 | 761 | ||
744 | len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); | 762 | len = read_cryptpacket(m->net_crypto, m->friendlist[i].crypt_connection_id, temp); |
745 | uint8_t packet_id = temp[0]; | 763 | uint8_t packet_id = temp[0]; |
746 | uint8_t *data = temp + 1; | 764 | uint8_t *data = temp + 1; |
747 | int data_length = len - 1; | 765 | int data_length = len - 1; |
@@ -833,8 +851,9 @@ void doFriends(Messenger *m) | |||
833 | } | 851 | } |
834 | } | 852 | } |
835 | } else { | 853 | } else { |
836 | if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ | 854 | if (is_cryptoconnected(m->net_crypto, |
837 | crypto_kill(m->friendlist[i].crypt_connection_id); | 855 | m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ |
856 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); | ||
838 | m->friendlist[i].crypt_connection_id = -1; | 857 | m->friendlist[i].crypt_connection_id = -1; |
839 | set_friend_status(m, i, FRIEND_CONFIRMED); | 858 | set_friend_status(m, i, FRIEND_CONFIRMED); |
840 | } | 859 | } |
@@ -844,7 +863,7 @@ void doFriends(Messenger *m) | |||
844 | 863 | ||
845 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { | 864 | if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { |
846 | /* if we stopped recieving ping packets kill it */ | 865 | /* if we stopped recieving ping packets kill it */ |
847 | crypto_kill(m->friendlist[i].crypt_connection_id); | 866 | crypto_kill(m->net_crypto, m->friendlist[i].crypt_connection_id); |
848 | m->friendlist[i].crypt_connection_id = -1; | 867 | m->friendlist[i].crypt_connection_id = -1; |
849 | set_friend_status(m, i, FRIEND_CONFIRMED); | 868 | set_friend_status(m, i, FRIEND_CONFIRMED); |
850 | } | 869 | } |
@@ -857,34 +876,31 @@ void doInbound(Messenger *m) | |||
857 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 876 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
858 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 877 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
859 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 878 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; |
860 | int inconnection = crypto_inbound(public_key, secret_nonce, session_key); | 879 | int inconnection = crypto_inbound(m->net_crypto, public_key, secret_nonce, session_key); |
861 | 880 | ||
862 | if (inconnection != -1) { | 881 | if (inconnection != -1) { |
863 | int friend_id = getfriend_id(m, public_key); | 882 | int friend_id = getfriend_id(m, public_key); |
864 | 883 | ||
865 | if (friend_id != -1) { | 884 | if (friend_id != -1) { |
866 | crypto_kill(m->friendlist[friend_id].crypt_connection_id); | 885 | crypto_kill(m->net_crypto, m->friendlist[friend_id].crypt_connection_id); |
867 | m->friendlist[friend_id].crypt_connection_id = | 886 | m->friendlist[friend_id].crypt_connection_id = |
868 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); | 887 | accept_crypto_inbound(m->net_crypto, inconnection, public_key, secret_nonce, session_key); |
869 | 888 | ||
870 | set_friend_status(m, friend_id, FRIEND_CONFIRMED); | 889 | set_friend_status(m, friend_id, FRIEND_CONFIRMED); |
871 | } | 890 | } |
872 | } | 891 | } |
873 | } | 892 | } |
874 | 893 | ||
875 | 894 | /* the main loop that needs to be run at least 20 times per second. */ | |
876 | /* the main loop that needs to be run at least 200 times per second. */ | ||
877 | void doMessenger(Messenger *m) | 895 | void doMessenger(Messenger *m) |
878 | { | 896 | { |
879 | networking_poll(); | 897 | networking_poll(m->net); |
880 | 898 | ||
881 | doDHT(); | 899 | do_DHT(m->dht); |
882 | doLossless_UDP(); | 900 | do_net_crypto(m->net_crypto); |
883 | doNetCrypto(); | ||
884 | doInbound(m); | 901 | doInbound(m); |
885 | doFriends(m); | 902 | doFriends(m); |
886 | 903 | LANdiscovery(m); | |
887 | timer_poll(); | ||
888 | } | 904 | } |
889 | 905 | ||
890 | /* returns the size of the messenger data (for saving) */ | 906 | /* returns the size of the messenger data (for saving) */ |
@@ -893,7 +909,7 @@ uint32_t Messenger_size(Messenger *m) | |||
893 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES | 909 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES |
894 | + sizeof(uint32_t) // nospam | 910 | + sizeof(uint32_t) // nospam |
895 | + sizeof(uint32_t) // DHT size | 911 | + sizeof(uint32_t) // DHT size |
896 | + DHT_size() // DHT itself | 912 | + DHT_size(m->dht) // DHT itself |
897 | + sizeof(uint32_t) // Friendlist size | 913 | + sizeof(uint32_t) // Friendlist size |
898 | + sizeof(Friend) * m->numfriends // Friendlist itself | 914 | + sizeof(Friend) * m->numfriends // Friendlist itself |
899 | + sizeof(uint16_t) // Own nickname length | 915 | + sizeof(uint16_t) // Own nickname length |
@@ -904,15 +920,15 @@ uint32_t Messenger_size(Messenger *m) | |||
904 | /* save the messenger in data of size Messenger_size() */ | 920 | /* save the messenger in data of size Messenger_size() */ |
905 | void Messenger_save(Messenger *m, uint8_t *data) | 921 | void Messenger_save(Messenger *m, uint8_t *data) |
906 | { | 922 | { |
907 | save_keys(data); | 923 | save_keys(m->net_crypto, data); |
908 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 924 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
909 | uint32_t nospam = get_nospam(); | 925 | uint32_t nospam = get_nospam(&(m->fr)); |
910 | memcpy(data, &nospam, sizeof(nospam)); | 926 | memcpy(data, &nospam, sizeof(nospam)); |
911 | data += sizeof(nospam); | 927 | data += sizeof(nospam); |
912 | uint32_t size = DHT_size(); | 928 | uint32_t size = DHT_size(m->dht); |
913 | memcpy(data, &size, sizeof(size)); | 929 | memcpy(data, &size, sizeof(size)); |
914 | data += sizeof(size); | 930 | data += sizeof(size); |
915 | DHT_save(data); | 931 | DHT_save(m->dht, data); |
916 | data += size; | 932 | data += size; |
917 | size = sizeof(Friend) * m->numfriends; | 933 | size = sizeof(Friend) * m->numfriends; |
918 | memcpy(data, &size, sizeof(size)); | 934 | memcpy(data, &size, sizeof(size)); |
@@ -935,11 +951,11 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
935 | return -1; | 951 | return -1; |
936 | 952 | ||
937 | length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; | 953 | length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; |
938 | load_keys(data); | 954 | load_keys(m->net_crypto, data); |
939 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 955 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
940 | uint32_t nospam; | 956 | uint32_t nospam; |
941 | memcpy(&nospam, data, sizeof(nospam)); | 957 | memcpy(&nospam, data, sizeof(nospam)); |
942 | set_nospam(nospam); | 958 | set_nospam(&(m->fr), nospam); |
943 | data += sizeof(nospam); | 959 | data += sizeof(nospam); |
944 | uint32_t size; | 960 | uint32_t size; |
945 | memcpy(&size, data, sizeof(size)); | 961 | memcpy(&size, data, sizeof(size)); |
@@ -950,7 +966,7 @@ int Messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
950 | 966 | ||
951 | length -= size; | 967 | length -= size; |
952 | 968 | ||
953 | if (DHT_load(data, size) == -1) | 969 | if (DHT_load(m->dht, data, size) == -1) |
954 | return -1; | 970 | return -1; |
955 | 971 | ||
956 | data += size; | 972 | data += size; |
diff --git a/core/Messenger.h b/core/Messenger.h index 9016be93..581c4ba9 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -112,8 +112,11 @@ typedef struct { | |||
112 | } Friend; | 112 | } Friend; |
113 | 113 | ||
114 | typedef struct Messenger { | 114 | typedef struct Messenger { |
115 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
116 | 115 | ||
116 | Networking_Core *net; | ||
117 | Net_Crypto *net_crypto; | ||
118 | DHT *dht; | ||
119 | Friend_Requests fr; | ||
117 | uint8_t name[MAX_NAME_LENGTH]; | 120 | uint8_t name[MAX_NAME_LENGTH]; |
118 | uint16_t name_length; | 121 | uint16_t name_length; |
119 | 122 | ||
@@ -125,6 +128,8 @@ typedef struct Messenger { | |||
125 | Friend *friendlist; | 128 | Friend *friendlist; |
126 | uint32_t numfriends; | 129 | uint32_t numfriends; |
127 | 130 | ||
131 | uint64_t last_LANdiscovery; | ||
132 | |||
128 | void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *); | 133 | void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *); |
129 | void *friend_message_userdata; | 134 | void *friend_message_userdata; |
130 | void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *); | 135 | void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *); |
@@ -219,17 +224,13 @@ int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t lengt | |||
219 | return -1 if failure */ | 224 | return -1 if failure */ |
220 | int setname(Messenger *m, uint8_t *name, uint16_t length); | 225 | int setname(Messenger *m, uint8_t *name, uint16_t length); |
221 | 226 | ||
222 | /** | 227 | /* |
223 | * @brief Get your nickname. | 228 | Get your nickname. |
224 | * | 229 | m The messanger context to use. |
225 | * @param[in] m The messanger context to use. | 230 | name Pointer to a string for the name. |
226 | * | 231 | nlen The length of the string buffer. |
227 | * @param[inout] name Pointer to a string for the name. | 232 | returns Return the length of the name, 0 on error. |
228 | * | 233 | */ |
229 | * @param[in] nlen The length of the string buffer. | ||
230 | * | ||
231 | * @return Return the length of the name, 0 on error. | ||
232 | */ | ||
233 | uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen); | 234 | uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen); |
234 | 235 | ||
235 | /* get name of friendnumber | 236 | /* get name of friendnumber |
diff --git a/core/friend_requests.c b/core/friend_requests.c index 3708f154..ee2da633 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -23,15 +23,12 @@ | |||
23 | 23 | ||
24 | #include "friend_requests.h" | 24 | #include "friend_requests.h" |
25 | 25 | ||
26 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
27 | |||
28 | |||
29 | /* Try to send a friendrequest to peer with public_key | 26 | /* Try to send a friendrequest to peer with public_key |
30 | data is the data in the request and length is the length. | 27 | data is the data in the request and length is the length. |
31 | return -1 if failure. | 28 | return -1 if failure. |
32 | return 0 if it sent the friend request directly to the friend. | 29 | return 0 if it sent the friend request directly to the friend. |
33 | return the number of peers it was routed through if it did not send it directly.*/ | 30 | return the number of peers it was routed through if it did not send it directly.*/ |
34 | int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) | 31 | int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) |
35 | { | 32 | { |
36 | if (length + sizeof(nospam_num) > MAX_DATA_SIZE) | 33 | if (length + sizeof(nospam_num) > MAX_DATA_SIZE) |
37 | return -1; | 34 | return -1; |
@@ -40,25 +37,26 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, | |||
40 | memcpy(temp, &nospam_num, sizeof(nospam_num)); | 37 | memcpy(temp, &nospam_num, sizeof(nospam_num)); |
41 | memcpy(temp + sizeof(nospam_num), data, length); | 38 | memcpy(temp + sizeof(nospam_num), data, length); |
42 | uint8_t packet[MAX_DATA_SIZE]; | 39 | uint8_t packet[MAX_DATA_SIZE]; |
43 | int len = create_request(packet, public_key, temp, length + sizeof(nospam_num), | 40 | int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp, |
41 | length + sizeof(nospam_num), | ||
44 | 32); /* 32 is friend request packet id */ | 42 | 32); /* 32 is friend request packet id */ |
45 | 43 | ||
46 | if (len == -1) | 44 | if (len == -1) |
47 | return -1; | 45 | return -1; |
48 | 46 | ||
49 | IP_Port ip_port = DHT_getfriendip(public_key); | 47 | IP_Port ip_port = DHT_getfriendip(dht, public_key); |
50 | 48 | ||
51 | if (ip_port.ip.i == 1) | 49 | if (ip_port.ip.i == 1) |
52 | return -1; | 50 | return -1; |
53 | 51 | ||
54 | if (ip_port.ip.i != 0) { | 52 | if (ip_port.ip.i != 0) { |
55 | if (sendpacket(ip_port, packet, len) != -1) | 53 | if (sendpacket(dht->c->lossless_udp->net->sock, ip_port, packet, len) != -1) |
56 | return 0; | 54 | return 0; |
57 | 55 | ||
58 | return -1; | 56 | return -1; |
59 | } | 57 | } |
60 | 58 | ||
61 | int num = route_tofriend(public_key, packet, len); | 59 | int num = route_tofriend(dht, public_key, packet, len); |
62 | 60 | ||
63 | if (num == 0) | 61 | if (num == 0) |
64 | return -1; | 62 | return -1; |
@@ -66,58 +64,48 @@ int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, | |||
66 | return num; | 64 | return num; |
67 | } | 65 | } |
68 | 66 | ||
69 | static uint32_t nospam; | 67 | |
70 | /* | 68 | /* |
71 | * Set and get the nospam variable used to prevent one type of friend request spam | 69 | * Set and get the nospam variable used to prevent one type of friend request spam |
72 | */ | 70 | */ |
73 | void set_nospam(uint32_t num) | 71 | void set_nospam(Friend_Requests *fr, uint32_t num) |
74 | { | 72 | { |
75 | nospam = num; | 73 | fr->nospam = num; |
76 | } | 74 | } |
77 | 75 | ||
78 | uint32_t get_nospam() | 76 | uint32_t get_nospam(Friend_Requests *fr) |
79 | { | 77 | { |
80 | return nospam; | 78 | return fr->nospam; |
81 | } | 79 | } |
82 | 80 | ||
83 | static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *); | 81 | |
84 | static uint8_t handle_friendrequest_isset = 0; | ||
85 | static void *handle_friendrequest_userdata; | ||
86 | /* set the function that will be executed when a friend request is received. */ | 82 | /* set the function that will be executed when a friend request is received. */ |
87 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata) | 83 | void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), |
84 | void *userdata) | ||
88 | { | 85 | { |
89 | handle_friendrequest = function; | 86 | fr->handle_friendrequest = function; |
90 | handle_friendrequest_isset = 1; | 87 | fr->handle_friendrequest_isset = 1; |
91 | handle_friendrequest_userdata = userdata; | 88 | fr->handle_friendrequest_userdata = userdata; |
92 | } | 89 | } |
93 | 90 | ||
94 | |||
95 | /*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem | ||
96 | TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/ | ||
97 | |||
98 | #define MAX_RECEIVED_STORED 32 | ||
99 | |||
100 | static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]; | ||
101 | static uint16_t received_requests_index; | ||
102 | |||
103 | /*Add to list of received friend requests*/ | 91 | /*Add to list of received friend requests*/ |
104 | static void addto_receivedlist(uint8_t *client_id) | 92 | static void addto_receivedlist(Friend_Requests *fr, uint8_t *client_id) |
105 | { | 93 | { |
106 | if (received_requests_index >= MAX_RECEIVED_STORED) | 94 | if (fr->received_requests_index >= MAX_RECEIVED_STORED) |
107 | received_requests_index = 0; | 95 | fr->received_requests_index = 0; |
108 | 96 | ||
109 | memcpy(received_requests[received_requests_index], client_id, crypto_box_PUBLICKEYBYTES); | 97 | memcpy(fr->received_requests[fr->received_requests_index], client_id, crypto_box_PUBLICKEYBYTES); |
110 | ++received_requests_index; | 98 | ++fr->received_requests_index; |
111 | } | 99 | } |
112 | 100 | ||
113 | /* Check if a friend request was already received | 101 | /* Check if a friend request was already received |
114 | return 0 if not, 1 if we did */ | 102 | return 0 if not, 1 if we did */ |
115 | static int request_received(uint8_t *client_id) | 103 | static int request_received(Friend_Requests *fr, uint8_t *client_id) |
116 | { | 104 | { |
117 | uint32_t i; | 105 | uint32_t i; |
118 | 106 | ||
119 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) { | 107 | for (i = 0; i < MAX_RECEIVED_STORED; ++i) { |
120 | if (memcmp(received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) | 108 | if (memcmp(fr->received_requests[i], client_id, crypto_box_PUBLICKEYBYTES) == 0) |
121 | return 1; | 109 | return 1; |
122 | } | 110 | } |
123 | 111 | ||
@@ -125,26 +113,29 @@ static int request_received(uint8_t *client_id) | |||
125 | } | 113 | } |
126 | 114 | ||
127 | 115 | ||
128 | static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) | 116 | static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, |
117 | uint32_t length) | ||
129 | { | 118 | { |
130 | if (handle_friendrequest_isset == 0) | 119 | Friend_Requests *fr = object; |
120 | |||
121 | if (fr->handle_friendrequest_isset == 0) | ||
131 | return 1; | 122 | return 1; |
132 | 123 | ||
133 | if (length <= sizeof(nospam)) | 124 | if (length <= sizeof(fr->nospam)) |
134 | return 1; | 125 | return 1; |
135 | 126 | ||
136 | if (request_received(source_pubkey)) | 127 | if (request_received(fr, source_pubkey)) |
137 | return 1; | 128 | return 1; |
138 | 129 | ||
139 | if (memcmp(packet, &nospam, sizeof(nospam)) != 0) | 130 | if (memcmp(packet, &fr->nospam, sizeof(fr->nospam)) != 0) |
140 | return 1; | 131 | return 1; |
141 | 132 | ||
142 | addto_receivedlist(source_pubkey); | 133 | addto_receivedlist(fr, source_pubkey); |
143 | (*handle_friendrequest)(source_pubkey, packet + 4, length - 4, handle_friendrequest_userdata); | 134 | (*fr->handle_friendrequest)(source_pubkey, packet + 4, length - 4, fr->handle_friendrequest_userdata); |
144 | return 0; | 135 | return 0; |
145 | } | 136 | } |
146 | 137 | ||
147 | void friendreq_init(void) | 138 | void friendreq_init(Friend_Requests *fr, Net_Crypto *c) |
148 | { | 139 | { |
149 | cryptopacket_registerhandler(32, &friendreq_handlepacket); | 140 | cryptopacket_registerhandler(c, 32, &friendreq_handlepacket, fr); |
150 | } | 141 | } |
diff --git a/core/friend_requests.h b/core/friend_requests.h index 3ce0df8c..2ebd557b 100644 --- a/core/friend_requests.h +++ b/core/friend_requests.h | |||
@@ -31,21 +31,37 @@ | |||
31 | extern "C" { | 31 | extern "C" { |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | typedef struct { | ||
35 | uint32_t nospam; | ||
36 | void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *); | ||
37 | uint8_t handle_friendrequest_isset; | ||
38 | void *handle_friendrequest_userdata; | ||
39 | |||
40 | /*NOTE: the following is just a temporary fix for the multiple friend requests received at the same time problem | ||
41 | TODO: Make this better (This will most likely tie in with the way we will handle spam.)*/ | ||
42 | |||
43 | #define MAX_RECEIVED_STORED 32 | ||
44 | |||
45 | uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]; | ||
46 | uint16_t received_requests_index; | ||
47 | } Friend_Requests; | ||
48 | |||
34 | /* Try to send a friendrequest to peer with public_key | 49 | /* Try to send a friendrequest to peer with public_key |
35 | data is the data in the request and length is the length. */ | 50 | data is the data in the request and length is the length. */ |
36 | int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); | 51 | int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); |
37 | /* | 52 | /* |
38 | * Set and get the nospam variable used to prevent one type of friend request spam | 53 | * Set and get the nospam variable used to prevent one type of friend request spam |
39 | */ | 54 | */ |
40 | void set_nospam(uint32_t num); | 55 | void set_nospam(Friend_Requests *fr, uint32_t num); |
41 | uint32_t get_nospam(); | 56 | uint32_t get_nospam(Friend_Requests *fr); |
42 | 57 | ||
43 | /* set the function that will be executed when a friend request for us is received. | 58 | /* set the function that will be executed when a friend request for us is received. |
44 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ | 59 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ |
45 | void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata); | 60 | void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), |
61 | void *userdata); | ||
46 | 62 | ||
47 | /* sets up friendreq packet handlers */ | 63 | /* sets up friendreq packet handlers */ |
48 | void friendreq_init(void); | 64 | void friendreq_init(Friend_Requests *fr, Net_Crypto *c); |
49 | 65 | ||
50 | #ifdef __cplusplus | 66 | #ifdef __cplusplus |
51 | } | 67 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index 8fcb62e1..e3757ffb 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -26,42 +26,12 @@ | |||
26 | 26 | ||
27 | #include "net_crypto.h" | 27 | #include "net_crypto.h" |
28 | 28 | ||
29 | /* Our public and secret keys. */ | ||
30 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
31 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
32 | |||
33 | typedef struct { | ||
34 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ | ||
35 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ | ||
36 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ | ||
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. */ | ||
39 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | ||
40 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */ | ||
41 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
42 | (we have received a handshake but no empty data packet), 3 if the connection is established. | ||
43 | 4 if the connection is timed out. */ | ||
44 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ | ||
45 | |||
46 | } Crypto_Connection; | ||
47 | |||
48 | static Crypto_Connection *crypto_connections; | ||
49 | |||
50 | static uint32_t crypto_connections_length; /* Length of connections array */ | ||
51 | |||
52 | #define MAX_CRYPTO_CONNECTIONS crypto_connections_length | ||
53 | |||
54 | #define CONN_NO_CONNECTION 0 | 29 | #define CONN_NO_CONNECTION 0 |
55 | #define CONN_HANDSHAKE_SENT 1 | 30 | #define CONN_HANDSHAKE_SENT 1 |
56 | #define CONN_NOT_CONFIRMED 2 | 31 | #define CONN_NOT_CONFIRMED 2 |
57 | #define CONN_ESTABLISHED 3 | 32 | #define CONN_ESTABLISHED 3 |
58 | #define CONN_TIMED_OUT 4 | 33 | #define CONN_TIMED_OUT 4 |
59 | 34 | ||
60 | #define MAX_INCOMING 64 | ||
61 | |||
62 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | ||
63 | static int incoming_connections[MAX_INCOMING]; | ||
64 | |||
65 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ | 35 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ |
66 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) | 36 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) |
67 | { | 37 | { |
@@ -175,16 +145,16 @@ void random_nonce(uint8_t *nonce) | |||
175 | /* return 0 if there is no received data in the buffer | 145 | /* return 0 if there is no received data in the buffer |
176 | return -1 if the packet was discarded. | 146 | return -1 if the packet was discarded. |
177 | return length of received data if successful */ | 147 | return length of received data if successful */ |
178 | int read_cryptpacket(int crypt_connection_id, uint8_t *data) | 148 | int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data) |
179 | { | 149 | { |
180 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 150 | if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length) |
181 | return 0; | 151 | return 0; |
182 | 152 | ||
183 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) | 153 | if (c->crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
184 | return 0; | 154 | return 0; |
185 | 155 | ||
186 | uint8_t temp_data[MAX_DATA_SIZE]; | 156 | uint8_t temp_data[MAX_DATA_SIZE]; |
187 | int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); | 157 | int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data); |
188 | 158 | ||
189 | if (length == 0) | 159 | if (length == 0) |
190 | return 0; | 160 | return 0; |
@@ -192,12 +162,12 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
192 | if (temp_data[0] != 3) | 162 | if (temp_data[0] != 3) |
193 | return -1; | 163 | return -1; |
194 | 164 | ||
195 | int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, | 165 | int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, |
196 | crypto_connections[crypt_connection_id].recv_nonce, | 166 | c->crypto_connections[crypt_connection_id].recv_nonce, |
197 | temp_data + 1, length - 1, data); | 167 | temp_data + 1, length - 1, data); |
198 | 168 | ||
199 | if (len != -1) { | 169 | if (len != -1) { |
200 | increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); | 170 | increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce); |
201 | return len; | 171 | return len; |
202 | } | 172 | } |
203 | 173 | ||
@@ -206,20 +176,20 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data) | |||
206 | 176 | ||
207 | /* return 0 if data could not be put in packet queue | 177 | /* return 0 if data could not be put in packet queue |
208 | return 1 if data was put into the queue */ | 178 | return 1 if data was put into the queue */ |
209 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | 179 | int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) |
210 | { | 180 | { |
211 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 181 | if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length) |
212 | return 0; | 182 | return 0; |
213 | 183 | ||
214 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) | 184 | if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) |
215 | return 0; | 185 | return 0; |
216 | 186 | ||
217 | if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) | 187 | if (c->crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) |
218 | return 0; | 188 | return 0; |
219 | 189 | ||
220 | uint8_t temp_data[MAX_DATA_SIZE]; | 190 | uint8_t temp_data[MAX_DATA_SIZE]; |
221 | int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, | 191 | int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, |
222 | crypto_connections[crypt_connection_id].sent_nonce, | 192 | c->crypto_connections[crypt_connection_id].sent_nonce, |
223 | data, length, temp_data + 1); | 193 | data, length, temp_data + 1); |
224 | 194 | ||
225 | if (len == -1) | 195 | if (len == -1) |
@@ -227,20 +197,23 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | |||
227 | 197 | ||
228 | temp_data[0] = 3; | 198 | temp_data[0] = 3; |
229 | 199 | ||
230 | if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) | 200 | if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) |
231 | return 0; | 201 | return 0; |
232 | 202 | ||
233 | increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); | 203 | increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce); |
234 | return 1; | 204 | return 1; |
235 | } | 205 | } |
236 | 206 | ||
237 | /* create a request to peer with public_key. | 207 | /* create a request to peer. |
208 | send_public_key and send_secret_key are the pub/secret keys of the sender | ||
209 | recv_public_key is public key of reciever | ||
238 | packet must be an array of MAX_DATA_SIZE big. | 210 | packet must be an array of MAX_DATA_SIZE big. |
239 | Data represents the data we send with the request with length being the length of the data. | 211 | Data represents the data we send with the request with length being the length of the data. |
240 | request_id is the id of the request (32 = friend request, 254 = ping request) | 212 | request_id is the id of the request (32 = friend request, 254 = ping request) |
241 | returns -1 on failure | 213 | returns -1 on failure |
242 | returns the length of the created packet on success */ | 214 | returns the length of the created packet on success */ |
243 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) | 215 | int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, |
216 | uint8_t *data, uint32_t length, uint8_t request_id) | ||
244 | { | 217 | { |
245 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) | 218 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) |
246 | return -1; | 219 | return -1; |
@@ -250,15 +223,15 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
250 | memcpy(temp + 1, data, length); | 223 | memcpy(temp + 1, data, length); |
251 | temp[0] = request_id; | 224 | temp[0] = request_id; |
252 | random_nonce(nonce); | 225 | random_nonce(nonce); |
253 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1, | 226 | int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, |
254 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); | 227 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); |
255 | 228 | ||
256 | if (len == -1) | 229 | if (len == -1) |
257 | return -1; | 230 | return -1; |
258 | 231 | ||
259 | packet[0] = 32; | 232 | packet[0] = 32; |
260 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 233 | memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); |
261 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); | 234 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); |
262 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); | 235 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); |
263 | 236 | ||
264 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; | 237 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; |
@@ -268,17 +241,18 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
268 | in data if a friend or ping request was sent to us and returns the length of the data. | 241 | in data if a friend or ping request was sent to us and returns the length of the data. |
269 | packet is the request packet and length is its length | 242 | packet is the request packet and length is its length |
270 | return -1 if not valid request. */ | 243 | return -1 if not valid request. */ |
271 | static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length) | 244 | static int handle_request(Net_Crypto *c, uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, |
245 | uint16_t length) | ||
272 | { | 246 | { |
273 | 247 | ||
274 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 248 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
275 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && | 249 | length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && |
276 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 250 | memcmp(packet + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
277 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | 251 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); |
278 | uint8_t nonce[crypto_box_NONCEBYTES]; | 252 | uint8_t nonce[crypto_box_NONCEBYTES]; |
279 | uint8_t temp[MAX_DATA_SIZE]; | 253 | uint8_t temp[MAX_DATA_SIZE]; |
280 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); | 254 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); |
281 | int len1 = decrypt_data(public_key, self_secret_key, nonce, | 255 | int len1 = decrypt_data(public_key, c->self_secret_key, nonce, |
282 | packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, | 256 | packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, |
283 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); | 257 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); |
284 | 258 | ||
@@ -293,35 +267,37 @@ static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_i | |||
293 | return -1; | 267 | return -1; |
294 | } | 268 | } |
295 | 269 | ||
296 | static cryptopacket_handler_callback cryptopackethandlers[256] = {0}; | 270 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object) |
297 | |||
298 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb) | ||
299 | { | 271 | { |
300 | cryptopackethandlers[byte] = cb; | 272 | c->cryptopackethandlers[byte].function = cb; |
273 | c->cryptopackethandlers[byte].object = object; | ||
301 | } | 274 | } |
302 | 275 | ||
303 | static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length) | 276 | static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
304 | { | 277 | { |
278 | DHT *dht = object; | ||
279 | |||
305 | if (packet[0] == 32) { | 280 | if (packet[0] == 32) { |
306 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | 281 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || |
307 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 282 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
308 | return 1; | 283 | return 1; |
309 | 284 | ||
310 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | 285 | if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. |
311 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 286 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
312 | uint8_t data[MAX_DATA_SIZE]; | 287 | uint8_t data[MAX_DATA_SIZE]; |
313 | uint8_t number; | 288 | uint8_t number; |
314 | int len = handle_request(public_key, data, &number, packet, length); | 289 | int len = handle_request(dht->c, public_key, data, &number, packet, length); |
315 | 290 | ||
316 | if (len == -1 || len == 0) | 291 | if (len == -1 || len == 0) |
317 | return 1; | 292 | return 1; |
318 | 293 | ||
319 | if (!cryptopackethandlers[number]) return 1; | 294 | if (!dht->c->cryptopackethandlers[number].function) return 1; |
320 | 295 | ||
321 | cryptopackethandlers[number](source, public_key, data, len); | 296 | dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, data, |
297 | len); | ||
322 | 298 | ||
323 | } else { /* if request is not for us, try routing it. */ | 299 | } else { /* if request is not for us, try routing it. */ |
324 | if (route_packet(packet + 1, packet, length) == length) | 300 | if (route_packet(dht, packet + 1, packet, length) == length) //NOTE |
325 | return 0; | 301 | return 0; |
326 | } | 302 | } |
327 | } | 303 | } |
@@ -332,7 +308,8 @@ static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length) | |||
332 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key | 308 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key |
333 | to peer with connection_id and public_key | 309 | to peer with connection_id and public_key |
334 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ | 310 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ |
335 | static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 311 | static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, |
312 | uint8_t *session_key) | ||
336 | { | 313 | { |
337 | uint8_t temp_data[MAX_DATA_SIZE]; | 314 | uint8_t temp_data[MAX_DATA_SIZE]; |
338 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; | 315 | uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; |
@@ -342,22 +319,23 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t | |||
342 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); | 319 | memcpy(temp, secret_nonce, crypto_box_NONCEBYTES); |
343 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); | 320 | memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES); |
344 | 321 | ||
345 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 322 | int len = encrypt_data(public_key, c->self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
346 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); | 323 | 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); |
347 | 324 | ||
348 | if (len == -1) | 325 | if (len == -1) |
349 | return 0; | 326 | return 0; |
350 | 327 | ||
351 | temp_data[0] = 2; | 328 | temp_data[0] = 2; |
352 | memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); | 329 | memcpy(temp_data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); |
353 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); | 330 | memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); |
354 | return write_packet(connection_id, temp_data, len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | 331 | return write_packet(c->lossless_udp, connection_id, temp_data, |
332 | len + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); | ||
355 | } | 333 | } |
356 | 334 | ||
357 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length | 335 | /* Extract secret nonce, session public key and public_key from a packet(data) with length length |
358 | return 1 if successful | 336 | return 1 if successful |
359 | return 0 if failure */ | 337 | return 0 if failure */ |
360 | static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | 338 | static int handle_cryptohandshake(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, |
361 | uint8_t *session_key, uint8_t *data, uint16_t length) | 339 | uint8_t *session_key, uint8_t *data, uint16_t length) |
362 | { | 340 | { |
363 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); | 341 | int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); |
@@ -374,7 +352,7 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | |||
374 | 352 | ||
375 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); | 353 | memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); |
376 | 354 | ||
377 | int len = decrypt_data(public_key, self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, | 355 | int len = decrypt_data(public_key, c->self_secret_key, data + 1 + crypto_box_PUBLICKEYBYTES, |
378 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, | 356 | data + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, |
379 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); | 357 | crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad, temp); |
380 | 358 | ||
@@ -389,13 +367,13 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, | |||
389 | /* get crypto connection id from public key of peer | 367 | /* get crypto connection id from public key of peer |
390 | return -1 if there are no connections like we are looking for | 368 | return -1 if there are no connections like we are looking for |
391 | return id if it found it */ | 369 | return id if it found it */ |
392 | static int getcryptconnection_id(uint8_t *public_key) | 370 | static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) |
393 | { | 371 | { |
394 | uint32_t i; | 372 | uint32_t i; |
395 | 373 | ||
396 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 374 | for (i = 0; i < c->crypto_connections_length; ++i) { |
397 | if (crypto_connections[i].status != CONN_NO_CONNECTION) | 375 | if (c->crypto_connections[i].status != CONN_NO_CONNECTION) |
398 | if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) | 376 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) |
399 | return i; | 377 | return i; |
400 | } | 378 | } |
401 | 379 | ||
@@ -404,63 +382,63 @@ static int getcryptconnection_id(uint8_t *public_key) | |||
404 | 382 | ||
405 | /* set the size of the friend list to numfriends | 383 | /* set the size of the friend list to numfriends |
406 | return -1 if realloc fails */ | 384 | return -1 if realloc fails */ |
407 | int realloc_cryptoconnection(uint32_t num) | 385 | int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) |
408 | { | 386 | { |
409 | if (num == 0) { | 387 | if (num == 0) { |
410 | free(crypto_connections); | 388 | free(c->crypto_connections); |
411 | crypto_connections = NULL; | 389 | c->crypto_connections = NULL; |
412 | return 0; | 390 | return 0; |
413 | } | 391 | } |
414 | 392 | ||
415 | Crypto_Connection *newcrypto_connections = realloc(crypto_connections, num * sizeof(Crypto_Connection)); | 393 | Crypto_Connection *newcrypto_connections = realloc(c->crypto_connections, num * sizeof(Crypto_Connection)); |
416 | 394 | ||
417 | if (newcrypto_connections == NULL) | 395 | if (newcrypto_connections == NULL) |
418 | return -1; | 396 | return -1; |
419 | 397 | ||
420 | crypto_connections = newcrypto_connections; | 398 | c->crypto_connections = newcrypto_connections; |
421 | return 0; | 399 | return 0; |
422 | } | 400 | } |
423 | 401 | ||
424 | /* Start a secure connection with other peer who has public_key and ip_port | 402 | /* Start a secure connection with other peer who has public_key and ip_port |
425 | returns -1 if failure | 403 | returns -1 if failure |
426 | returns crypt_connection_id of the initialized connection if everything went well. */ | 404 | returns crypt_connection_id of the initialized connection if everything went well. */ |
427 | int crypto_connect(uint8_t *public_key, IP_Port ip_port) | 405 | int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) |
428 | { | 406 | { |
429 | uint32_t i; | 407 | uint32_t i; |
430 | int id = getcryptconnection_id(public_key); | 408 | int id = getcryptconnection_id(c, public_key); |
431 | 409 | ||
432 | if (id != -1) { | 410 | if (id != -1) { |
433 | IP_Port c_ip = connection_ip(crypto_connections[id].number); | 411 | IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number); |
434 | 412 | ||
435 | if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) | 413 | if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) |
436 | return -1; | 414 | return -1; |
437 | } | 415 | } |
438 | 416 | ||
439 | if (realloc_cryptoconnection(crypto_connections_length + 1) == -1) | 417 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) |
440 | return -1; | 418 | return -1; |
441 | 419 | ||
442 | memset(&crypto_connections[crypto_connections_length], 0, sizeof(Crypto_Connection)); | 420 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); |
443 | crypto_connections[crypto_connections_length].number = ~0; | 421 | c->crypto_connections[c->crypto_connections_length].number = ~0; |
444 | 422 | ||
445 | for (i = 0; i <= MAX_CRYPTO_CONNECTIONS; ++i) { | 423 | for (i = 0; i <= c->crypto_connections_length; ++i) { |
446 | if (crypto_connections[i].status == CONN_NO_CONNECTION) { | 424 | if (c->crypto_connections[i].status == CONN_NO_CONNECTION) { |
447 | int id = new_connection(ip_port); | 425 | int id = new_connection(c->lossless_udp, ip_port); |
448 | 426 | ||
449 | if (id == -1) | 427 | if (id == -1) |
450 | return -1; | 428 | return -1; |
451 | 429 | ||
452 | crypto_connections[i].number = id; | 430 | c->crypto_connections[i].number = id; |
453 | crypto_connections[i].status = CONN_HANDSHAKE_SENT; | 431 | c->crypto_connections[i].status = CONN_HANDSHAKE_SENT; |
454 | random_nonce(crypto_connections[i].recv_nonce); | 432 | random_nonce(c->crypto_connections[i].recv_nonce); |
455 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 433 | memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
456 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 434 | crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); |
457 | 435 | ||
458 | if (crypto_connections_length == i) | 436 | if (c->crypto_connections_length == i) |
459 | ++crypto_connections_length; | 437 | ++c->crypto_connections_length; |
460 | 438 | ||
461 | if (send_cryptohandshake(id, public_key, crypto_connections[i].recv_nonce, | 439 | if (send_cryptohandshake(c, id, public_key, c->crypto_connections[i].recv_nonce, |
462 | crypto_connections[i].sessionpublic_key) == 1) { | 440 | c->crypto_connections[i].sessionpublic_key) == 1) { |
463 | increment_nonce(crypto_connections[i].recv_nonce); | 441 | increment_nonce(c->crypto_connections[i].recv_nonce); |
464 | return i; | 442 | return i; |
465 | } | 443 | } |
466 | 444 | ||
@@ -478,25 +456,26 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port) | |||
478 | and the session public key for the connection in session_key | 456 | and the session public key for the connection in session_key |
479 | to accept it see: accept_crypto_inbound(...) | 457 | to accept it see: accept_crypto_inbound(...) |
480 | to refuse it just call kill_connection(...) on the connection id */ | 458 | to refuse it just call kill_connection(...) on the connection id */ |
481 | int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 459 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) |
482 | { | 460 | { |
483 | uint32_t i; | 461 | uint32_t i; |
484 | 462 | ||
485 | for (i = 0; i < MAX_INCOMING; ++i) { | 463 | for (i = 0; i < MAX_INCOMING; ++i) { |
486 | if (incoming_connections[i] != -1) { | 464 | if (c->incoming_connections[i] != -1) { |
487 | if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) { | 465 | if (is_connected(c->lossless_udp, c->incoming_connections[i]) == 4 |
488 | kill_connection(incoming_connections[i]); | 466 | || is_connected(c->lossless_udp, c->incoming_connections[i]) == 0) { |
489 | incoming_connections[i] = -1; | 467 | kill_connection(c->lossless_udp, c->incoming_connections[i]); |
468 | c->incoming_connections[i] = -1; | ||
490 | continue; | 469 | continue; |
491 | } | 470 | } |
492 | 471 | ||
493 | if (id_packet(incoming_connections[i]) == 2) { | 472 | if (id_packet(c->lossless_udp, c->incoming_connections[i]) == 2) { |
494 | uint8_t temp_data[MAX_DATA_SIZE]; | 473 | uint8_t temp_data[MAX_DATA_SIZE]; |
495 | uint16_t len = read_packet(incoming_connections[i], temp_data); | 474 | uint16_t len = read_packet(c->lossless_udp, c->incoming_connections[i], temp_data); |
496 | 475 | ||
497 | if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { | 476 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { |
498 | int connection_id = incoming_connections[i]; | 477 | int connection_id = c->incoming_connections[i]; |
499 | incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ | 478 | c->incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ |
500 | return connection_id; | 479 | return connection_id; |
501 | } | 480 | } |
502 | } | 481 | } |
@@ -509,25 +488,25 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_ | |||
509 | /* kill a crypto connection | 488 | /* kill a crypto connection |
510 | return 0 if killed successfully | 489 | return 0 if killed successfully |
511 | return 1 if there was a problem. */ | 490 | return 1 if there was a problem. */ |
512 | int crypto_kill(int crypt_connection_id) | 491 | int crypto_kill(Net_Crypto *c, int crypt_connection_id) |
513 | { | 492 | { |
514 | if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) | 493 | if (crypt_connection_id < 0 || crypt_connection_id >= c->crypto_connections_length) |
515 | return 1; | 494 | return 1; |
516 | 495 | ||
517 | if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { | 496 | if (c->crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { |
518 | crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; | 497 | c->crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; |
519 | kill_connection(crypto_connections[crypt_connection_id].number); | 498 | kill_connection(c->lossless_udp, c->crypto_connections[crypt_connection_id].number); |
520 | memset(&crypto_connections[crypt_connection_id], 0 , sizeof(Crypto_Connection)); | 499 | memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection)); |
521 | crypto_connections[crypt_connection_id].number = ~0; | 500 | c->crypto_connections[crypt_connection_id].number = ~0; |
522 | uint32_t i; | 501 | uint32_t i; |
523 | 502 | ||
524 | for (i = crypto_connections_length; i != 0; --i) { | 503 | for (i = c->crypto_connections_length; i != 0; --i) { |
525 | if (crypto_connections[i - 1].status != CONN_NO_CONNECTION) | 504 | if (c->crypto_connections[i - 1].status != CONN_NO_CONNECTION) |
526 | break; | 505 | break; |
527 | } | 506 | } |
528 | 507 | ||
529 | crypto_connections_length = i; | 508 | c->crypto_connections_length = i; |
530 | realloc_cryptoconnection(crypto_connections_length); | 509 | realloc_cryptoconnection(c, c->crypto_connections_length); |
531 | return 0; | 510 | return 0; |
532 | } | 511 | } |
533 | 512 | ||
@@ -537,7 +516,8 @@ int crypto_kill(int crypt_connection_id) | |||
537 | /* accept an incoming connection using the parameters provided by crypto_inbound | 516 | /* accept an incoming connection using the parameters provided by crypto_inbound |
538 | return -1 if not successful | 517 | return -1 if not successful |
539 | returns the crypt_connection_id if successful */ | 518 | returns the crypt_connection_id if successful */ |
540 | int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) | 519 | int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, |
520 | uint8_t *session_key) | ||
541 | { | 521 | { |
542 | uint32_t i; | 522 | uint32_t i; |
543 | 523 | ||
@@ -549,37 +529,38 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
549 | { | 529 | { |
550 | return -1; | 530 | return -1; |
551 | }*/ | 531 | }*/ |
552 | if (realloc_cryptoconnection(crypto_connections_length + 1) == -1) | 532 | if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1) |
553 | return -1; | 533 | return -1; |
554 | 534 | ||
555 | memset(&crypto_connections[crypto_connections_length], 0, sizeof(Crypto_Connection)); | 535 | memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection)); |
556 | crypto_connections[crypto_connections_length].number = ~0; | 536 | c->crypto_connections[c->crypto_connections_length].number = ~0; |
557 | 537 | ||
558 | for (i = 0; i <= MAX_CRYPTO_CONNECTIONS; ++i) { | 538 | for (i = 0; i <= c->crypto_connections_length; ++i) { |
559 | if (crypto_connections[i].status == CONN_NO_CONNECTION) { | 539 | if (c->crypto_connections[i].status == CONN_NO_CONNECTION) { |
560 | crypto_connections[i].number = connection_id; | 540 | c->crypto_connections[i].number = connection_id; |
561 | crypto_connections[i].status = CONN_NOT_CONFIRMED; | 541 | c->crypto_connections[i].status = CONN_NOT_CONFIRMED; |
562 | random_nonce(crypto_connections[i].recv_nonce); | 542 | random_nonce(c->crypto_connections[i].recv_nonce); |
563 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 543 | memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); |
564 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 544 | memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
565 | increment_nonce(crypto_connections[i].sent_nonce); | 545 | increment_nonce(c->crypto_connections[i].sent_nonce); |
566 | memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 546 | memcpy(c->crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
567 | 547 | ||
568 | crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); | 548 | crypto_box_keypair(c->crypto_connections[i].sessionpublic_key, c->crypto_connections[i].sessionsecret_key); |
569 | 549 | ||
570 | if (crypto_connections_length == i) | 550 | if (c->crypto_connections_length == i) |
571 | ++crypto_connections_length; | 551 | ++c->crypto_connections_length; |
572 | 552 | ||
573 | if (send_cryptohandshake(connection_id, public_key, crypto_connections[i].recv_nonce, | 553 | if (send_cryptohandshake(c, connection_id, public_key, c->crypto_connections[i].recv_nonce, |
574 | crypto_connections[i].sessionpublic_key) == 1) { | 554 | c->crypto_connections[i].sessionpublic_key) == 1) { |
575 | increment_nonce(crypto_connections[i].recv_nonce); | 555 | increment_nonce(c->crypto_connections[i].recv_nonce); |
576 | uint32_t zero = 0; | 556 | uint32_t zero = 0; |
577 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | 557 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, |
578 | crypto_connections[i].sessionsecret_key, | 558 | c->crypto_connections[i].sessionsecret_key, |
579 | crypto_connections[i].shared_key); | 559 | c->crypto_connections[i].shared_key); |
580 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ | 560 | c->crypto_connections[i].status = |
581 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 561 | CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
582 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | 562 | write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); |
563 | c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | ||
583 | return i; | 564 | return i; |
584 | } | 565 | } |
585 | 566 | ||
@@ -593,48 +574,46 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre | |||
593 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet | 574 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connection is not confirmed yet |
594 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 575 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
595 | 4 if the connection is timed out and waiting to be killed */ | 576 | 4 if the connection is timed out and waiting to be killed */ |
596 | int is_cryptoconnected(int crypt_connection_id) | 577 | int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id) |
597 | { | 578 | { |
598 | if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) | 579 | if (crypt_connection_id >= 0 && crypt_connection_id < c->crypto_connections_length) |
599 | return crypto_connections[crypt_connection_id].status; | 580 | return c->crypto_connections[crypt_connection_id].status; |
600 | 581 | ||
601 | return CONN_NO_CONNECTION; | 582 | return CONN_NO_CONNECTION; |
602 | } | 583 | } |
603 | 584 | ||
604 | /* Generate our public and private keys | 585 | void new_keys(Net_Crypto *c) |
605 | Only call this function the first time the program starts. */ | ||
606 | void new_keys(void) | ||
607 | { | 586 | { |
608 | crypto_box_keypair(self_public_key, self_secret_key); | 587 | crypto_box_keypair(c->self_public_key, c->self_secret_key); |
609 | } | 588 | } |
610 | 589 | ||
611 | /* save the public and private keys to the keys array | 590 | /* save the public and private keys to the keys array |
612 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 591 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
613 | void save_keys(uint8_t *keys) | 592 | void save_keys(Net_Crypto *c, uint8_t *keys) |
614 | { | 593 | { |
615 | memcpy(keys, self_public_key, crypto_box_PUBLICKEYBYTES); | 594 | memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES); |
616 | memcpy(keys + crypto_box_PUBLICKEYBYTES, self_secret_key, crypto_box_SECRETKEYBYTES); | 595 | memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); |
617 | } | 596 | } |
618 | 597 | ||
619 | /* load the public and private keys from the keys array | 598 | /* load the public and private keys from the keys array |
620 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 599 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
621 | void load_keys(uint8_t *keys) | 600 | void load_keys(Net_Crypto *c, uint8_t *keys) |
622 | { | 601 | { |
623 | memcpy(self_public_key, keys, crypto_box_PUBLICKEYBYTES); | 602 | memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES); |
624 | memcpy(self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); | 603 | memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); |
625 | } | 604 | } |
626 | 605 | ||
627 | /* TODO: optimize this | 606 | /* TODO: optimize this |
628 | adds an incoming connection to the incoming_connection list. | 607 | adds an incoming connection to the incoming_connection list. |
629 | returns 0 if successful | 608 | returns 0 if successful |
630 | returns 1 if failure */ | 609 | returns 1 if failure */ |
631 | static int new_incoming(int id) | 610 | static int new_incoming(Net_Crypto *c, int id) |
632 | { | 611 | { |
633 | uint32_t i; | 612 | uint32_t i; |
634 | 613 | ||
635 | for (i = 0; i < MAX_INCOMING; ++i) { | 614 | for (i = 0; i < MAX_INCOMING; ++i) { |
636 | if (incoming_connections[i] == -1) { | 615 | if (c->incoming_connections[i] == -1) { |
637 | incoming_connections[i] = id; | 616 | c->incoming_connections[i] = id; |
638 | return 0; | 617 | return 0; |
639 | } | 618 | } |
640 | } | 619 | } |
@@ -644,81 +623,83 @@ static int new_incoming(int id) | |||
644 | 623 | ||
645 | /* TODO: optimize this | 624 | /* TODO: optimize this |
646 | handle all new incoming connections. */ | 625 | handle all new incoming connections. */ |
647 | static void handle_incomings(void) | 626 | static void handle_incomings(Net_Crypto *c) |
648 | { | 627 | { |
649 | int income; | 628 | int income; |
650 | 629 | ||
651 | while (1) { | 630 | while (1) { |
652 | income = incoming_connection(); | 631 | income = incoming_connection(c->lossless_udp); |
653 | 632 | ||
654 | if (income == -1 || new_incoming(income) ) | 633 | if (income == -1 || new_incoming(c, income) ) |
655 | break; | 634 | break; |
656 | } | 635 | } |
657 | } | 636 | } |
658 | 637 | ||
659 | /* handle received packets for not yet established crypto connections. */ | 638 | /* handle received packets for not yet established crypto connections. */ |
660 | static void receive_crypto(void) | 639 | static void receive_crypto(Net_Crypto *c) |
661 | { | 640 | { |
662 | uint32_t i; | 641 | uint32_t i; |
663 | 642 | ||
664 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 643 | for (i = 0; i < c->crypto_connections_length; ++i) { |
665 | if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { | 644 | if (c->crypto_connections[i].status == CONN_HANDSHAKE_SENT) { |
666 | uint8_t temp_data[MAX_DATA_SIZE]; | 645 | uint8_t temp_data[MAX_DATA_SIZE]; |
667 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 646 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
668 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 647 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
669 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 648 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; |
670 | uint16_t len; | 649 | uint16_t len; |
671 | 650 | ||
672 | if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ | 651 | if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* handle handshake packet. */ |
673 | len = read_packet(crypto_connections[i].number, temp_data); | 652 | len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); |
674 | 653 | ||
675 | if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { | 654 | if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { |
676 | if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 655 | if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
677 | memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); | 656 | memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); |
678 | memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); | 657 | memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); |
679 | increment_nonce(crypto_connections[i].sent_nonce); | 658 | increment_nonce(c->crypto_connections[i].sent_nonce); |
680 | uint32_t zero = 0; | 659 | uint32_t zero = 0; |
681 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | 660 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, |
682 | crypto_connections[i].sessionsecret_key, | 661 | c->crypto_connections[i].sessionsecret_key, |
683 | crypto_connections[i].shared_key); | 662 | c->crypto_connections[i].shared_key); |
684 | crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ | 663 | c->crypto_connections[i].status = |
685 | write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); | 664 | CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ |
686 | crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | 665 | write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); |
666 | c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ | ||
687 | } | 667 | } |
688 | } | 668 | } |
689 | } else if (id_packet(crypto_connections[i].number) != -1) { // This should not happen kill the connection if it does | 669 | } else if (id_packet(c->lossless_udp, |
690 | crypto_kill(crypto_connections[i].number); | 670 | c->crypto_connections[i].number) != -1) { // This should not happen kill the connection if it does |
671 | crypto_kill(c, i); | ||
691 | return; | 672 | return; |
692 | } | 673 | } |
693 | } | 674 | } |
694 | 675 | ||
695 | if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { | 676 | if (c->crypto_connections[i].status == CONN_NOT_CONFIRMED) { |
696 | if (id_packet(crypto_connections[i].number) == 3) { | 677 | if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { |
697 | uint8_t temp_data[MAX_DATA_SIZE]; | 678 | uint8_t temp_data[MAX_DATA_SIZE]; |
698 | uint8_t data[MAX_DATA_SIZE]; | 679 | uint8_t data[MAX_DATA_SIZE]; |
699 | int length = read_packet(crypto_connections[i].number, temp_data); | 680 | int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); |
700 | int len = decrypt_data(crypto_connections[i].peersessionpublic_key, | 681 | int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, |
701 | crypto_connections[i].sessionsecret_key, | 682 | c->crypto_connections[i].sessionsecret_key, |
702 | crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); | 683 | c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); |
703 | uint32_t zero = 0; | 684 | uint32_t zero = 0; |
704 | 685 | ||
705 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { | 686 | if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { |
706 | increment_nonce(crypto_connections[i].recv_nonce); | 687 | increment_nonce(c->crypto_connections[i].recv_nonce); |
707 | encrypt_precompute(crypto_connections[i].peersessionpublic_key, | 688 | encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, |
708 | crypto_connections[i].sessionsecret_key, | 689 | c->crypto_connections[i].sessionsecret_key, |
709 | crypto_connections[i].shared_key); | 690 | c->crypto_connections[i].shared_key); |
710 | crypto_connections[i].status = CONN_ESTABLISHED; | 691 | c->crypto_connections[i].status = CONN_ESTABLISHED; |
711 | 692 | ||
712 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ | 693 | /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ |
713 | kill_connection_in(crypto_connections[i].number, 3000000); | 694 | kill_connection_in(c->lossless_udp, c->crypto_connections[i].number, 3000000); |
714 | } else { | 695 | } else { |
715 | crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does | 696 | crypto_kill(c, i); // This should not happen kill the connection if it does |
716 | return; | 697 | return; |
717 | } | 698 | } |
718 | } else if (id_packet(crypto_connections[i].number) != -1) | 699 | } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) |
719 | /* This should not happen | 700 | /* This should not happen |
720 | kill the connection if it does */ | 701 | kill the connection if it does */ |
721 | crypto_kill(crypto_connections[i].number); | 702 | crypto_kill(c, i); |
722 | 703 | ||
723 | return; | 704 | return; |
724 | } | 705 | } |
@@ -727,33 +708,64 @@ static void receive_crypto(void) | |||
727 | 708 | ||
728 | /* run this to (re)initialize net_crypto | 709 | /* run this to (re)initialize net_crypto |
729 | sets all the global connection variables to their default values. */ | 710 | sets all the global connection variables to their default values. */ |
730 | void initNetCrypto(void) | 711 | Net_Crypto *new_net_crypto(Networking_Core *net) |
712 | { | ||
713 | if (net == NULL) | ||
714 | return NULL; | ||
715 | |||
716 | Net_Crypto *temp = calloc(1, sizeof(Net_Crypto)); | ||
717 | |||
718 | if (temp == NULL) | ||
719 | return NULL; | ||
720 | |||
721 | temp->lossless_udp = new_lossless_udp(net); | ||
722 | |||
723 | if (temp->lossless_udp == NULL) | ||
724 | return NULL; | ||
725 | |||
726 | memset(temp->incoming_connections, -1 , sizeof(int) * MAX_INCOMING); | ||
727 | return temp; | ||
728 | } | ||
729 | |||
730 | void init_cryptopackets(void *dht) | ||
731 | { | 731 | { |
732 | memset(incoming_connections, -1 , sizeof(incoming_connections)); | 732 | DHT *s_dht = dht; |
733 | networking_registerhandler(32, &cryptopacket_handle); | 733 | networking_registerhandler(s_dht->c->lossless_udp->net, 32, &cryptopacket_handle, s_dht); |
734 | } | 734 | } |
735 | 735 | ||
736 | static void killTimedout(void) | 736 | static void kill_timedout(Net_Crypto *c) |
737 | { | 737 | { |
738 | uint32_t i; | 738 | uint32_t i; |
739 | 739 | ||
740 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { | 740 | for (i = 0; i < c->crypto_connections_length; ++i) { |
741 | if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4) | 741 | if (c->crypto_connections[i].status != CONN_NO_CONNECTION |
742 | crypto_connections[i].status = CONN_TIMED_OUT; | 742 | && is_connected(c->lossless_udp, c->crypto_connections[i].number) == 4) |
743 | else if (is_connected(crypto_connections[i].number) == 4) { | 743 | c->crypto_connections[i].status = CONN_TIMED_OUT; |
744 | kill_connection(crypto_connections[i].number); | 744 | else if (is_connected(c->lossless_udp, c->crypto_connections[i].number) == 4) { |
745 | crypto_connections[i].number = ~0; | 745 | kill_connection(c->lossless_udp, c->crypto_connections[i].number); |
746 | c->crypto_connections[i].number = ~0; | ||
746 | } | 747 | } |
747 | } | 748 | } |
748 | } | 749 | } |
749 | 750 | ||
750 | /* main loop */ | 751 | /* main loop */ |
751 | void doNetCrypto(void) | 752 | void do_net_crypto(Net_Crypto *c) |
752 | { | 753 | { |
753 | /* TODO:check if friend requests were sent correctly | 754 | do_lossless_udp(c->lossless_udp); |
754 | handle new incoming connections | 755 | handle_incomings(c); |
755 | handle friend requests */ | 756 | receive_crypto(c); |
756 | handle_incomings(); | 757 | kill_timedout(c); |
757 | receive_crypto(); | 758 | } |
758 | killTimedout(); | 759 | |
760 | void kill_net_crypto(Net_Crypto *c) | ||
761 | { | ||
762 | uint32_t i; | ||
763 | |||
764 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
765 | crypto_kill(c, i); | ||
766 | } | ||
767 | |||
768 | kill_lossless_udp(c->lossless_udp); | ||
769 | memset(c, 0, sizeof(Net_Crypto)); | ||
770 | free(c); | ||
759 | } | 771 | } |
diff --git a/core/net_crypto.h b/core/net_crypto.h index 742d9fdc..46bcf250 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -25,15 +25,54 @@ | |||
25 | #define NET_CRYPTO_H | 25 | #define NET_CRYPTO_H |
26 | 26 | ||
27 | #include "Lossless_UDP.h" | 27 | #include "Lossless_UDP.h" |
28 | #include "DHT.h" | ||
29 | 28 | ||
30 | #ifdef __cplusplus | 29 | #ifdef __cplusplus |
31 | extern "C" { | 30 | extern "C" { |
32 | #endif | 31 | #endif |
33 | 32 | ||
34 | /* Our public key. */ | 33 | #define MAX_INCOMING 64 |
35 | extern uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 34 | |
36 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | 35 | typedef struct { |
36 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* the real public key of the peer. */ | ||
37 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* nonce of received packets */ | ||
38 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* nonce of sent packets. */ | ||
39 | uint8_t sessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* our public key for this session. */ | ||
40 | uint8_t sessionsecret_key[crypto_box_SECRETKEYBYTES]; /* our private key for this session. */ | ||
41 | uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ | ||
42 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; /* the precomputed shared key from encrypt_precompute */ | ||
43 | uint8_t status; /* 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | ||
44 | (we have received a handshake but no empty data packet), 3 if the connection is established. | ||
45 | 4 if the connection is timed out. */ | ||
46 | uint16_t number; /* Lossless_UDP connection number corresponding to this connection. */ | ||
47 | |||
48 | } Crypto_Connection; | ||
49 | |||
50 | typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, | ||
51 | uint32_t len); | ||
52 | |||
53 | typedef struct { | ||
54 | cryptopacket_handler_callback function; | ||
55 | void *object; | ||
56 | } Cryptopacket_Handles; | ||
57 | |||
58 | typedef struct { | ||
59 | Lossless_UDP *lossless_udp; | ||
60 | |||
61 | Crypto_Connection *crypto_connections; | ||
62 | |||
63 | uint32_t crypto_connections_length; /* Length of connections array */ | ||
64 | |||
65 | /* Our public and secret keys. */ | ||
66 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
67 | uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; | ||
68 | |||
69 | /* keeps track of the connection numbers for friends request so we can check later if they were sent */ | ||
70 | int incoming_connections[MAX_INCOMING]; | ||
71 | |||
72 | Cryptopacket_Handles cryptopackethandlers[256]; | ||
73 | } Net_Crypto; | ||
74 | |||
75 | #include "DHT.h" | ||
37 | 76 | ||
38 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) | 77 | #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) |
39 | 78 | ||
@@ -75,34 +114,36 @@ void random_nonce(uint8_t *nonce); | |||
75 | /* return 0 if there is no received data in the buffer | 114 | /* return 0 if there is no received data in the buffer |
76 | return -1 if the packet was discarded. | 115 | return -1 if the packet was discarded. |
77 | return length of received data if successful */ | 116 | return length of received data if successful */ |
78 | int read_cryptpacket(int crypt_connection_id, uint8_t *data); | 117 | int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data); |
79 | 118 | ||
80 | /* return 0 if data could not be put in packet queue | 119 | /* return 0 if data could not be put in packet queue |
81 | return 1 if data was put into the queue */ | 120 | return 1 if data was put into the queue */ |
82 | int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); | 121 | int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); |
83 | 122 | ||
84 | /* create a request to peer with public_key. | 123 | /* create a request to peer. |
85 | packet must be an array of MAX_DATA_SIZE big. | 124 | send_public_key and send_secret_key are the pub/secret keys of the sender |
86 | Data represents the data we send with the request with length being the length of the data. | 125 | recv_public_key is public key of reciever |
87 | request_id is the id of the request (32 = friend request, 254 = ping request) | 126 | packet must be an array of MAX_DATA_SIZE big. |
88 | returns -1 on failure | 127 | Data represents the data we send with the request with length being the length of the data. |
89 | returns the length of the created packet on success */ | 128 | request_id is the id of the request (32 = friend request, 254 = ping request) |
90 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id); | 129 | returns -1 on failure |
130 | returns the length of the created packet on success */ | ||
131 | int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, | ||
132 | uint8_t *data, uint32_t length, uint8_t request_id); | ||
91 | 133 | ||
92 | 134 | ||
93 | typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len); | ||
94 | /* Function to call when request beginning with byte is received */ | 135 | /* Function to call when request beginning with byte is received */ |
95 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); | 136 | void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object); |
96 | 137 | ||
97 | /* Start a secure connection with other peer who has public_key and ip_port | 138 | /* Start a secure connection with other peer who has public_key and ip_port |
98 | returns -1 if failure | 139 | returns -1 if failure |
99 | returns crypt_connection_id of the initialized connection if everything went well. */ | 140 | returns crypt_connection_id of the initialized connection if everything went well. */ |
100 | int crypto_connect(uint8_t *public_key, IP_Port ip_port); | 141 | int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port); |
101 | 142 | ||
102 | /* kill a crypto connection | 143 | /* kill a crypto connection |
103 | return 0 if killed successfully | 144 | return 0 if killed successfully |
104 | return 1 if there was a problem. */ | 145 | return 1 if there was a problem. */ |
105 | int crypto_kill(int crypt_connection_id); | 146 | int crypto_kill(Net_Crypto *c, int crypt_connection_id); |
106 | 147 | ||
107 | /* handle an incoming connection | 148 | /* handle an incoming connection |
108 | return -1 if no crypto inbound connection | 149 | return -1 if no crypto inbound connection |
@@ -111,37 +152,43 @@ int crypto_kill(int crypt_connection_id); | |||
111 | and the session public key for the connection in session_key | 152 | and the session public key for the connection in session_key |
112 | to accept it see: accept_crypto_inbound(...) | 153 | to accept it see: accept_crypto_inbound(...) |
113 | to refuse it just call kill_connection(...) on the connection id */ | 154 | to refuse it just call kill_connection(...) on the connection id */ |
114 | int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); | 155 | int crypto_inbound(Net_Crypto *c, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); |
115 | 156 | ||
116 | /* accept an incoming connection using the parameters provided by crypto_inbound | 157 | /* accept an incoming connection using the parameters provided by crypto_inbound |
117 | return -1 if not successful | 158 | return -1 if not successful |
118 | returns the crypt_connection_id if successful */ | 159 | returns the crypt_connection_id if successful */ |
119 | int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key); | 160 | int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, uint8_t *secret_nonce, |
161 | uint8_t *session_key); | ||
120 | 162 | ||
121 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet | 163 | /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet |
122 | (we have received a handshake but no empty data packet), 3 if the connection is established. | 164 | (we have received a handshake but no empty data packet), 3 if the connection is established. |
123 | 4 if the connection is timed out and waiting to be killed */ | 165 | 4 if the connection is timed out and waiting to be killed */ |
124 | int is_cryptoconnected(int crypt_connection_id); | 166 | int is_cryptoconnected(Net_Crypto *c, int crypt_connection_id); |
125 | 167 | ||
126 | 168 | ||
127 | /* Generate our public and private keys | 169 | /* Generate our public and private keys |
128 | Only call this function the first time the program starts. */ | 170 | Only call this function the first time the program starts. */ |
129 | void new_keys(void); | 171 | void new_keys(Net_Crypto *c); |
130 | 172 | ||
131 | /* save the public and private keys to the keys array | 173 | /* save the public and private keys to the keys array |
132 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 174 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
133 | void save_keys(uint8_t *keys); | 175 | void save_keys(Net_Crypto *c, uint8_t *keys); |
134 | 176 | ||
135 | /* load the public and private keys from the keys array | 177 | /* load the public and private keys from the keys array |
136 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ | 178 | Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ |
137 | void load_keys(uint8_t *keys); | 179 | void load_keys(Net_Crypto *c, uint8_t *keys); |
138 | 180 | ||
139 | /* run this to (re)initialize net_crypto | 181 | /* create new instance of Net_Crypto |
140 | sets all the global connection variables to their default values. */ | 182 | sets all the global connection variables to their default values. */ |
141 | void initNetCrypto(void); | 183 | Net_Crypto *new_net_crypto(Networking_Core *net); |
142 | 184 | ||
143 | /* main loop */ | 185 | /* main loop */ |
144 | void doNetCrypto(void); | 186 | void do_net_crypto(Net_Crypto *c); |
187 | |||
188 | void kill_net_crypto(Net_Crypto *c); | ||
189 | |||
190 | /* Init the cryptopacket handling */ | ||
191 | void init_cryptopackets(void *dht); | ||
145 | 192 | ||
146 | #ifdef __cplusplus | 193 | #ifdef __cplusplus |
147 | } | 194 | } |
diff --git a/core/network.c b/core/network.c index 1977ce38..849c7e2a 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -56,12 +56,9 @@ uint32_t random_int(void) | |||
56 | #endif | 56 | #endif |
57 | } | 57 | } |
58 | 58 | ||
59 | /* our UDP socket, a global variable. */ | ||
60 | static int sock; | ||
61 | |||
62 | /* Basic network functions: | 59 | /* Basic network functions: |
63 | Function to send packet(data) of length length to ip_port */ | 60 | Function to send packet(data) of length length to ip_port */ |
64 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) | 61 | int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length) |
65 | { | 62 | { |
66 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; | 63 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; |
67 | return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | 64 | return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); |
@@ -71,7 +68,7 @@ int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) | |||
71 | the packet data into data | 68 | the packet data into data |
72 | the packet length into length. | 69 | the packet length into length. |
73 | dump all empty packets. */ | 70 | dump all empty packets. */ |
74 | static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) | 71 | static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) |
75 | { | 72 | { |
76 | ADDR addr; | 73 | ADDR addr; |
77 | #ifdef WIN32 | 74 | #ifdef WIN32 |
@@ -89,36 +86,33 @@ static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) | |||
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | 88 | ||
92 | static packet_handler_callback packethandlers[256] = {0}; | 89 | void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object) |
93 | |||
94 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb) | ||
95 | { | 90 | { |
96 | packethandlers[byte] = cb; | 91 | net->packethandlers[byte].function = cb; |
92 | net->packethandlers[byte].object = object; | ||
97 | } | 93 | } |
98 | 94 | ||
99 | void networking_poll() | 95 | void networking_poll(Networking_Core *net) |
100 | { | 96 | { |
101 | IP_Port ip_port; | 97 | IP_Port ip_port; |
102 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 98 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
103 | uint32_t length; | 99 | uint32_t length; |
104 | 100 | ||
105 | while (receivepacket(&ip_port, data, &length) != -1) { | 101 | while (receivepacket(net->sock, &ip_port, data, &length) != -1) { |
106 | if (length < 1) continue; | 102 | if (length < 1) continue; |
107 | 103 | ||
108 | if (!packethandlers[data[0]]) continue; | 104 | if (!(net->packethandlers[data[0]].function)) continue; |
109 | 105 | ||
110 | packethandlers[data[0]](ip_port, data, length); | 106 | net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); |
111 | } | 107 | } |
112 | } | 108 | } |
113 | 109 | ||
114 | /* initialize networking | 110 | uint8_t at_startup_ran; |
115 | bind to ip and port | 111 | static void at_startup(void) |
116 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
117 | port is in host byte order (this means don't worry about it) | ||
118 | returns 0 if no problems | ||
119 | returns -1 if there are problems */ | ||
120 | int init_networking(IP ip, uint16_t port) | ||
121 | { | 112 | { |
113 | if (at_startup_ran != 0) | ||
114 | return; | ||
115 | |||
122 | #ifdef WIN32 | 116 | #ifdef WIN32 |
123 | WSADATA wsaData; | 117 | WSADATA wsaData; |
124 | 118 | ||
@@ -129,20 +123,49 @@ int init_networking(IP ip, uint16_t port) | |||
129 | srandom((uint32_t)current_time()); | 123 | srandom((uint32_t)current_time()); |
130 | #endif | 124 | #endif |
131 | srand((uint32_t)current_time()); | 125 | srand((uint32_t)current_time()); |
126 | at_startup_ran = 1; | ||
127 | } | ||
128 | |||
129 | /* TODO: put this somewhere | ||
130 | static void at_shutdown(void) | ||
131 | { | ||
132 | #ifdef WIN32 | ||
133 | WSACleanup(); | ||
134 | #endif | ||
135 | } | ||
136 | */ | ||
132 | 137 | ||
138 | /* initialize networking | ||
139 | bind to ip and port | ||
140 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
141 | port is in host byte order (this means don't worry about it) | ||
142 | returns Networking_Core object if no problems | ||
143 | returns NULL if there are problems */ | ||
144 | Networking_Core *new_networking(IP ip, uint16_t port) | ||
145 | { | ||
146 | at_startup(); | ||
133 | /* initialize our socket */ | 147 | /* initialize our socket */ |
134 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | 148 | Networking_Core *temp = calloc(1, sizeof(Networking_Core)); |
149 | |||
150 | if (temp == NULL) | ||
151 | return NULL; | ||
152 | |||
153 | temp->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
135 | 154 | ||
136 | /* Check for socket error */ | 155 | /* Check for socket error */ |
137 | #ifdef WIN32 | 156 | #ifdef WIN32 |
138 | 157 | ||
139 | if (sock == INVALID_SOCKET) /* MSDN recommends this */ | 158 | if (temp->sock == INVALID_SOCKET) { /* MSDN recommends this */ |
140 | return -1; | 159 | free(temp); |
160 | return NULL; | ||
161 | } | ||
141 | 162 | ||
142 | #else | 163 | #else |
143 | 164 | ||
144 | if (sock < 0) | 165 | if (temp->sock < 0) { |
145 | return -1; | 166 | free(temp); |
167 | return NULL; | ||
168 | } | ||
146 | 169 | ||
147 | #endif | 170 | #endif |
148 | 171 | ||
@@ -161,34 +184,33 @@ int init_networking(IP ip, uint16_t port) | |||
161 | 184 | ||
162 | /* Enable broadcast on socket */ | 185 | /* Enable broadcast on socket */ |
163 | int broadcast = 1; | 186 | int broadcast = 1; |
164 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); | 187 | setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); |
165 | 188 | ||
166 | /* Set socket nonblocking */ | 189 | /* Set socket nonblocking */ |
167 | #ifdef WIN32 | 190 | #ifdef WIN32 |
168 | /* I think this works for windows */ | 191 | /* I think this works for windows */ |
169 | u_long mode = 1; | 192 | u_long mode = 1; |
170 | /* ioctl(sock, FIONBIO, &mode); */ | 193 | /* ioctl(sock, FIONBIO, &mode); */ |
171 | ioctlsocket(sock, FIONBIO, &mode); | 194 | ioctlsocket(temp->sock, FIONBIO, &mode); |
172 | #else | 195 | #else |
173 | fcntl(sock, F_SETFL, O_NONBLOCK, 1); | 196 | fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1); |
174 | #endif | 197 | #endif |
175 | 198 | ||
176 | /* Bind our socket to port PORT and address 0.0.0.0 */ | 199 | /* Bind our socket to port PORT and address 0.0.0.0 */ |
177 | ADDR addr = {AF_INET, htons(port), ip}; | 200 | ADDR addr = {AF_INET, htons(port), ip}; |
178 | bind(sock, (struct sockaddr *)&addr, sizeof(addr)); | 201 | bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); |
179 | 202 | return temp; | |
180 | return 0; | ||
181 | } | 203 | } |
182 | 204 | ||
183 | /* function to cleanup networking stuff */ | 205 | /* function to cleanup networking stuff */ |
184 | void shutdown_networking(void) | 206 | void kill_networking(Networking_Core *net) |
185 | { | 207 | { |
186 | #ifdef WIN32 | 208 | #ifdef WIN32 |
187 | closesocket(sock); | 209 | closesocket(net->sock); |
188 | WSACleanup(); | ||
189 | #else | 210 | #else |
190 | close(sock); | 211 | close(net->sock); |
191 | #endif | 212 | #endif |
213 | free(net); | ||
192 | return; | 214 | return; |
193 | } | 215 | } |
194 | 216 | ||
diff --git a/core/network.h b/core/network.h index 127a55d1..87f45978 100644 --- a/core/network.h +++ b/core/network.h | |||
@@ -99,7 +99,18 @@ typedef struct { | |||
99 | /* Function to receive data, ip and port of sender is put into ip_port | 99 | /* Function to receive data, ip and port of sender is put into ip_port |
100 | the packet data into data | 100 | the packet data into data |
101 | the packet length into length. */ | 101 | the packet length into length. */ |
102 | typedef int (*packet_handler_callback)(IP_Port ip_port, uint8_t *data, uint32_t len); | 102 | typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, uint8_t *data, uint32_t len); |
103 | |||
104 | typedef struct { | ||
105 | packet_handler_callback function; | ||
106 | void *object; | ||
107 | } Packet_Handles; | ||
108 | |||
109 | typedef struct { | ||
110 | Packet_Handles packethandlers[256]; | ||
111 | /* our UDP socket */ | ||
112 | int sock; | ||
113 | } Networking_Core; | ||
103 | 114 | ||
104 | /* returns current time in milleseconds since the epoch. */ | 115 | /* returns current time in milleseconds since the epoch. */ |
105 | uint64_t current_time(void); | 116 | uint64_t current_time(void); |
@@ -111,13 +122,13 @@ uint32_t random_int(void); | |||
111 | /* Basic network functions: */ | 122 | /* Basic network functions: */ |
112 | 123 | ||
113 | /* Function to send packet(data) of length length to ip_port */ | 124 | /* Function to send packet(data) of length length to ip_port */ |
114 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length); | 125 | int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length); |
115 | 126 | ||
116 | /* Function to call when packet beginning with byte is received */ | 127 | /* Function to call when packet beginning with byte is received */ |
117 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb); | 128 | void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object); |
118 | 129 | ||
119 | /* call this several times a second */ | 130 | /* call this several times a second */ |
120 | void networking_poll(); | 131 | void networking_poll(Networking_Core *net); |
121 | 132 | ||
122 | /* initialize networking | 133 | /* initialize networking |
123 | bind to ip and port | 134 | bind to ip and port |
@@ -125,10 +136,10 @@ void networking_poll(); | |||
125 | port is in host byte order (this means don't worry about it) | 136 | port is in host byte order (this means don't worry about it) |
126 | returns 0 if no problems | 137 | returns 0 if no problems |
127 | returns -1 if there were problems */ | 138 | returns -1 if there were problems */ |
128 | int init_networking(IP ip, uint16_t port); | 139 | Networking_Core *new_networking(IP ip, uint16_t port); |
129 | 140 | ||
130 | /* function to cleanup networking stuff(doesn't do much right now) */ | 141 | /* function to cleanup networking stuff(doesn't do much right now) */ |
131 | void shutdown_networking(void); | 142 | void kill_networking(Networking_Core *net); |
132 | 143 | ||
133 | /* | 144 | /* |
134 | resolve_addr(): | 145 | resolve_addr(): |
diff --git a/core/ping.c b/core/ping.c index 47d6e163..4bb9c38a 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -23,17 +23,20 @@ typedef struct { | |||
23 | uint64_t timestamp; | 23 | uint64_t timestamp; |
24 | } pinged_t; | 24 | } pinged_t; |
25 | 25 | ||
26 | static pinged_t pings[PING_NUM_MAX]; | 26 | typedef struct { |
27 | static size_t num_pings; | 27 | pinged_t pings[PING_NUM_MAX]; |
28 | static size_t pos_pings; | 28 | size_t num_pings; |
29 | static clientid_t *self_id = (clientid_t *) &self_public_key; | 29 | size_t pos_pings; |
30 | } PING; | ||
30 | 31 | ||
31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 32 | void *new_ping(void) |
33 | { | ||
34 | return calloc(1, sizeof(PING)); | ||
35 | } | ||
32 | 36 | ||
33 | void init_ping() | 37 | void kill_ping(void *ping) |
34 | { | 38 | { |
35 | num_pings = 0; | 39 | free(ping); |
36 | pos_pings = 0; | ||
37 | } | 40 | } |
38 | 41 | ||
39 | static bool is_timeout(uint64_t time) | 42 | static bool is_timeout(uint64_t time) |
@@ -41,17 +44,18 @@ static bool is_timeout(uint64_t time) | |||
41 | return (time + PING_TIMEOUT) < now(); | 44 | return (time + PING_TIMEOUT) < now(); |
42 | } | 45 | } |
43 | 46 | ||
44 | static void remove_timeouts() // O(n) | 47 | static void remove_timeouts(void *ping) // O(n) |
45 | { | 48 | { |
49 | PING *png = ping; | ||
46 | size_t i, id; | 50 | size_t i, id; |
47 | size_t new_pos = pos_pings; | 51 | size_t new_pos = png->pos_pings; |
48 | size_t new_num = num_pings; | 52 | size_t new_num = png->num_pings; |
49 | 53 | ||
50 | // Loop through buffer, oldest first | 54 | // Loop through buffer, oldest first |
51 | for (i = 0; i < num_pings; i++) { | 55 | for (i = 0; i < png->num_pings; i++) { |
52 | id = (pos_pings + i) % PING_NUM_MAX; | 56 | id = (png->pos_pings + i) % PING_NUM_MAX; |
53 | 57 | ||
54 | if (is_timeout(pings[id].timestamp)) { | 58 | if (is_timeout(png->pings[id].timestamp)) { |
55 | new_pos++; | 59 | new_pos++; |
56 | new_num--; | 60 | new_num--; |
57 | } | 61 | } |
@@ -61,47 +65,50 @@ static void remove_timeouts() // O(n) | |||
61 | } | 65 | } |
62 | } | 66 | } |
63 | 67 | ||
64 | num_pings = new_num; | 68 | png->num_pings = new_num; |
65 | pos_pings = new_pos % PING_NUM_MAX; | 69 | png->pos_pings = new_pos % PING_NUM_MAX; |
66 | } | 70 | } |
67 | 71 | ||
68 | uint64_t add_ping(IP_Port ipp) // O(n) | 72 | uint64_t add_ping(void *ping, IP_Port ipp) // O(n) |
69 | { | 73 | { |
74 | PING *png = ping; | ||
70 | size_t p; | 75 | size_t p; |
71 | 76 | ||
72 | remove_timeouts(); | 77 | remove_timeouts(ping); |
73 | 78 | ||
74 | // Remove oldest ping if full buffer | 79 | // Remove oldest ping if full buffer |
75 | if (num_pings == PING_NUM_MAX) { | 80 | if (png->num_pings == PING_NUM_MAX) { |
76 | num_pings--; | 81 | png->num_pings--; |
77 | pos_pings = (pos_pings + 1) % PING_NUM_MAX; | 82 | png->pos_pings = (png->pos_pings + 1) % PING_NUM_MAX; |
78 | } | 83 | } |
79 | 84 | ||
80 | // Insert new ping at end of list | 85 | // Insert new ping at end of list |
81 | p = (pos_pings + num_pings) % PING_NUM_MAX; | 86 | p = (png->pos_pings + png->num_pings) % PING_NUM_MAX; |
82 | 87 | ||
83 | pings[p].ipp = ipp; | 88 | png->pings[p].ipp = ipp; |
84 | pings[p].timestamp = now(); | 89 | png->pings[p].timestamp = now(); |
85 | pings[p].id = random_64b(); | 90 | png->pings[p].id = random_64b(); |
86 | 91 | ||
87 | num_pings++; | 92 | png->num_pings++; |
88 | return pings[p].id; | 93 | return png->pings[p].id; |
89 | } | 94 | } |
90 | 95 | ||
91 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. | 96 | bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. |
92 | { | 97 | { |
98 | PING *png = ping; | ||
99 | |||
93 | if (ipp.ip.i == 0 && ping_id == 0) | 100 | if (ipp.ip.i == 0 && ping_id == 0) |
94 | return false; | 101 | return false; |
95 | 102 | ||
96 | size_t i, id; | 103 | size_t i, id; |
97 | 104 | ||
98 | remove_timeouts(); | 105 | remove_timeouts(ping); |
99 | 106 | ||
100 | for (i = 0; i < num_pings; i++) { | 107 | for (i = 0; i < png->num_pings; i++) { |
101 | id = (pos_pings + i) % PING_NUM_MAX; | 108 | id = (png->pos_pings + i) % PING_NUM_MAX; |
102 | 109 | ||
103 | // ping_id = 0 means match any id | 110 | // ping_id = 0 means match any id |
104 | if ((ipp_eq(pings[id].ipp, ipp) || ipp.ip.i == 0) && (pings[id].id == ping_id || ping_id == 0)) { | 111 | if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.i == 0) && (png->pings[id].id == ping_id || ping_id == 0)) { |
105 | return true; | 112 | return true; |
106 | } | 113 | } |
107 | } | 114 | } |
@@ -109,25 +116,25 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with | |||
109 | return false; | 116 | return false; |
110 | } | 117 | } |
111 | 118 | ||
112 | int send_ping_request(IP_Port ipp, clientid_t *client_id) | 119 | int send_ping_request(void *ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id) |
113 | { | 120 | { |
114 | pingreq_t pk; | 121 | pingreq_t pk; |
115 | int rc; | 122 | int rc; |
116 | uint64_t ping_id; | 123 | uint64_t ping_id; |
117 | 124 | ||
118 | if (is_pinging(ipp, 0) || id_eq(client_id, self_id)) | 125 | if (is_pinging(ping, ipp, 0) || id_eq(client_id, (clientid_t *)c->self_public_key)) |
119 | return 1; | 126 | return 1; |
120 | 127 | ||
121 | // Generate random ping_id | 128 | // Generate random ping_id |
122 | ping_id = add_ping(ipp); | 129 | ping_id = add_ping(ping, ipp); |
123 | 130 | ||
124 | pk.magic = PACKET_PING_REQ; | 131 | pk.magic = PACKET_PING_REQ; |
125 | id_cpy(&pk.client_id, self_id); // Our pubkey | 132 | id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey |
126 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce | 133 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce |
127 | 134 | ||
128 | // Encrypt ping_id using recipient privkey | 135 | // Encrypt ping_id using recipient privkey |
129 | rc = encrypt_data((uint8_t *) client_id, | 136 | rc = encrypt_data((uint8_t *) client_id, |
130 | self_secret_key, | 137 | c->self_secret_key, |
131 | (uint8_t *) &pk.nonce, | 138 | (uint8_t *) &pk.nonce, |
132 | (uint8_t *) &ping_id, sizeof(ping_id), | 139 | (uint8_t *) &ping_id, sizeof(ping_id), |
133 | (uint8_t *) &pk.ping_id); | 140 | (uint8_t *) &pk.ping_id); |
@@ -135,24 +142,24 @@ int send_ping_request(IP_Port ipp, clientid_t *client_id) | |||
135 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 142 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
136 | return 1; | 143 | return 1; |
137 | 144 | ||
138 | return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk)); | 145 | return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
139 | } | 146 | } |
140 | 147 | ||
141 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | 148 | int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id) |
142 | { | 149 | { |
143 | pingres_t pk; | 150 | pingres_t pk; |
144 | int rc; | 151 | int rc; |
145 | 152 | ||
146 | if (id_eq(client_id, self_id)) | 153 | if (id_eq(client_id, (clientid_t *)c->self_public_key)) |
147 | return 1; | 154 | return 1; |
148 | 155 | ||
149 | pk.magic = PACKET_PING_RES; | 156 | pk.magic = PACKET_PING_RES; |
150 | id_cpy(&pk.client_id, self_id); // Our pubkey | 157 | id_cpy(&pk.client_id, (clientid_t *)c->self_public_key); // Our pubkey |
151 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce | 158 | random_nonce((uint8_t *) &pk.nonce); // Generate random nonce |
152 | 159 | ||
153 | // Encrypt ping_id using recipient privkey | 160 | // Encrypt ping_id using recipient privkey |
154 | rc = encrypt_data((uint8_t *) client_id, | 161 | rc = encrypt_data((uint8_t *) client_id, |
155 | self_secret_key, | 162 | c->self_secret_key, |
156 | (uint8_t *) &pk.nonce, | 163 | (uint8_t *) &pk.nonce, |
157 | (uint8_t *) &ping_id, sizeof(ping_id), | 164 | (uint8_t *) &ping_id, sizeof(ping_id), |
158 | (uint8_t *) &pk.ping_id); | 165 | (uint8_t *) &pk.ping_id); |
@@ -160,21 +167,22 @@ int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id) | |||
160 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) | 167 | if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) |
161 | return 1; | 168 | return 1; |
162 | 169 | ||
163 | return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk)); | 170 | return sendpacket(c->lossless_udp->net->sock, ipp, (uint8_t *) &pk, sizeof(pk)); |
164 | } | 171 | } |
165 | 172 | ||
166 | int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length) | 173 | int handle_ping_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
167 | { | 174 | { |
175 | DHT *dht = object; | ||
168 | pingreq_t *p = (pingreq_t *) packet; | 176 | pingreq_t *p = (pingreq_t *) packet; |
169 | int rc; | 177 | int rc; |
170 | uint64_t ping_id; | 178 | uint64_t ping_id; |
171 | 179 | ||
172 | if (length != sizeof(pingreq_t) || id_eq(&p->client_id, self_id)) | 180 | if (length != sizeof(pingreq_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key)) |
173 | return 1; | 181 | return 1; |
174 | 182 | ||
175 | // Decrypt ping_id | 183 | // Decrypt ping_id |
176 | rc = decrypt_data((uint8_t *) &p->client_id, | 184 | rc = decrypt_data((uint8_t *) &p->client_id, |
177 | self_secret_key, | 185 | dht->c->self_secret_key, |
178 | (uint8_t *) &p->nonce, | 186 | (uint8_t *) &p->nonce, |
179 | (uint8_t *) &p->ping_id, | 187 | (uint8_t *) &p->ping_id, |
180 | sizeof(ping_id) + ENCRYPTION_PADDING, | 188 | sizeof(ping_id) + ENCRYPTION_PADDING, |
@@ -184,24 +192,25 @@ int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length) | |||
184 | return 1; | 192 | return 1; |
185 | 193 | ||
186 | // Send response | 194 | // Send response |
187 | send_ping_response(source, &p->client_id, ping_id); | 195 | send_ping_response(dht->c, source, &p->client_id, ping_id); |
188 | add_toping((uint8_t *) &p->client_id, source); | 196 | add_toping(dht, (uint8_t *) &p->client_id, source); |
189 | 197 | ||
190 | return 0; | 198 | return 0; |
191 | } | 199 | } |
192 | 200 | ||
193 | int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length) | 201 | int handle_ping_response(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
194 | { | 202 | { |
203 | DHT *dht = object; | ||
195 | pingres_t *p = (pingres_t *) packet; | 204 | pingres_t *p = (pingres_t *) packet; |
196 | int rc; | 205 | int rc; |
197 | uint64_t ping_id; | 206 | uint64_t ping_id; |
198 | 207 | ||
199 | if (length != sizeof(pingres_t) || id_eq(&p->client_id, self_id)) | 208 | if (length != sizeof(pingres_t) || id_eq(&p->client_id, (clientid_t *)dht->c->self_public_key)) |
200 | return 1; | 209 | return 1; |
201 | 210 | ||
202 | // Decrypt ping_id | 211 | // Decrypt ping_id |
203 | rc = decrypt_data((uint8_t *) &p->client_id, | 212 | rc = decrypt_data((uint8_t *) &p->client_id, |
204 | self_secret_key, | 213 | dht->c->self_secret_key, |
205 | (uint8_t *) &p->nonce, | 214 | (uint8_t *) &p->nonce, |
206 | (uint8_t *) &p->ping_id, | 215 | (uint8_t *) &p->ping_id, |
207 | sizeof(ping_id) + ENCRYPTION_PADDING, | 216 | sizeof(ping_id) + ENCRYPTION_PADDING, |
@@ -211,10 +220,10 @@ int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length) | |||
211 | return 1; | 220 | return 1; |
212 | 221 | ||
213 | // Make sure ping_id is correct | 222 | // Make sure ping_id is correct |
214 | if (!is_pinging(source, ping_id)) | 223 | if (!is_pinging(dht->ping, source, ping_id)) |
215 | return 1; | 224 | return 1; |
216 | 225 | ||
217 | // Associate source ip with client_id | 226 | // Associate source ip with client_id |
218 | addto_lists(source, (uint8_t *) &p->client_id); | 227 | addto_lists(dht, source, (uint8_t *) &p->client_id); |
219 | return 0; | 228 | return 0; |
220 | } | 229 | } |
diff --git a/core/ping.h b/core/ping.h index 0c44874b..c04ec80e 100644 --- a/core/ping.h +++ b/core/ping.h | |||
@@ -7,10 +7,11 @@ | |||
7 | 7 | ||
8 | #include <stdbool.h> | 8 | #include <stdbool.h> |
9 | 9 | ||
10 | void init_ping(); | 10 | void *new_ping(void); |
11 | uint64_t add_ping(IP_Port ipp); | 11 | void kill_ping(void *ping); |
12 | bool is_pinging(IP_Port ipp, uint64_t ping_id); | 12 | uint64_t add_ping(void *ping, IP_Port ipp); |
13 | int send_ping_request(IP_Port ipp, clientid_t *client_id); | 13 | bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id); |
14 | int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id); | 14 | int send_ping_request(void *ping, Net_Crypto *c, IP_Port ipp, clientid_t *client_id); |
15 | int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length); | 15 | int send_ping_response(Net_Crypto *c, IP_Port ipp, clientid_t *client_id, uint64_t ping_id); |
16 | int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length); | 16 | int handle_ping_request(void *object, IP_Port source, uint8_t *packet, uint32_t length); |
17 | int handle_ping_response(void *object, IP_Port source, uint8_t *packet, uint32_t length); | ||
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 299e030c..5d97b37a 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c | |||
@@ -44,7 +44,7 @@ | |||
44 | 44 | ||
45 | 45 | ||
46 | 46 | ||
47 | void manage_keys() | 47 | void manage_keys(DHT *dht) |
48 | { | 48 | { |
49 | const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 49 | const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
50 | uint8_t keys[KEYS_SIZE]; | 50 | uint8_t keys[KEYS_SIZE]; |
@@ -60,12 +60,12 @@ void manage_keys() | |||
60 | exit(1); | 60 | exit(1); |
61 | } | 61 | } |
62 | 62 | ||
63 | load_keys(keys); | 63 | load_keys(dht->c, keys); |
64 | printf("Keys loaded successfully\n"); | 64 | printf("Keys loaded successfully\n"); |
65 | } else { | 65 | } else { |
66 | //otherwise save new keys | 66 | //otherwise save new keys |
67 | new_keys(); | 67 | new_keys(dht->c); |
68 | save_keys(keys); | 68 | save_keys(dht->c, keys); |
69 | keys_file = fopen("key", "w"); | 69 | keys_file = fopen("key", "w"); |
70 | 70 | ||
71 | if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) { | 71 | if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) { |
@@ -81,7 +81,13 @@ void manage_keys() | |||
81 | 81 | ||
82 | int main(int argc, char *argv[]) | 82 | int main(int argc, char *argv[]) |
83 | { | 83 | { |
84 | manage_keys(); | 84 | //initialize networking |
85 | //bind to ip 0.0.0.0:PORT | ||
86 | IP ip; | ||
87 | ip.i = 0; | ||
88 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); | ||
89 | init_cryptopackets(dht); | ||
90 | manage_keys(dht); | ||
85 | printf("Public key: "); | 91 | printf("Public key: "); |
86 | uint32_t i; | 92 | uint32_t i; |
87 | 93 | ||
@@ -89,22 +95,17 @@ int main(int argc, char *argv[]) | |||
89 | file = fopen("PUBLIC_ID.txt", "w"); | 95 | file = fopen("PUBLIC_ID.txt", "w"); |
90 | 96 | ||
91 | for (i = 0; i < 32; i++) { | 97 | for (i = 0; i < 32; i++) { |
92 | if (self_public_key[i] < 16) | 98 | if (dht->c->self_public_key[i] < 16) |
93 | printf("0"); | 99 | printf("0"); |
94 | 100 | ||
95 | printf("%hhX", self_public_key[i]); | 101 | printf("%hhX", dht->c->self_public_key[i]); |
96 | fprintf(file, "%hhX", self_public_key[i]); | 102 | fprintf(file, "%hhX", dht->c->self_public_key[i]); |
97 | } | 103 | } |
98 | 104 | ||
99 | fclose(file); | 105 | fclose(file); |
100 | 106 | ||
101 | printf("\n"); | 107 | printf("\n"); |
102 | printf("Port: %u\n", PORT); | 108 | printf("Port: %u\n", PORT); |
103 | //initialize networking | ||
104 | //bind to ip 0.0.0.0:PORT | ||
105 | IP ip; | ||
106 | ip.i = 0; | ||
107 | init_networking(ip, PORT); | ||
108 | 109 | ||
109 | perror("Initialization"); | 110 | perror("Initialization"); |
110 | 111 | ||
@@ -114,28 +115,24 @@ int main(int argc, char *argv[]) | |||
114 | bootstrap_info.ip.i = inet_addr(argv[1]); | 115 | bootstrap_info.ip.i = inet_addr(argv[1]); |
115 | bootstrap_info.port = htons(atoi(argv[2])); | 116 | bootstrap_info.port = htons(atoi(argv[2])); |
116 | uint8_t *bootstrap_key = hex_string_to_bin(argv[3]); | 117 | uint8_t *bootstrap_key = hex_string_to_bin(argv[3]); |
117 | DHT_bootstrap(bootstrap_info, bootstrap_key); | 118 | DHT_bootstrap(dht, bootstrap_info, bootstrap_key); |
118 | free(bootstrap_key); | 119 | free(bootstrap_key); |
119 | } | 120 | } |
120 | 121 | ||
121 | DHT_init(); | ||
122 | friendreq_init(); | ||
123 | |||
124 | int is_waiting_for_dht_connection = 1; | 122 | int is_waiting_for_dht_connection = 1; |
125 | 123 | ||
126 | while (1) { | 124 | while (1) { |
127 | if (is_waiting_for_dht_connection && DHT_isconnected()) { | 125 | if (is_waiting_for_dht_connection && DHT_isconnected(dht)) { |
128 | printf("Connected to other bootstrap server successfully.\n"); | 126 | printf("Connected to other bootstrap server successfully.\n"); |
129 | is_waiting_for_dht_connection = 0; | 127 | is_waiting_for_dht_connection = 0; |
130 | } | 128 | } |
131 | 129 | ||
132 | doDHT(); | 130 | do_DHT(dht); |
133 | 131 | ||
134 | networking_poll(); | 132 | networking_poll(dht->c->lossless_udp->net); |
135 | 133 | ||
136 | c_sleep(1); | 134 | c_sleep(1); |
137 | } | 135 | } |
138 | 136 | ||
139 | shutdown_networking(); | ||
140 | return 0; | 137 | return 0; |
141 | } | 138 | } |
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c index 896d6a69..81ac538b 100644 --- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c +++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c | |||
@@ -77,7 +77,7 @@ and connect to them. | |||
77 | returns 1 if the connection to the DHT is up | 77 | returns 1 if the connection to the DHT is up |
78 | returns -1 if all attempts failed | 78 | returns -1 if all attempts failed |
79 | */ | 79 | */ |
80 | int connect_to_servers(struct server_info_s *info) | 80 | int connect_to_servers(DHT *dht, struct server_info_s *info) |
81 | { | 81 | { |
82 | int i; | 82 | int i; |
83 | int c; | 83 | int c; |
@@ -86,7 +86,7 @@ int connect_to_servers(struct server_info_s *info) | |||
86 | if (info[i].valid) { | 86 | if (info[i].valid) { |
87 | /* Actual bootstrapping code goes here */ | 87 | /* Actual bootstrapping code goes here */ |
88 | //puts("Calling DHT_bootstrap"); | 88 | //puts("Calling DHT_bootstrap"); |
89 | DHT_bootstrap(info[i].conn, info[i].bs_pk); | 89 | DHT_bootstrap(dht, info[i].conn, info[i].bs_pk); |
90 | } | 90 | } |
91 | } | 91 | } |
92 | 92 | ||
@@ -94,28 +94,28 @@ int connect_to_servers(struct server_info_s *info) | |||
94 | for (c = 0; c != 100; ++c) { | 94 | for (c = 0; c != 100; ++c) { |
95 | usleep(10000); | 95 | usleep(10000); |
96 | 96 | ||
97 | if (DHT_isconnected()) { | 97 | if (DHT_isconnected(dht)) { |
98 | //puts("Connected"); | 98 | //puts("Connected"); |
99 | return 1; | 99 | return 1; |
100 | break; | 100 | break; |
101 | } | 101 | } |
102 | 102 | ||
103 | if (DHT_isconnected() == 0 && c == 99) { | 103 | if (DHT_isconnected(dht) == 0 && c == 99) { |
104 | //puts("Not connected"); | 104 | //puts("Not connected"); |
105 | return -1; | 105 | return -1; |
106 | break; | 106 | break; |
107 | } | 107 | } |
108 | 108 | ||
109 | doDHT(); | 109 | do_DHT(dht); |
110 | 110 | ||
111 | networking_poll(); | 111 | networking_poll(dht->c->lossless_udp->net); |
112 | } | 112 | } |
113 | 113 | ||
114 | /* This probably never happens */ | 114 | /* This probably never happens */ |
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | void manage_keys(char *keys_file) | 118 | void manage_keys(DHT *dht, char *keys_file) |
119 | { | 119 | { |
120 | const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 120 | const uint32_t KEYS_SIZE = crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
121 | uint8_t keys[KEYS_SIZE]; | 121 | uint8_t keys[KEYS_SIZE]; |
@@ -134,13 +134,13 @@ void manage_keys(char *keys_file) | |||
134 | printf("Keys loaded successfully\n"); | 134 | printf("Keys loaded successfully\n"); |
135 | } | 135 | } |
136 | 136 | ||
137 | load_keys(keys); | 137 | load_keys(dht->c, keys); |
138 | 138 | ||
139 | } else { | 139 | } else { |
140 | /* otherwise save new keys */ | 140 | /* otherwise save new keys */ |
141 | /* Silly work-around to ignore any errors coming from new_keys() */ | 141 | /* Silly work-around to ignore any errors coming from new_keys() */ |
142 | new_keys(); | 142 | new_keys(dht->c); |
143 | save_keys(keys); | 143 | save_keys(dht->c, keys); |
144 | keysf = fopen(keys_file, "w"); | 144 | keysf = fopen(keys_file, "w"); |
145 | 145 | ||
146 | if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keysf) != KEYS_SIZE) { | 146 | if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keysf) != KEYS_SIZE) { |
@@ -294,9 +294,14 @@ int main(int argc, char *argv[]) | |||
294 | exit(EXIT_FAILURE); | 294 | exit(EXIT_FAILURE); |
295 | } | 295 | } |
296 | 296 | ||
297 | /* Read the config file */ | ||
298 | server_conf = configure_server(argv[1]); | 297 | server_conf = configure_server(argv[1]); |
299 | 298 | ||
299 | /* initialize networking | ||
300 | bind to ip 0.0.0.0:PORT */ | ||
301 | IP ip; | ||
302 | ip.i = 0; | ||
303 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port))); | ||
304 | /* Read the config file */ | ||
300 | printf("PID file: %s\n", server_conf.pid_file); | 305 | printf("PID file: %s\n", server_conf.pid_file); |
301 | printf("Key file: %s\n", server_conf.keys_file); | 306 | printf("Key file: %s\n", server_conf.keys_file); |
302 | 307 | ||
@@ -313,38 +318,32 @@ int main(int argc, char *argv[]) | |||
313 | /* Manage the keys */ | 318 | /* Manage the keys */ |
314 | /* for now, just ignore any errors after this call. */ | 319 | /* for now, just ignore any errors after this call. */ |
315 | int tmperr = errno; | 320 | int tmperr = errno; |
316 | manage_keys(server_conf.keys_file); | 321 | manage_keys(dht, server_conf.keys_file); |
317 | errno = tmperr; | 322 | errno = tmperr; |
318 | 323 | ||
324 | init_cryptopackets(dht); | ||
319 | /* Public key */ | 325 | /* Public key */ |
320 | int i; | 326 | int i; |
321 | printf("\nPublic Key: "); | 327 | printf("\nPublic Key: "); |
322 | 328 | ||
323 | for (i = 0; i < 32; ++i) { | 329 | for (i = 0; i < 32; ++i) { |
324 | uint8_t ln, hn; | 330 | uint8_t ln, hn; |
325 | ln = 0x0F & self_public_key[i]; | 331 | ln = 0x0F & dht->c->self_public_key[i]; |
326 | hn = 0xF0 & self_public_key[i]; | 332 | hn = 0xF0 & dht->c->self_public_key[i]; |
327 | hn = hn >> 4; | 333 | hn = hn >> 4; |
328 | printf("%X%X", hn, ln); | 334 | printf("%X%X", hn, ln); |
329 | } | 335 | } |
330 | 336 | ||
331 | printf("\n"); | 337 | printf("\n"); |
332 | 338 | ||
333 | /* initialize networking | ||
334 | bind to ip 0.0.0.0:PORT */ | ||
335 | IP ip; | ||
336 | ip.i = 0; | ||
337 | init_networking(ip, server_conf.port); | ||
338 | |||
339 | /* Bootstrap the DHT | 339 | /* Bootstrap the DHT |
340 | This one throws odd errors, too. Ignore. I assume they come | 340 | This one throws odd errors, too. Ignore. I assume they come |
341 | from somewhere in the core. */ | 341 | from somewhere in the core. */ |
342 | DHT_init(); | ||
343 | tmperr = errno; | 342 | tmperr = errno; |
344 | connect_to_servers(server_conf.info); | 343 | connect_to_servers(dht, server_conf.info); |
345 | errno = tmperr; | 344 | errno = tmperr; |
346 | 345 | ||
347 | if (!DHT_isconnected()) { | 346 | if (!DHT_isconnected(dht)) { |
348 | puts("Could not establish DHT connection. Check server settings.\n"); | 347 | puts("Could not establish DHT connection. Check server settings.\n"); |
349 | exit(EXIT_FAILURE); | 348 | exit(EXIT_FAILURE); |
350 | } else { | 349 | } else { |
@@ -404,13 +403,10 @@ int main(int argc, char *argv[]) | |||
404 | close(STDIN_FILENO); | 403 | close(STDIN_FILENO); |
405 | close(STDERR_FILENO); | 404 | close(STDERR_FILENO); |
406 | 405 | ||
407 | /* Main loop */ | ||
408 | friendreq_init(); | ||
409 | |||
410 | while (1) { | 406 | while (1) { |
411 | doDHT(); | 407 | do_DHT(dht); |
412 | 408 | ||
413 | networking_poll(); | 409 | networking_poll(dht->c->lossless_udp->net); |
414 | usleep(10000); | 410 | usleep(10000); |
415 | } | 411 | } |
416 | 412 | ||
diff --git a/core/timer.c b/other/unused/timer.c index 29190921..29190921 100644 --- a/core/timer.c +++ b/other/unused/timer.c | |||
diff --git a/core/timer.h b/other/unused/timer.h index 15491326..15491326 100644 --- a/core/timer.h +++ b/other/unused/timer.h | |||
diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index 9e07135c..e3cdc838 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt | |||
@@ -9,7 +9,6 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testclient.cmake) | |||
9 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake) | 9 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Lossless_UDP_testserver.cmake) |
10 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake) | 10 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Messenger_test.cmake) |
11 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/crypto_speed_test.cmake) | 11 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/crypto_speed_test.cmake) |
12 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/timer_test.cmake) | ||
13 | 12 | ||
14 | if(WIN32) | 13 | if(WIN32) |
15 | # include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake) | 14 | # include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/nTox_win32.cmake) |
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index 3883f3a7..8ab9157e 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -28,8 +28,8 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | //#include "../core/network.h" | 30 | //#include "../core/network.h" |
31 | #include "../core/DHT.c" | 31 | #include "../core/DHT.h" |
32 | #include "../core/friend_requests.c" | 32 | #include "../core/friend_requests.h" |
33 | #include "misc_tools.h" | 33 | #include "misc_tools.h" |
34 | 34 | ||
35 | #include <string.h> | 35 | #include <string.h> |
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define PORT 33445 | 49 | #define PORT 33445 |
50 | 50 | ||
51 | void print_clientlist() | 51 | void print_clientlist(DHT *dht) |
52 | { | 52 | { |
53 | uint32_t i, j; | 53 | uint32_t i, j; |
54 | IP_Port p_ip; | 54 | IP_Port p_ip; |
@@ -58,34 +58,34 @@ void print_clientlist() | |||
58 | printf("ClientID: "); | 58 | printf("ClientID: "); |
59 | 59 | ||
60 | for (j = 0; j < 32; j++) { | 60 | for (j = 0; j < 32; j++) { |
61 | printf("%02hhX", close_clientlist[i].client_id[j]); | 61 | printf("%02hhX", dht->close_clientlist[i].client_id[j]); |
62 | } | 62 | } |
63 | 63 | ||
64 | p_ip = close_clientlist[i].ip_port; | 64 | p_ip = dht->close_clientlist[i].ip_port; |
65 | printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); | 65 | printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); |
66 | printf("\nTimestamp: %llu", (long long unsigned int) close_clientlist[i].timestamp); | 66 | printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp); |
67 | printf("\nLast pinged: %llu\n", (long long unsigned int) close_clientlist[i].last_pinged); | 67 | printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged); |
68 | p_ip = close_clientlist[i].ret_ip_port; | 68 | p_ip = dht->close_clientlist[i].ret_ip_port; |
69 | printf("OUR IP: %u.%u.%u.%u Port: %u\n", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); | 69 | printf("OUR IP: %u.%u.%u.%u Port: %u\n", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); |
70 | printf("Timestamp: %llu\n", (long long unsigned int) close_clientlist[i].ret_timestamp); | 70 | printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp); |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | void print_friendlist() | 74 | void print_friendlist(DHT *dht) |
75 | { | 75 | { |
76 | uint32_t i, j, k; | 76 | uint32_t i, j, k; |
77 | IP_Port p_ip; | 77 | IP_Port p_ip; |
78 | printf("_________________FRIENDS__________________________________\n"); | 78 | printf("_________________FRIENDS__________________________________\n"); |
79 | 79 | ||
80 | for (k = 0; k < num_friends; k++) { | 80 | for (k = 0; k < dht->num_friends; k++) { |
81 | printf("FRIEND %u\n", k); | 81 | printf("FRIEND %u\n", k); |
82 | printf("ID: "); | 82 | printf("ID: "); |
83 | 83 | ||
84 | for (j = 0; j < 32; j++) { | 84 | for (j = 0; j < 32; j++) { |
85 | printf("%c", friends_list[k].client_id[j]); | 85 | printf("%c", dht->friends_list[k].client_id[j]); |
86 | } | 86 | } |
87 | 87 | ||
88 | p_ip = DHT_getfriendip(friends_list[k].client_id); | 88 | p_ip = DHT_getfriendip(dht, dht->friends_list[k].client_id); |
89 | printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); | 89 | printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); |
90 | 90 | ||
91 | printf("\nCLIENTS IN LIST:\n\n"); | 91 | printf("\nCLIENTS IN LIST:\n\n"); |
@@ -94,19 +94,19 @@ void print_friendlist() | |||
94 | printf("ClientID: "); | 94 | printf("ClientID: "); |
95 | 95 | ||
96 | for (j = 0; j < 32; j++) { | 96 | for (j = 0; j < 32; j++) { |
97 | if (friends_list[k].client_list[i].client_id[j] < 16) | 97 | if (dht->friends_list[k].client_list[i].client_id[j] < 16) |
98 | printf("0"); | 98 | printf("0"); |
99 | 99 | ||
100 | printf("%hhX", friends_list[k].client_list[i].client_id[j]); | 100 | printf("%hhX", dht->friends_list[k].client_list[i].client_id[j]); |
101 | } | 101 | } |
102 | 102 | ||
103 | p_ip = friends_list[k].client_list[i].ip_port; | 103 | p_ip = dht->friends_list[k].client_list[i].ip_port; |
104 | printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); | 104 | printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); |
105 | printf("\nTimestamp: %llu", (long long unsigned int) friends_list[k].client_list[i].timestamp); | 105 | printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp); |
106 | printf("\nLast pinged: %llu\n", (long long unsigned int) friends_list[k].client_list[i].last_pinged); | 106 | printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged); |
107 | p_ip = friends_list[k].client_list[i].ret_ip_port; | 107 | p_ip = dht->friends_list[k].client_list[i].ret_ip_port; |
108 | printf("ret IP: %u.%u.%u.%u:%u\n", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); | 108 | printf("ret IP: %u.%u.%u.%u:%u\n", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port)); |
109 | printf("Timestamp: %llu\n", (long long unsigned int)friends_list[k].client_list[i].ret_timestamp); | 109 | printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp); |
110 | } | 110 | } |
111 | } | 111 | } |
112 | } | 112 | } |
@@ -130,21 +130,28 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port) | |||
130 | int main(int argc, char *argv[]) | 130 | int main(int argc, char *argv[]) |
131 | { | 131 | { |
132 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); | 132 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); |
133 | /* initialize networking */ | ||
134 | /* bind to ip 0.0.0.0:PORT */ | ||
135 | IP ip; | ||
136 | ip.i = 0; | ||
137 | |||
138 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); | ||
139 | init_cryptopackets(dht); | ||
133 | 140 | ||
134 | if (argc < 4) { | 141 | if (argc < 4) { |
135 | printf("usage %s ip port public_key\n", argv[0]); | 142 | printf("usage %s ip port public_key\n", argv[0]); |
136 | exit(0); | 143 | exit(0); |
137 | } | 144 | } |
138 | 145 | ||
139 | new_keys(); | 146 | new_keys(dht->c); |
140 | printf("OUR ID: "); | 147 | printf("OUR ID: "); |
141 | uint32_t i; | 148 | uint32_t i; |
142 | 149 | ||
143 | for (i = 0; i < 32; i++) { | 150 | for (i = 0; i < 32; i++) { |
144 | if (self_public_key[i] < 16) | 151 | if (dht->c->self_public_key[i] < 16) |
145 | printf("0"); | 152 | printf("0"); |
146 | 153 | ||
147 | printf("%hhX", self_public_key[i]); | 154 | printf("%hhX", dht->c->self_public_key[i]); |
148 | } | 155 | } |
149 | 156 | ||
150 | char temp_id[128]; | 157 | char temp_id[128]; |
@@ -153,13 +160,7 @@ int main(int argc, char *argv[]) | |||
153 | if (scanf("%s", temp_id) != 1) | 160 | if (scanf("%s", temp_id) != 1) |
154 | exit(0); | 161 | exit(0); |
155 | 162 | ||
156 | DHT_addfriend(hex_string_to_bin(temp_id)); | 163 | DHT_addfriend(dht, hex_string_to_bin(temp_id)); |
157 | |||
158 | /* initialize networking */ | ||
159 | /* bind to ip 0.0.0.0:PORT */ | ||
160 | IP ip; | ||
161 | ip.i = 0; | ||
162 | init_networking(ip, PORT); | ||
163 | 164 | ||
164 | 165 | ||
165 | perror("Initialization"); | 166 | perror("Initialization"); |
@@ -170,7 +171,7 @@ int main(int argc, char *argv[]) | |||
170 | * bootstrap_ip_port.ip.c[2] = 0; | 171 | * bootstrap_ip_port.ip.c[2] = 0; |
171 | * bootstrap_ip_port.ip.c[3] = 1; */ | 172 | * bootstrap_ip_port.ip.c[3] = 1; */ |
172 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | 173 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); |
173 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); | 174 | DHT_bootstrap(dht, bootstrap_ip_port, hex_string_to_bin(argv[3])); |
174 | 175 | ||
175 | /* | 176 | /* |
176 | IP_Port ip_port; | 177 | IP_Port ip_port; |
@@ -178,12 +179,9 @@ int main(int argc, char *argv[]) | |||
178 | uint32_t length; | 179 | uint32_t length; |
179 | */ | 180 | */ |
180 | 181 | ||
181 | DHT_init(); | ||
182 | friendreq_init(); | ||
183 | |||
184 | while (1) { | 182 | while (1) { |
185 | 183 | ||
186 | doDHT(); | 184 | do_DHT(dht); |
187 | 185 | ||
188 | /* slvrTODO: | 186 | /* slvrTODO: |
189 | while(receivepacket(&ip_port, data, &length) != -1) { | 187 | while(receivepacket(&ip_port, data, &length) != -1) { |
@@ -195,13 +193,12 @@ int main(int argc, char *argv[]) | |||
195 | } | 193 | } |
196 | } | 194 | } |
197 | */ | 195 | */ |
198 | networking_poll(); | 196 | networking_poll(dht->c->lossless_udp->net); |
199 | 197 | ||
200 | print_clientlist(); | 198 | print_clientlist(dht); |
201 | print_friendlist(); | 199 | print_friendlist(dht); |
202 | c_sleep(300); | 200 | c_sleep(300); |
203 | } | 201 | } |
204 | 202 | ||
205 | shutdown_networking(); | ||
206 | return 0; | 203 | return 0; |
207 | } | 204 | } |
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 575be2bd..09e9e0a3 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c | |||
@@ -122,29 +122,29 @@ void printconnection(int connection_id) | |||
122 | 122 | ||
123 | /*( receive packets and send them to the packethandler */ | 123 | /*( receive packets and send them to the packethandler */ |
124 | /*run doLossless_UDP(); */ | 124 | /*run doLossless_UDP(); */ |
125 | void Lossless_UDP() | 125 | //void Lossless_UDP() |
126 | { | 126 | //{ |
127 | /* IP_Port ip_port; | 127 | /* IP_Port ip_port; |
128 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 128 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
129 | uint32_t length; | 129 | uint32_t length; |
130 | while (receivepacket(&ip_port, data, &length) != -1) { | 130 | while (receivepacket(&ip_port, data, &length) != -1) { |
131 | printf("packet with length: %u\n", length); */ | 131 | printf("packet with length: %u\n", length); */ |
132 | /* if(rand() % 3 != 1)//add packet loss | 132 | /* if(rand() % 3 != 1)//add packet loss |
133 | { */ | 133 | { */ |
134 | /* | 134 | /* |
135 | if (LosslessUDP_handlepacket(data, length, ip_port)) | 135 | if (LosslessUDP_handlepacket(data, length, ip_port)) |
136 | printpacket(data, length, ip_port); | 136 | printpacket(data, length, ip_port); |
137 | else | 137 | else |
138 | printf("Received handled packet with length: %u\n", length); //printconnection(0); */ | 138 | printf("Received handled packet with length: %u\n", length); //printconnection(0); */ |
139 | |||
140 | /* } */ | ||
141 | /* }*/ | ||
142 | |||
143 | networking_poll(); | ||
144 | |||
145 | doLossless_UDP(); | ||
146 | 139 | ||
147 | } | 140 | /* } */ |
141 | /* }*/ | ||
142 | |||
143 | //networking_poll(); | ||
144 | |||
145 | //doLossless_UDP(); | ||
146 | |||
147 | //} | ||
148 | 148 | ||
149 | int main(int argc, char *argv[]) | 149 | int main(int argc, char *argv[]) |
150 | { | 150 | { |
@@ -166,25 +166,26 @@ int main(int argc, char *argv[]) | |||
166 | /* bind to ip 0.0.0.0:PORT */ | 166 | /* bind to ip 0.0.0.0:PORT */ |
167 | IP ip; | 167 | IP ip; |
168 | ip.i = 0; | 168 | ip.i = 0; |
169 | init_networking(ip, PORT); | 169 | Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); |
170 | perror("Initialization"); | 170 | perror("Initialization"); |
171 | IP_Port serverip; | 171 | IP_Port serverip; |
172 | serverip.ip.i = inet_addr(argv[1]); | 172 | serverip.ip.i = inet_addr(argv[1]); |
173 | serverip.port = htons(atoi(argv[2])); | 173 | serverip.port = htons(atoi(argv[2])); |
174 | printip(serverip); | 174 | printip(serverip); |
175 | int connection = new_connection(serverip); | 175 | int connection = new_connection(ludp, serverip); |
176 | uint64_t timer = current_time(); | 176 | uint64_t timer = current_time(); |
177 | 177 | ||
178 | while (1) { | 178 | while (1) { |
179 | /* printconnection(connection); */ | 179 | /* printconnection(connection); */ |
180 | Lossless_UDP(); | 180 | networking_poll(ludp->net); |
181 | do_lossless_udp(ludp); | ||
181 | 182 | ||
182 | if (is_connected(connection) == 3) { | 183 | if (is_connected(ludp, connection) == 3) { |
183 | printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer)); | 184 | printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer)); |
184 | break; | 185 | break; |
185 | } | 186 | } |
186 | 187 | ||
187 | if (is_connected(connection) == 0) { | 188 | if (is_connected(ludp, connection) == 0) { |
188 | printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer)); | 189 | printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer)); |
189 | return 1; | 190 | return 1; |
190 | } | 191 | } |
@@ -194,25 +195,25 @@ int main(int argc, char *argv[]) | |||
194 | 195 | ||
195 | timer = current_time(); | 196 | timer = current_time(); |
196 | 197 | ||
197 | LosslessUDP_init(); | ||
198 | 198 | ||
199 | /*read first part of file */ | 199 | /*read first part of file */ |
200 | read = fread(buffer, 1, 512, file); | 200 | read = fread(buffer, 1, 512, file); |
201 | 201 | ||
202 | while (1) { | 202 | while (1) { |
203 | /* printconnection(connection); */ | 203 | /* printconnection(connection); */ |
204 | Lossless_UDP(); | 204 | networking_poll(ludp->net); |
205 | do_lossless_udp(ludp); | ||
205 | 206 | ||
206 | if (is_connected(connection) == 3) { | 207 | if (is_connected(ludp, connection) == 3) { |
207 | 208 | ||
208 | if (write_packet(connection, buffer, read)) { | 209 | if (write_packet(ludp, connection, buffer, read)) { |
209 | /* printf("Wrote data.\n"); */ | 210 | /* printf("Wrote data.\n"); */ |
210 | read = fread(buffer, 1, 512, file); | 211 | read = fread(buffer, 1, 512, file); |
211 | 212 | ||
212 | } | 213 | } |
213 | 214 | ||
214 | /* printf("%u\n", sendqueue(connection)); */ | 215 | /* printf("%u\n", sendqueue(connection)); */ |
215 | if (sendqueue(connection) == 0) { | 216 | if (sendqueue(ludp, connection) == 0) { |
216 | if (read == 0) { | 217 | if (read == 0) { |
217 | printf("Sent file successfully in: %llu us\n", (unsigned long long)(current_time() - timer)); | 218 | printf("Sent file successfully in: %llu us\n", (unsigned long long)(current_time() - timer)); |
218 | break; | 219 | break; |
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index dec50d7f..a82b787a 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c | |||
@@ -118,27 +118,27 @@ void printconnection(int connection_id) | |||
118 | 118 | ||
119 | /* receive packets and send them to the packethandler | 119 | /* receive packets and send them to the packethandler |
120 | * run doLossless_UDP(); */ | 120 | * run doLossless_UDP(); */ |
121 | void Lossless_UDP() | 121 | //void Lossless_UDP() |
122 | { | 122 | //{ |
123 | // IP_Port ip_port; | 123 | // IP_Port ip_port; |
124 | // uint8_t data[MAX_UDP_PACKET_SIZE]; | 124 | // uint8_t data[MAX_UDP_PACKET_SIZE]; |
125 | // uint32_t length; | 125 | // uint32_t length; |
126 | // while (receivepacket(&ip_port, data, &length) != -1) { | 126 | // while (receivepacket(&ip_port, data, &length) != -1) { |
127 | //if(rand() % 3 != 1)//add packet loss | 127 | //if(rand() % 3 != 1)//add packet loss |
128 | //{ | 128 | //{ |
129 | // if (LosslessUDP_handlepacket(data, length, ip_port)) { | 129 | // if (LosslessUDP_handlepacket(data, length, ip_port)) { |
130 | // printpacket(data, length, ip_port); | 130 | // printpacket(data, length, ip_port); |
131 | // } else { | 131 | // } else { |
132 | //printconnection(0); | 132 | //printconnection(0); |
133 | // printf("Received handled packet with length: %u\n", length); | 133 | // printf("Received handled packet with length: %u\n", length); |
134 | // } | 134 | // } |
135 | //} | 135 | //} |
136 | // } | 136 | // } |
137 | 137 | ||
138 | networking_poll(); | 138 | // networking_poll(); |
139 | 139 | ||
140 | doLossless_UDP(); | 140 | //doLossless_UDP(); |
141 | } | 141 | //} |
142 | 142 | ||
143 | 143 | ||
144 | int main(int argc, char *argv[]) | 144 | int main(int argc, char *argv[]) |
@@ -161,20 +161,19 @@ int main(int argc, char *argv[]) | |||
161 | //bind to ip 0.0.0.0:PORT | 161 | //bind to ip 0.0.0.0:PORT |
162 | IP ip; | 162 | IP ip; |
163 | ip.i = 0; | 163 | ip.i = 0; |
164 | init_networking(ip, PORT); | 164 | Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); |
165 | perror("Initialization"); | 165 | perror("Initialization"); |
166 | 166 | ||
167 | int connection; | 167 | int connection; |
168 | uint64_t timer = current_time(); | 168 | uint64_t timer = current_time(); |
169 | 169 | ||
170 | LosslessUDP_init(); | ||
171 | |||
172 | while (1) { | 170 | while (1) { |
173 | Lossless_UDP(); | 171 | networking_poll(ludp->net); |
174 | connection = incoming_connection(); | 172 | do_lossless_udp(ludp); |
173 | connection = incoming_connection(ludp); | ||
175 | 174 | ||
176 | if (connection != -1) { | 175 | if (connection != -1) { |
177 | if (is_connected(connection) == 2) { | 176 | if (is_connected(ludp, connection) == 2) { |
178 | printf("Received the connection.\n"); | 177 | printf("Received the connection.\n"); |
179 | 178 | ||
180 | } | 179 | } |
@@ -189,11 +188,12 @@ int main(int argc, char *argv[]) | |||
189 | 188 | ||
190 | while (1) { | 189 | while (1) { |
191 | //printconnection(0); | 190 | //printconnection(0); |
192 | Lossless_UDP(); | 191 | networking_poll(ludp->net); |
192 | do_lossless_udp(ludp); | ||
193 | 193 | ||
194 | if (is_connected(connection) >= 2) { | 194 | if (is_connected(ludp, connection) >= 2) { |
195 | kill_connection_in(connection, 3000000); | 195 | kill_connection_in(ludp, connection, 3000000); |
196 | read = read_packet(connection, buffer); | 196 | read = read_packet(ludp, connection, buffer); |
197 | 197 | ||
198 | if (read != 0) { | 198 | if (read != 0) { |
199 | // printf("Received data.\n"); | 199 | // printf("Received data.\n"); |
@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) | |||
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | if (is_connected(connection) == 4) { | 205 | if (is_connected(ludp, connection) == 4) { |
206 | printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); | 206 | printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); |
207 | fclose(file); | 207 | fclose(file); |
208 | return 1; | 208 | return 1; |
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index f8685b39..c76584d7 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <unistd.h> | 48 | #include <unistd.h> |
49 | #include <arpa/inet.h> | 49 | #include <arpa/inet.h> |
50 | #define c_sleep(x) usleep(1000*x) | 50 | #define c_sleep(x) usleep(1000*x) |
51 | #define PORT 33445 | ||
51 | 52 | ||
52 | #endif | 53 | #endif |
53 | 54 | ||
@@ -106,7 +107,7 @@ int main(int argc, char *argv[]) | |||
106 | IP_Port bootstrap_ip_port; | 107 | IP_Port bootstrap_ip_port; |
107 | bootstrap_ip_port.port = htons(atoi(argv[2])); | 108 | bootstrap_ip_port.port = htons(atoi(argv[2])); |
108 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | 109 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); |
109 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); | 110 | DHT_bootstrap(m->dht, bootstrap_ip_port, hex_string_to_bin(argv[3])); |
110 | } else { | 111 | } else { |
111 | FILE *file = fopen(argv[1], "rb"); | 112 | FILE *file = fopen(argv[1], "rb"); |
112 | 113 | ||
diff --git a/testing/cmake/timer_test.cmake b/testing/cmake/timer_test.cmake deleted file mode 100644 index a5f8c5ec..00000000 --- a/testing/cmake/timer_test.cmake +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | cmake_minimum_required(VERSION 2.6.0) | ||
2 | project(timer_test C) | ||
3 | |||
4 | set(exe_name timer_test) | ||
5 | |||
6 | add_executable(${exe_name} | ||
7 | timer_test.c) | ||
8 | |||
9 | linkCoreLibraries(${exe_name}) | ||
diff --git a/testing/nTox.c b/testing/nTox.c index 8813f305..a476cc19 100644 --- a/testing/nTox.c +++ b/testing/nTox.c | |||
@@ -521,12 +521,12 @@ int main(int argc, char *argv[]) | |||
521 | exit(1); | 521 | exit(1); |
522 | 522 | ||
523 | unsigned char *binary_string = hex_string_to_bin(argv[3]); | 523 | unsigned char *binary_string = hex_string_to_bin(argv[3]); |
524 | DHT_bootstrap(bootstrap_ip_port, binary_string); | 524 | DHT_bootstrap(m->dht, bootstrap_ip_port, binary_string); |
525 | free(binary_string); | 525 | free(binary_string); |
526 | nodelay(stdscr, TRUE); | 526 | nodelay(stdscr, TRUE); |
527 | 527 | ||
528 | while (true) { | 528 | while (true) { |
529 | if (on == 0 && DHT_isconnected()) { | 529 | if (on == 0 && DHT_isconnected(m->dht)) { |
530 | new_lines("[i] connected to DHT\n[i] define username with /n"); | 530 | new_lines("[i] connected to DHT\n[i] define username with /n"); |
531 | on = 1; | 531 | on = 1; |
532 | } | 532 | } |
diff --git a/testing/timer_test.c b/testing/timer_test.c deleted file mode 100644 index f47d4878..00000000 --- a/testing/timer_test.c +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | #include "../core/timer.h" | ||
2 | #include <stdio.h> | ||
3 | |||
4 | #ifdef WINDOWS | ||
5 | #include <windows.h> | ||
6 | #else | ||
7 | #include <unistd.h> | ||
8 | #endif | ||
9 | |||
10 | void mssleep(int ms) | ||
11 | { | ||
12 | #ifdef WINDOWS | ||
13 | Sleep(ms); | ||
14 | #else | ||
15 | usleep(ms * 1000); | ||
16 | #endif | ||
17 | } | ||
18 | |||
19 | int callback(timer *t, void *arg) | ||
20 | { | ||
21 | printf("%s\n", (char *)arg); | ||
22 | return 1; | ||
23 | } | ||
24 | |||
25 | int repeating(timer *t, void *arg) | ||
26 | { | ||
27 | printf("%s\n", (char *)arg); | ||
28 | timer_start(t, 3); | ||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | extern void timer_debug_print(); | ||
33 | |||
34 | int main(int argc, char **argv) | ||
35 | { | ||
36 | timer_init(); | ||
37 | timer_debug_print(); | ||
38 | |||
39 | timer *t = new_timer(); | ||
40 | timer_setup(t, &callback, "Long setup method, 4 seconds"); | ||
41 | timer_start(t, 4); | ||
42 | timer_debug_print(); | ||
43 | |||
44 | timer_single(&repeating, (void *)"This repeats every 3 seconds", 3); | ||
45 | timer_debug_print(); | ||
46 | |||
47 | timer_single(&callback, "Short method, 4 seconds", 4); | ||
48 | timer_debug_print(); | ||
49 | |||
50 | timer_single(&callback, "1 second", 1); | ||
51 | timer_debug_print(); | ||
52 | |||
53 | timer_single(&callback, "15 seconds", 15); | ||
54 | timer_debug_print(); | ||
55 | |||
56 | timer_single(&callback, "10 seconds", 10); | ||
57 | timer_debug_print(); | ||
58 | |||
59 | timer_us(&callback, "100000us", 100000); | ||
60 | timer_us(&callback, "13s", 13 * US_PER_SECOND); | ||
61 | |||
62 | while (true) { | ||
63 | timer_poll(); | ||
64 | mssleep(10); | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index 57404a59..c7979843 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c | |||
@@ -123,7 +123,7 @@ static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint1 | |||
123 | 123 | ||
124 | status[len - 1] = '\0'; | 124 | status[len - 1] = '\0'; |
125 | fix_name(status); | 125 | fix_name(status); |
126 | 126 | ||
127 | wattron(ctx->history, COLOR_PAIR(3)); | 127 | wattron(ctx->history, COLOR_PAIR(3)); |
128 | wprintw(ctx->history, "* Your partner changed status to '%s'\n", status); | 128 | wprintw(ctx->history, "* Your partner changed status to '%s'\n", status); |
129 | wattroff(ctx->history, COLOR_PAIR(3)); | 129 | wattroff(ctx->history, COLOR_PAIR(3)); |
@@ -342,7 +342,7 @@ void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd) | |||
342 | wprintw(ctx->history, "Invalid command.\n"); | 342 | wprintw(ctx->history, "Invalid command.\n"); |
343 | } | 343 | } |
344 | 344 | ||
345 | static void chat_onDraw(ToxWindow *self) | 345 | static void chat_onDraw(ToxWindow *self, Messenger *m) |
346 | { | 346 | { |
347 | curs_set(1); | 347 | curs_set(1); |
348 | int x, y; | 348 | int x, y; |
diff --git a/testing/toxic/dhtstatus.c b/testing/toxic/dhtstatus.c index a11dc616..6c9f2a80 100644 --- a/testing/toxic/dhtstatus.c +++ b/testing/toxic/dhtstatus.c | |||
@@ -34,9 +34,9 @@ static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key) | |||
34 | } | 34 | } |
35 | } | 35 | } |
36 | 36 | ||
37 | static void dhtstatus_onDraw(ToxWindow *self) | 37 | static void dhtstatus_onDraw(ToxWindow *self, Messenger *m) |
38 | { | 38 | { |
39 | Client_data *close_clientlist = DHT_get_close_list(); | 39 | Client_data *close_clientlist = DHT_get_close_list(m->dht); |
40 | curs_set(0); | 40 | curs_set(0); |
41 | werase(self->window); | 41 | werase(self->window); |
42 | 42 | ||
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c index 0a58bc54..2e46f124 100644 --- a/testing/toxic/friendlist.c +++ b/testing/toxic/friendlist.c | |||
@@ -102,7 +102,7 @@ static void friendlist_onKey(ToxWindow *self, Messenger *m, int key) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | static void friendlist_onDraw(ToxWindow *self) | 105 | static void friendlist_onDraw(ToxWindow *self, Messenger *m) |
106 | { | 106 | { |
107 | curs_set(0); | 107 | curs_set(0); |
108 | werase(self->window); | 108 | werase(self->window); |
diff --git a/testing/toxic/main.c b/testing/toxic/main.c index 9abe8de4..e5525e94 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c | |||
@@ -90,11 +90,11 @@ static Messenger *init_tox() | |||
90 | #define MAXSERVERS 50 | 90 | #define MAXSERVERS 50 |
91 | 91 | ||
92 | /* Connects to a random DHT server listed in the DHTservers file */ | 92 | /* Connects to a random DHT server listed in the DHTservers file */ |
93 | int init_connection(void) | 93 | int init_connection(Messenger *m) |
94 | { | 94 | { |
95 | FILE *fp = NULL; | 95 | FILE *fp = NULL; |
96 | 96 | ||
97 | if (DHT_isconnected()) | 97 | if (DHT_isconnected(m->dht)) |
98 | return 0; | 98 | return 0; |
99 | 99 | ||
100 | fp = fopen(SRVLIST_FILE, "r"); | 100 | fp = fopen(SRVLIST_FILE, "r"); |
@@ -135,7 +135,7 @@ int init_connection(void) | |||
135 | 135 | ||
136 | dht.ip.i = resolved_address; | 136 | dht.ip.i = resolved_address; |
137 | unsigned char *binary_string = hex_string_to_bin(key); | 137 | unsigned char *binary_string = hex_string_to_bin(key); |
138 | DHT_bootstrap(dht, binary_string); | 138 | DHT_bootstrap(m->dht, dht, binary_string); |
139 | free(binary_string); | 139 | free(binary_string); |
140 | return 0; | 140 | return 0; |
141 | } | 141 | } |
@@ -146,18 +146,18 @@ static void do_tox(Messenger *m, ToxWindow *prompt) | |||
146 | static int conn_err = 0; | 146 | static int conn_err = 0; |
147 | static bool dht_on = false; | 147 | static bool dht_on = false; |
148 | 148 | ||
149 | if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) { | 149 | if (!dht_on && !DHT_isconnected(m->dht) && !(conn_try++ % 100)) { |
150 | if (!conn_err) { | 150 | if (!conn_err) { |
151 | conn_err = init_connection(); | 151 | conn_err = init_connection(m); |
152 | wprintw(prompt->window, "\nEstablishing connection...\n"); | 152 | wprintw(prompt->window, "\nEstablishing connection...\n"); |
153 | 153 | ||
154 | if (conn_err) | 154 | if (conn_err) |
155 | wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err); | 155 | wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err); |
156 | } | 156 | } |
157 | } else if (!dht_on && DHT_isconnected()) { | 157 | } else if (!dht_on && DHT_isconnected(m->dht)) { |
158 | dht_on = true; | 158 | dht_on = true; |
159 | wprintw(prompt->window, "\nDHT connected.\n"); | 159 | wprintw(prompt->window, "\nDHT connected.\n"); |
160 | } else if (dht_on && !DHT_isconnected()) { | 160 | } else if (dht_on && !DHT_isconnected(m->dht)) { |
161 | dht_on = false; | 161 | dht_on = false; |
162 | wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n"); | 162 | wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n"); |
163 | } | 163 | } |
@@ -297,7 +297,7 @@ int main(int argc, char *argv[]) | |||
297 | strcpy(DATA_FILE, user_config_dir); | 297 | strcpy(DATA_FILE, user_config_dir); |
298 | strcat(DATA_FILE, CONFIGDIR); | 298 | strcat(DATA_FILE, CONFIGDIR); |
299 | strcat(DATA_FILE, "data"); | 299 | strcat(DATA_FILE, "data"); |
300 | 300 | ||
301 | SRVLIST_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("DHTservers") + 1); | 301 | SRVLIST_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("DHTservers") + 1); |
302 | strcpy(SRVLIST_FILE, user_config_dir); | 302 | strcpy(SRVLIST_FILE, user_config_dir); |
303 | strcat(SRVLIST_FILE, CONFIGDIR); | 303 | strcat(SRVLIST_FILE, CONFIGDIR); |
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index 81f00bce..e194a90e 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c | |||
@@ -204,7 +204,7 @@ void cmd_connect(ToxWindow *self, Messenger *m, char **args) | |||
204 | 204 | ||
205 | dht.ip.i = resolved_address; | 205 | dht.ip.i = resolved_address; |
206 | unsigned char *binary_string = hex_string_to_bin(key); | 206 | unsigned char *binary_string = hex_string_to_bin(key); |
207 | DHT_bootstrap(dht, binary_string); | 207 | DHT_bootstrap(m->dht, dht, binary_string); |
208 | free(binary_string); | 208 | free(binary_string); |
209 | } | 209 | } |
210 | 210 | ||
@@ -365,7 +365,9 @@ static void execute(ToxWindow *self, Messenger *m, char *u_cmd) | |||
365 | cmd[i] = '\0'; | 365 | cmd[i] = '\0'; |
366 | 366 | ||
367 | int j = i; | 367 | int j = i; |
368 | |||
368 | while (++j < MAX_STR_SIZE && isspace(cmd[j])); | 369 | while (++j < MAX_STR_SIZE && isspace(cmd[j])); |
370 | |||
369 | i = j - 1; | 371 | i = j - 1; |
370 | 372 | ||
371 | numargs++; | 373 | numargs++; |
@@ -460,7 +462,7 @@ static void prompt_onKey(ToxWindow *self, Messenger *m, int key) | |||
460 | } | 462 | } |
461 | } | 463 | } |
462 | 464 | ||
463 | static void prompt_onDraw(ToxWindow *self) | 465 | static void prompt_onDraw(ToxWindow *self, Messenger *m) |
464 | { | 466 | { |
465 | curs_set(1); | 467 | curs_set(1); |
466 | int x, y; | 468 | int x, y; |
diff --git a/testing/toxic/windows.c b/testing/toxic/windows.c index c0ff3026..8fdf4e19 100644 --- a/testing/toxic/windows.c +++ b/testing/toxic/windows.c | |||
@@ -88,23 +88,25 @@ int add_window(Messenger *m, ToxWindow w) | |||
88 | { | 88 | { |
89 | if (LINES < 2) | 89 | if (LINES < 2) |
90 | return -1; | 90 | return -1; |
91 | 91 | ||
92 | int i; | 92 | int i; |
93 | for(i = 0; i < MAX_WINDOWS_NUM; i++) { | 93 | |
94 | if (windows[i].window) | 94 | for (i = 0; i < MAX_WINDOWS_NUM; i++) { |
95 | if (windows[i].window) | ||
95 | continue; | 96 | continue; |
96 | 97 | ||
97 | w.window = newwin(LINES - 2, COLS, 0, 0); | 98 | w.window = newwin(LINES - 2, COLS, 0, 0); |
99 | |||
98 | if (w.window == NULL) | 100 | if (w.window == NULL) |
99 | return -1; | 101 | return -1; |
100 | 102 | ||
101 | windows[i] = w; | 103 | windows[i] = w; |
102 | w.onInit(&w, m); | 104 | w.onInit(&w, m); |
103 | 105 | ||
104 | active_window = windows+i; | 106 | active_window = windows + i; |
105 | return i; | 107 | return i; |
106 | } | 108 | } |
107 | 109 | ||
108 | return -1; | 110 | return -1; |
109 | } | 111 | } |
110 | 112 | ||
@@ -113,8 +115,10 @@ void del_window(ToxWindow *w) | |||
113 | { | 115 | { |
114 | active_window = windows; // Go to prompt screen | 116 | active_window = windows; // Go to prompt screen |
115 | delwin(w->window); | 117 | delwin(w->window); |
118 | |||
116 | if (w->x) | 119 | if (w->x) |
117 | free(w->x); | 120 | free(w->x); |
121 | |||
118 | w->window = NULL; | 122 | w->window = NULL; |
119 | memset(w, 0, sizeof(ToxWindow)); | 123 | memset(w, 0, sizeof(ToxWindow)); |
120 | clear(); | 124 | clear(); |
@@ -124,19 +128,19 @@ void del_window(ToxWindow *w) | |||
124 | /* Shows next window when tab or back-tab is pressed */ | 128 | /* Shows next window when tab or back-tab is pressed */ |
125 | void set_next_window(int ch) | 129 | void set_next_window(int ch) |
126 | { | 130 | { |
127 | ToxWindow *end = windows+MAX_WINDOWS_NUM-1; | 131 | ToxWindow *end = windows + MAX_WINDOWS_NUM - 1; |
128 | ToxWindow *inf = active_window; | 132 | ToxWindow *inf = active_window; |
129 | while(true) { | 133 | |
134 | while (true) { | ||
130 | if (ch == '\t') { | 135 | if (ch == '\t') { |
131 | if (++active_window > end) | 136 | if (++active_window > end) |
132 | active_window = windows; | 137 | active_window = windows; |
133 | } else | 138 | } else if (--active_window < windows) |
134 | if (--active_window < windows) | 139 | active_window = end; |
135 | active_window = end; | 140 | |
136 | |||
137 | if (active_window->window) | 141 | if (active_window->window) |
138 | return; | 142 | return; |
139 | 143 | ||
140 | if (active_window == inf) { // infinite loop check | 144 | if (active_window == inf) { // infinite loop check |
141 | endwin(); | 145 | endwin(); |
142 | exit(2); | 146 | exit(2); |
@@ -148,14 +152,14 @@ void set_active_window(int index) | |||
148 | { | 152 | { |
149 | if (index < 0 || index >= MAX_WINDOWS_NUM) | 153 | if (index < 0 || index >= MAX_WINDOWS_NUM) |
150 | return; | 154 | return; |
151 | 155 | ||
152 | active_window = windows+index; | 156 | active_window = windows + index; |
153 | } | 157 | } |
154 | 158 | ||
155 | ToxWindow *init_windows() | 159 | ToxWindow *init_windows() |
156 | { | 160 | { |
157 | int n_prompt = add_window(m, new_prompt()); | 161 | int n_prompt = add_window(m, new_prompt()); |
158 | 162 | ||
159 | if (n_prompt == -1 | 163 | if (n_prompt == -1 |
160 | || add_window(m, new_friendlist()) == -1 | 164 | || add_window(m, new_friendlist()) == -1 |
161 | || add_window(m, new_dhtstatus()) == -1) { | 165 | || add_window(m, new_dhtstatus()) == -1) { |
@@ -166,7 +170,7 @@ ToxWindow *init_windows() | |||
166 | 170 | ||
167 | prompt = &windows[n_prompt]; | 171 | prompt = &windows[n_prompt]; |
168 | active_window = prompt; | 172 | active_window = prompt; |
169 | 173 | ||
170 | return prompt; | 174 | return prompt; |
171 | } | 175 | } |
172 | 176 | ||
@@ -189,7 +193,7 @@ static void draw_bar() | |||
189 | 193 | ||
190 | for (i = 0; i < (MAX_WINDOWS_NUM); ++i) { | 194 | for (i = 0; i < (MAX_WINDOWS_NUM); ++i) { |
191 | if (windows[i].window) { | 195 | if (windows[i].window) { |
192 | if (windows+i == active_window) | 196 | if (windows + i == active_window) |
193 | attron(A_BOLD); | 197 | attron(A_BOLD); |
194 | 198 | ||
195 | odd = (odd + 1) % blinkrate; | 199 | odd = (odd + 1) % blinkrate; |
@@ -197,13 +201,13 @@ static void draw_bar() | |||
197 | if (windows[i].blink && (odd < (blinkrate / 2))) | 201 | if (windows[i].blink && (odd < (blinkrate / 2))) |
198 | attron(COLOR_PAIR(3)); | 202 | attron(COLOR_PAIR(3)); |
199 | 203 | ||
200 | clrtoeol(); | 204 | clrtoeol(); |
201 | printw(" %s", windows[i].title); | 205 | printw(" %s", windows[i].title); |
202 | 206 | ||
203 | if (windows[i].blink && (odd < (blinkrate / 2))) | 207 | if (windows[i].blink && (odd < (blinkrate / 2))) |
204 | attroff(COLOR_PAIR(3)); | 208 | attroff(COLOR_PAIR(3)); |
205 | 209 | ||
206 | if (windows+i == active_window) { | 210 | if (windows + i == active_window) { |
207 | attroff(A_BOLD); | 211 | attroff(A_BOLD); |
208 | } | 212 | } |
209 | } | 213 | } |
@@ -225,7 +229,7 @@ void draw_active_window(Messenger *m) | |||
225 | prepare_window(a->window); | 229 | prepare_window(a->window); |
226 | a->blink = false; | 230 | a->blink = false; |
227 | draw_bar(); | 231 | draw_bar(); |
228 | a->onDraw(a); | 232 | a->onDraw(a, m); |
229 | 233 | ||
230 | /* Handle input */ | 234 | /* Handle input */ |
231 | int ch = getch(); | 235 | int ch = getch(); |
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h index be5557e9..86917dbe 100644 --- a/testing/toxic/windows.h +++ b/testing/toxic/windows.h | |||
@@ -24,7 +24,7 @@ typedef struct ToxWindow_ ToxWindow; | |||
24 | 24 | ||
25 | struct ToxWindow_ { | 25 | struct ToxWindow_ { |
26 | void(*onKey)(ToxWindow *, Messenger *, int); | 26 | void(*onKey)(ToxWindow *, Messenger *, int); |
27 | void(*onDraw)(ToxWindow *); | 27 | void(*onDraw)(ToxWindow *, Messenger *); |
28 | void(*onInit)(ToxWindow *, Messenger *); | 28 | void(*onInit)(ToxWindow *, Messenger *); |
29 | void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t); | 29 | void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t); |
30 | void(*onMessage)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t); | 30 | void(*onMessage)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t); |