summaryrefslogtreecommitdiff
path: root/core/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/DHT.c')
-rw-r--r--core/DHT.c461
1 files changed, 258 insertions, 203 deletions
diff --git a/core/DHT.c b/core/DHT.c
index c3249846..226a38ca 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -77,7 +77,7 @@ typedef struct {
77 /* Symetric NAT hole punching stuff */ 77 /* Symetric NAT hole punching stuff */
78 78
79 /* 1 if currently hole punching, otherwise 0 */ 79 /* 1 if currently hole punching, otherwise 0 */
80 uint8_t hole_punching; 80 uint8_t hole_punching;
81 uint32_t punching_index; 81 uint32_t punching_index;
82 uint64_t punching_timestamp; 82 uint64_t punching_timestamp;
83 uint64_t recvNATping_timestamp; 83 uint64_t recvNATping_timestamp;
@@ -98,11 +98,11 @@ typedef struct {
98 98
99/*----------------------------------------------------------------------------------*/ 99/*----------------------------------------------------------------------------------*/
100 100
101 /* Our client id/public key */ 101/* Our client id/public key */
102uint8_t self_public_key[CLIENT_ID_SIZE]; 102uint8_t self_public_key[CLIENT_ID_SIZE];
103uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 103uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
104static Client_data close_clientlist[LCLIENT_LIST]; 104static Client_data close_clientlist[LCLIENT_LIST];
105static Friend * friends_list; 105static Friend *friends_list;
106static uint16_t num_friends; 106static uint16_t num_friends;
107static Pinged send_nodes[LSEND_NODES_ARRAY]; 107static Pinged send_nodes[LSEND_NODES_ARRAY];
108static Node_format toping[MAX_TOPING]; 108static Node_format toping[MAX_TOPING];
@@ -111,7 +111,7 @@ static uint64_t last_toping;
111/*----------------------------------------------------------------------------------*/ 111/*----------------------------------------------------------------------------------*/
112 112
113 113
114Client_data * DHT_get_close_list(void) 114Client_data *DHT_get_close_list(void)
115{ 115{
116 return close_clientlist; 116 return close_clientlist;
117} 117}
@@ -121,37 +121,39 @@ Client_data * DHT_get_close_list(void)
121 * return 1 if client_id1 is closer 121 * return 1 if client_id1 is closer
122 * return 2 if client_id2 is closer 122 * return 2 if client_id2 is closer
123 */ 123 */
124static int id_closest(uint8_t * id, uint8_t * id1, uint8_t * id2) 124static int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2)
125{ 125{
126 size_t i; 126 size_t i;
127 uint8_t distance1, distance2; 127 uint8_t distance1, distance2;
128 128
129 for(i = 0; i < CLIENT_ID_SIZE; ++i) { 129 for (i = 0; i < CLIENT_ID_SIZE; ++i) {
130 130
131 distance1 = abs(id[i] ^ id1[i]); 131 distance1 = abs(id[i] ^ id1[i]);
132 distance2 = abs(id[i] ^ id2[i]); 132 distance2 = abs(id[i] ^ id2[i]);
133 133
134 if(distance1 < distance2) 134 if (distance1 < distance2)
135 return 1; 135 return 1;
136 if(distance1 > distance2) 136
137 if (distance1 > distance2)
137 return 2; 138 return 2;
138 } 139 }
140
139 return 0; 141 return 0;
140} 142}
141 143
142static int ipport_equal(IP_Port a, IP_Port b) 144static int ipport_equal(IP_Port a, IP_Port b)
143{ 145{
144 return (a.ip.i == b.ip.i) && (a.port == b.port); 146 return (a.ip.i == b.ip.i) && (a.port == b.port);
145} 147}
146 148
147static int id_equal(uint8_t* a, uint8_t* b) 149static int id_equal(uint8_t *a, uint8_t *b)
148{ 150{
149 return memcmp(a, b, CLIENT_ID_SIZE) == 0; 151 return memcmp(a, b, CLIENT_ID_SIZE) == 0;
150} 152}
151 153
152static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout) 154static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
153{ 155{
154 return timestamp + timeout <= time_now; 156 return timestamp + timeout <= time_now;
155} 157}
156 158
157/* check if client with client_id is already in list of length length. 159/* check if client with client_id is already in list of length length.
@@ -161,18 +163,18 @@ static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
161 * 163 *
162 * TODO: maybe optimize this. 164 * TODO: maybe optimize this.
163 */ 165 */
164static int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) 166static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port)
165{ 167{
166 uint32_t i; 168 uint32_t i;
167 uint64_t temp_time = unix_time(); 169 uint64_t temp_time = unix_time();
168 170
169 for(i = 0; i < length; ++i) { 171 for (i = 0; i < length; ++i) {
170 /*If ip_port is assigned to a different client_id replace it*/ 172 /*If ip_port is assigned to a different client_id replace it*/
171 if(ipport_equal(list[i].ip_port, ip_port)) { 173 if (ipport_equal(list[i].ip_port, ip_port)) {
172 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 174 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
173 } 175 }
174 176
175 if(id_equal(list[i].client_id, client_id)) { 177 if (id_equal(list[i].client_id, client_id)) {
176 /* Refresh the client timestamp. */ 178 /* Refresh the client timestamp. */
177 list[i].timestamp = temp_time; 179 list[i].timestamp = temp_time;
178 list[i].ip_port.ip.i = ip_port.ip.i; 180 list[i].ip_port.ip.i = ip_port.ip.i;
@@ -180,18 +182,19 @@ static int client_in_list(Client_data * list, uint32_t length, uint8_t * client_
180 return 1; 182 return 1;
181 } 183 }
182 } 184 }
185
183 return 0; 186 return 0;
184} 187}
185 188
186/* check if client with client_id is already in node format list of length length. 189/* check if client with client_id is already in node format list of length length.
187 * return True(1) or False(0) 190 * return True(1) or False(0)
188 */ 191 */
189static int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 192static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id)
190{ 193{
191 uint32_t i; 194 uint32_t i;
192 195
193 for(i = 0; i < length; ++i) { 196 for (i = 0; i < length; ++i) {
194 if(id_equal(list[i].client_id, client_id)) 197 if (id_equal(list[i].client_id, client_id))
195 return 1; 198 return 1;
196 } 199 }
197 200
@@ -200,12 +203,12 @@ static int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * cli
200 203
201/* Returns the friend number from the client_id, or -1 if a failure occurs 204/* Returns the friend number from the client_id, or -1 if a failure occurs
202 */ 205 */
203static int friend_number(uint8_t * client_id) 206static int friend_number(uint8_t *client_id)
204{ 207{
205 uint32_t i; 208 uint32_t i;
206 209
207 for(i = 0; i < num_friends; ++i) { 210 for (i = 0; i < num_friends; ++i) {
208 if(id_equal(friends_list[i].client_id, client_id)) 211 if (id_equal(friends_list[i].client_id, client_id))
209 return i; 212 return i;
210 } 213 }
211 214
@@ -217,7 +220,7 @@ static int friend_number(uint8_t * client_id)
217 * 220 *
218 * TODO: For the love of based Allah make this function cleaner and much more efficient. 221 * TODO: For the love of based Allah make this function cleaner and much more efficient.
219 */ 222 */
220static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 223static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list)
221{ 224{
222 uint32_t i, j, k; 225 uint32_t i, j, k;
223 uint64_t temp_time = unix_time(); 226 uint64_t temp_time = unix_time();
@@ -228,13 +231,13 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
228 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); 231 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id);
229 232
230 /* if node isn't good or is already in list. */ 233 /* if node isn't good or is already in list. */
231 if(tout || inlist) 234 if (tout || inlist)
232 continue; 235 continue;
233 236
234 if(num_nodes < MAX_SENT_NODES) { 237 if (num_nodes < MAX_SENT_NODES) {
235 238
236 memcpy( nodes_list[num_nodes].client_id, 239 memcpy( nodes_list[num_nodes].client_id,
237 close_clientlist[i].client_id, 240 close_clientlist[i].client_id,
238 CLIENT_ID_SIZE ); 241 CLIENT_ID_SIZE );
239 242
240 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 243 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
@@ -242,13 +245,14 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
242 245
243 } else { 246 } else {
244 247
245 for(j = 0; j < MAX_SENT_NODES; ++j) { 248 for (j = 0; j < MAX_SENT_NODES; ++j) {
246 closest = id_closest( client_id, 249 closest = id_closest( client_id,
247 nodes_list[j].client_id, 250 nodes_list[j].client_id,
248 close_clientlist[i].client_id ); 251 close_clientlist[i].client_id );
249 if(closest == 2) { 252
250 memcpy( nodes_list[j].client_id, 253 if (closest == 2) {
251 close_clientlist[i].client_id, 254 memcpy( nodes_list[j].client_id,
255 close_clientlist[i].client_id,
252 CLIENT_ID_SIZE); 256 CLIENT_ID_SIZE);
253 257
254 nodes_list[j].ip_port = close_clientlist[i].ip_port; 258 nodes_list[j].ip_port = close_clientlist[i].ip_port;
@@ -258,35 +262,36 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
258 } 262 }
259 } 263 }
260 264
261 for(i = 0; i < num_friends; ++i) { 265 for (i = 0; i < num_friends; ++i) {
262 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 266 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
263 267
264 tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); 268 tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT);
265 inlist = client_in_nodelist( nodes_list, 269 inlist = client_in_nodelist( nodes_list,
266 MAX_SENT_NODES, 270 MAX_SENT_NODES,
267 friends_list[i].client_list[j].client_id); 271 friends_list[i].client_list[j].client_id);
268 272
269 /* if node isn't good or is already in list. */ 273 /* if node isn't good or is already in list. */
270 if(tout || inlist) 274 if (tout || inlist)
271 continue; 275 continue;
272 276
273 if(num_nodes < MAX_SENT_NODES) { 277 if (num_nodes < MAX_SENT_NODES) {
274 278
275 memcpy( nodes_list[num_nodes].client_id, 279 memcpy( nodes_list[num_nodes].client_id,
276 friends_list[i].client_list[j].client_id, 280 friends_list[i].client_list[j].client_id,
277 CLIENT_ID_SIZE); 281 CLIENT_ID_SIZE);
278 282
279 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 283 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
280 num_nodes++; 284 num_nodes++;
281 } else { 285 } else {
282 for(k = 0; k < MAX_SENT_NODES; ++k) { 286 for (k = 0; k < MAX_SENT_NODES; ++k) {
283 287
284 closest = id_closest( client_id, 288 closest = id_closest( client_id,
285 nodes_list[k].client_id, 289 nodes_list[k].client_id,
286 friends_list[i].client_list[j].client_id ); 290 friends_list[i].client_list[j].client_id );
287 if(closest == 2) { 291
288 memcpy( nodes_list[k].client_id, 292 if (closest == 2) {
289 friends_list[i].client_list[j].client_id, 293 memcpy( nodes_list[k].client_id,
294 friends_list[i].client_list[j].client_id,
290 CLIENT_ID_SIZE ); 295 CLIENT_ID_SIZE );
291 296
292 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 297 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
@@ -296,6 +301,7 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
296 } 301 }
297 } 302 }
298 } 303 }
304
299 return num_nodes; 305 return num_nodes;
300} 306}
301 307
@@ -303,16 +309,17 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
303 * return 0 if successful 309 * return 0 if successful
304 * return 1 if not (list contains no bad nodes) 310 * return 1 if not (list contains no bad nodes)
305 */ 311 */
306static int replace_bad( Client_data * list, 312static int replace_bad( Client_data *list,
307 uint32_t length, 313 uint32_t length,
308 uint8_t * client_id, 314 uint8_t *client_id,
309 IP_Port ip_port ) 315 IP_Port ip_port )
310{ 316{
311 uint32_t i; 317 uint32_t i;
312 uint64_t temp_time = unix_time(); 318 uint64_t temp_time = unix_time();
313 for(i = 0; i < length; ++i) { 319
320 for (i = 0; i < length; ++i) {
314 /* if node is bad */ 321 /* if node is bad */
315 if(is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) { 322 if (is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) {
316 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 323 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
317 list[i].ip_port = ip_port; 324 list[i].ip_port = ip_port;
318 list[i].timestamp = temp_time; 325 list[i].timestamp = temp_time;
@@ -325,42 +332,46 @@ static int replace_bad( Client_data * list,
325 332
326 return 1; 333 return 1;
327} 334}
328/*Sort the list. It will be sorted from furthest to closest. 335/*Sort the list. It will be sorted from furthest to closest.
329 TODO: this is innefficient and needs to be optimized.*/ 336 TODO: this is innefficient and needs to be optimized.*/
330static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) 337static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id)
331{ 338{
332 if(length == 0) 339 if (length == 0)
333 return; 340 return;
341
334 uint32_t i, count; 342 uint32_t i, count;
335 while(1) { 343
344 while (1) {
336 count = 0; 345 count = 0;
337 for(i = 0; i < (length - 1); ++i) { 346
338 if(id_closest(comp_client_id, list[i].client_id, list[i + 1].client_id) == 1) { 347 for (i = 0; i < (length - 1); ++i) {
348 if (id_closest(comp_client_id, list[i].client_id, list[i + 1].client_id) == 1) {
339 Client_data temp = list[i + 1]; 349 Client_data temp = list[i + 1];
340 list[i + 1] = list[i]; 350 list[i + 1] = list[i];
341 list[i] = temp; 351 list[i] = temp;
342 ++count; 352 ++count;
343 } 353 }
344 } 354 }
345 if(count == 0) 355
356 if (count == 0)
346 return; 357 return;
347 } 358 }
348} 359}
349 360
350 361
351/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ 362/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */
352static int replace_good( Client_data * list, 363static int replace_good( Client_data *list,
353 uint32_t length, 364 uint32_t length,
354 uint8_t * client_id, 365 uint8_t *client_id,
355 IP_Port ip_port, 366 IP_Port ip_port,
356 uint8_t * comp_client_id ) 367 uint8_t *comp_client_id )
357{ 368{
358 uint32_t i; 369 uint32_t i;
359 uint64_t temp_time = unix_time(); 370 uint64_t temp_time = unix_time();
360 sort_list(list, length, comp_client_id); 371 sort_list(list, length, comp_client_id);
361 372
362 for(i = 0; i < length; ++i) 373 for (i = 0; i < length; ++i)
363 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { 374 if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
364 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 375 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
365 list[i].ip_port = ip_port; 376 list[i].ip_port = ip_port;
366 list[i].timestamp = temp_time; 377 list[i].timestamp = temp_time;
@@ -373,42 +384,42 @@ static int replace_good( Client_data * list,
373 return 1; 384 return 1;
374} 385}
375 386
376/* Attempt to add client with ip_port and client_id to the friends client list 387/* Attempt to add client with ip_port and client_id to the friends client list
377 * and close_clientlist 388 * and close_clientlist
378 */ 389 */
379void addto_lists(IP_Port ip_port, uint8_t * client_id) 390void addto_lists(IP_Port ip_port, uint8_t *client_id)
380{ 391{
381 uint32_t i; 392 uint32_t i;
382 393
383 /* NOTE: current behavior if there are two clients with the same id is 394 /* NOTE: current behavior if there are two clients with the same id is
384 * to replace the first ip by the second. 395 * to replace the first ip by the second.
385 */ 396 */
386 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 397 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
387 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 398 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
388 /* if we can't replace bad nodes we try replacing good ones */ 399 /* if we can't replace bad nodes we try replacing good ones */
389 replace_good( close_clientlist, 400 replace_good( close_clientlist,
390 LCLIENT_LIST, 401 LCLIENT_LIST,
391 client_id, 402 client_id,
392 ip_port, 403 ip_port,
393 self_public_key ); 404 self_public_key );
394 } 405 }
395 } 406 }
396 407
397 for (i = 0; i < num_friends; ++i) { 408 for (i = 0; i < num_friends; ++i) {
398 if (!client_in_list( friends_list[i].client_list, 409 if (!client_in_list( friends_list[i].client_list,
399 MAX_FRIEND_CLIENTS, 410 MAX_FRIEND_CLIENTS,
400 client_id, 411 client_id,
401 ip_port )) { 412 ip_port )) {
402 413
403 if (replace_bad( friends_list[i].client_list, 414 if (replace_bad( friends_list[i].client_list,
404 MAX_FRIEND_CLIENTS, 415 MAX_FRIEND_CLIENTS,
405 client_id, 416 client_id,
406 ip_port )) { 417 ip_port )) {
407 /* if we can't replace bad nodes we try replacing good ones. */ 418 /* if we can't replace bad nodes we try replacing good ones. */
408 replace_good( friends_list[i].client_list, 419 replace_good( friends_list[i].client_list,
409 MAX_FRIEND_CLIENTS, 420 MAX_FRIEND_CLIENTS,
410 client_id, 421 client_id,
411 ip_port, 422 ip_port,
412 friends_list[i].client_id ); 423 friends_list[i].client_id );
413 } 424 }
414 } 425 }
@@ -418,7 +429,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
418/* If client_id is a friend or us, update ret_ip_port 429/* If client_id is a friend or us, update ret_ip_port
419 * nodeclient_id is the id of the node that sent us this info 430 * nodeclient_id is the id of the node that sent us this info
420 */ 431 */
421static void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) 432static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id)
422{ 433{
423 uint32_t i, j; 434 uint32_t i, j;
424 uint64_t temp_time = unix_time(); 435 uint64_t temp_time = unix_time();
@@ -458,17 +469,17 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
458 uint8_t pinging; 469 uint8_t pinging;
459 uint64_t temp_time = unix_time(); 470 uint64_t temp_time = unix_time();
460 471
461 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) { 472 for (i = 0; i < LSEND_NODES_ARRAY; ++i ) {
462 if(!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) { 473 if (!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) {
463 pinging = 0; 474 pinging = 0;
464 475
465 if(ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port)) 476 if (ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port))
466 ++pinging; 477 ++pinging;
467 478
468 if(ping_id != 0 && send_nodes[i].ping_id == ping_id) 479 if (ping_id != 0 && send_nodes[i].ping_id == ping_id)
469 ++pinging; 480 ++pinging;
470 481
471 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 482 if (pinging == (ping_id != 0) + (ip_port.ip.i != 0))
472 return 1; 483 return 1;
473 } 484 }
474 } 485 }
@@ -483,9 +494,9 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
483 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 494 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
484 uint64_t temp_time = unix_time(); 495 uint64_t temp_time = unix_time();
485 496
486 for(i = 0; i < PING_TIMEOUT; ++i ) { 497 for (i = 0; i < PING_TIMEOUT; ++i ) {
487 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) { 498 for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
488 if(is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) { 499 if (is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) {
489 send_nodes[j].timestamp = temp_time; 500 send_nodes[j].timestamp = temp_time;
490 send_nodes[j].ip_port = ip_port; 501 send_nodes[j].ip_port = ip_port;
491 send_nodes[j].ping_id = ping_id; 502 send_nodes[j].ping_id = ping_id;
@@ -498,15 +509,15 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
498} 509}
499 510
500/* send a getnodes request */ 511/* send a getnodes request */
501static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 512static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
502{ 513{
503 /* check if packet is gonna be sent to ourself */ 514 /* check if packet is gonna be sent to ourself */
504 if(id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0)) 515 if (id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0))
505 return 1; 516 return 1;
506 517
507 uint64_t ping_id = add_gettingnodes(ip_port); 518 uint64_t ping_id = add_gettingnodes(ip_port);
508 519
509 if(ping_id == 0) 520 if (ping_id == 0)
510 return 1; 521 return 1;
511 522
512 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 523 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
@@ -518,14 +529,14 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
518 memcpy(plain, &ping_id, sizeof(ping_id)); 529 memcpy(plain, &ping_id, sizeof(ping_id));
519 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 530 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
520 531
521 int len = encrypt_data( public_key, 532 int len = encrypt_data( public_key,
522 self_secret_key, 533 self_secret_key,
523 nonce, 534 nonce,
524 plain, 535 plain,
525 sizeof(ping_id) + CLIENT_ID_SIZE, 536 sizeof(ping_id) + CLIENT_ID_SIZE,
526 encrypt ); 537 encrypt );
527 538
528 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 539 if (len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
529 return -1; 540 return -1;
530 541
531 data[0] = 2; 542 data[0] = 2;
@@ -537,10 +548,10 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
537} 548}
538 549
539/* send a send nodes response */ 550/* send a send nodes response */
540static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 551static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id)
541{ 552{
542 /* check if packet is gonna be sent to ourself */ 553 /* check if packet is gonna be sent to ourself */
543 if(id_equal(public_key, self_public_key)) 554 if (id_equal(public_key, self_public_key))
544 return 1; 555 return 1;
545 556
546 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 557 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
@@ -549,7 +560,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
549 Node_format nodes_list[MAX_SENT_NODES]; 560 Node_format nodes_list[MAX_SENT_NODES];
550 int num_nodes = get_close_nodes(client_id, nodes_list); 561 int num_nodes = get_close_nodes(client_id, nodes_list);
551 562
552 if(num_nodes == 0) 563 if (num_nodes == 0)
553 return 0; 564 return 0;
554 565
555 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 566 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
@@ -560,14 +571,14 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
560 memcpy(plain, &ping_id, sizeof(ping_id)); 571 memcpy(plain, &ping_id, sizeof(ping_id));
561 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 572 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
562 573
563 int len = encrypt_data( public_key, 574 int len = encrypt_data( public_key,
564 self_secret_key, 575 self_secret_key,
565 nonce, 576 nonce,
566 plain, 577 plain,
567 sizeof(ping_id) + num_nodes * sizeof(Node_format), 578 sizeof(ping_id) + num_nodes * sizeof(Node_format),
568 encrypt ); 579 encrypt );
569 580
570 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 581 if (len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
571 return -1; 582 return -1;
572 583
573 data[0] = 3; 584 data[0] = 3;
@@ -578,11 +589,11 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
578 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 589 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
579} 590}
580 591
581static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length) 592static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length)
582{ 593{
583 uint64_t ping_id; 594 uint64_t ping_id;
584 595
585 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 596 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
586 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING )) 597 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING ))
587 return 1; 598 return 1;
588 599
@@ -592,11 +603,11 @@ static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length)
592 603
593 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 604 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
594 605
595 int len = decrypt_data( packet + 1, 606 int len = decrypt_data( packet + 1,
596 self_secret_key, 607 self_secret_key,
597 packet + 1 + CLIENT_ID_SIZE, 608 packet + 1 + CLIENT_ID_SIZE,
598 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 609 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
599 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, 610 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING,
600 plain ); 611 plain );
601 612
602 if (len != sizeof(ping_id) + CLIENT_ID_SIZE) 613 if (len != sizeof(ping_id) + CLIENT_ID_SIZE)
@@ -610,32 +621,33 @@ static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length)
610 return 0; 621 return 0;
611} 622}
612 623
613static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length) 624static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length)
614{ 625{
615 uint64_t ping_id; 626 uint64_t ping_id;
616 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 627 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
617 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 628 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
618 629
619 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) || 630 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) ||
620 ((length - cid_size) % sizeof(Node_format)) != 0 || 631 ((length - cid_size) % sizeof(Node_format)) != 0 ||
621 (length < cid_size + sizeof(Node_format))) 632 (length < cid_size + sizeof(Node_format)))
622 return 1; 633 return 1;
623 634
624 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format); 635 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format);
625 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 636 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
626 637
627 int len = decrypt_data( 638 int len = decrypt_data(
628 packet + 1, 639 packet + 1,
629 self_secret_key, 640 self_secret_key,
630 packet + 1 + CLIENT_ID_SIZE, 641 packet + 1 + CLIENT_ID_SIZE,
631 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 642 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
632 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); 643 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain );
633 644
634 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 645 if (len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
635 return 1; 646 return 1;
636 647
637 memcpy(&ping_id, plain, sizeof(ping_id)); 648 memcpy(&ping_id, plain, sizeof(ping_id));
638 if(!is_gettingnodes(source, ping_id)) 649
650 if (!is_gettingnodes(source, ping_id))
639 return 1; 651 return 1;
640 652
641 Node_format nodes_list[MAX_SENT_NODES]; 653 Node_format nodes_list[MAX_SENT_NODES];
@@ -644,8 +656,9 @@ static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length)
644 addto_lists(source, packet + 1); 656 addto_lists(source, packet + 1);
645 657
646 uint32_t i; 658 uint32_t i;
647 for(i = 0; i < num_nodes; ++i) { 659
648 send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id); 660 for (i = 0; i < num_nodes; ++i) {
661 send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id);
649 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 662 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
650 } 663 }
651 664
@@ -655,12 +668,14 @@ static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length)
655/*----------------------------------------------------------------------------------*/ 668/*----------------------------------------------------------------------------------*/
656/*------------------------END of packet handling functions--------------------------*/ 669/*------------------------END of packet handling functions--------------------------*/
657 670
658int DHT_addfriend(uint8_t * client_id) 671int DHT_addfriend(uint8_t *client_id)
659{ 672{
660 if(friend_number(client_id) != -1) /*Is friend already in DHT?*/ 673 if (friend_number(client_id) != -1) /*Is friend already in DHT?*/
661 return 1; 674 return 1;
662 Friend * temp; 675
676 Friend *temp;
663 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 677 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
678
664 if (temp == NULL) 679 if (temp == NULL)
665 return 1; 680 return 1;
666 681
@@ -673,22 +688,24 @@ int DHT_addfriend(uint8_t * client_id)
673 return 0; 688 return 0;
674} 689}
675 690
676int DHT_delfriend(uint8_t * client_id) 691int DHT_delfriend(uint8_t *client_id)
677{ 692{
678 uint32_t i; 693 uint32_t i;
679 Friend * temp; 694 Friend *temp;
695
680 for (i = 0; i < num_friends; ++i) { 696 for (i = 0; i < num_friends; ++i) {
681 /* Equal */ 697 /* Equal */
682 if (id_equal(friends_list[i].client_id, client_id)) { 698 if (id_equal(friends_list[i].client_id, client_id)) {
683 --num_friends; 699 --num_friends;
684 700
685 if (num_friends != i) { 701 if (num_friends != i) {
686 memcpy( friends_list[i].client_id, 702 memcpy( friends_list[i].client_id,
687 friends_list[num_friends].client_id, 703 friends_list[num_friends].client_id,
688 CLIENT_ID_SIZE ); 704 CLIENT_ID_SIZE );
689 } 705 }
690 706
691 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 707 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
708
692 if (temp == NULL) 709 if (temp == NULL)
693 return 1; 710 return 1;
694 711
@@ -701,7 +718,7 @@ int DHT_delfriend(uint8_t * client_id)
701} 718}
702 719
703/* TODO: Optimize this. */ 720/* TODO: Optimize this. */
704IP_Port DHT_getfriendip(uint8_t * client_id) 721IP_Port DHT_getfriendip(uint8_t *client_id)
705{ 722{
706 uint32_t i, j; 723 uint32_t i, j;
707 uint64_t temp_time = unix_time(); 724 uint64_t temp_time = unix_time();
@@ -711,18 +728,21 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
711 /* Equal */ 728 /* Equal */
712 if (id_equal(friends_list[i].client_id, client_id)) { 729 if (id_equal(friends_list[i].client_id, client_id)) {
713 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 730 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
714 if (id_equal(friends_list[i].client_list[j].client_id, client_id) && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) 731 if (id_equal(friends_list[i].client_list[j].client_id, client_id)
732 && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT))
715 return friends_list[i].client_list[j].ip_port; 733 return friends_list[i].client_list[j].ip_port;
716 } 734 }
735
717 return empty; 736 return empty;
718 } 737 }
719 } 738 }
739
720 empty.ip.i = 1; 740 empty.ip.i = 1;
721 return empty; 741 return empty;
722} 742}
723 743
724/* Ping each client in the "friends" list every 60 seconds. Send a get nodes request 744/* Ping each client in the "friends" list every 60 seconds. Send a get nodes request
725 * every 20 seconds to a random good node for each "friend" in our "friends" list. 745 * every 20 seconds to a random good node for each "friend" in our "friends" list.
726 */ 746 */
727static void doDHTFriends(void) 747static void doDHTFriends(void)
728{ 748{
@@ -733,22 +753,25 @@ static void doDHTFriends(void)
733 753
734 for (i = 0; i < num_friends; ++i) { 754 for (i = 0; i < num_friends; ++i) {
735 uint32_t num_nodes = 0; 755 uint32_t num_nodes = 0;
756
736 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 757 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
737 /* if node is not dead. */ 758 /* if node is not dead. */
738 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 759 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
739 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 760 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
740 send_ping_request( friends_list[i].client_list[j].ip_port, 761 send_ping_request( friends_list[i].client_list[j].ip_port,
741 (clientid_t*) &friends_list[i].client_list[j].client_id ); 762 (clientid_t *) &friends_list[i].client_list[j].client_id );
742 friends_list[i].client_list[j].last_pinged = temp_time; 763 friends_list[i].client_list[j].last_pinged = temp_time;
743 } 764 }
765
744 /* if node is good. */ 766 /* if node is good. */
745 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { 767 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) {
746 index[num_nodes] = j; 768 index[num_nodes] = j;
747 ++num_nodes; 769 ++num_nodes;
748 } 770 }
749 } 771 }
750 } 772 }
751 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 773
774 if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
752 rand_node = rand() % num_nodes; 775 rand_node = rand() % num_nodes;
753 getnodes( friends_list[i].client_list[index[rand_node]].ip_port, 776 getnodes( friends_list[i].client_list[index[rand_node]].ip_port,
754 friends_list[i].client_list[index[rand_node]].client_id, 777 friends_list[i].client_list[index[rand_node]].client_id,
@@ -775,10 +798,11 @@ static void doClose(void)
775 /* if node is not dead. */ 798 /* if node is not dead. */
776 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { 799 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
777 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 800 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
778 send_ping_request( close_clientlist[i].ip_port, 801 send_ping_request( close_clientlist[i].ip_port,
779 (clientid_t*) &close_clientlist[i].client_id ); 802 (clientid_t *) &close_clientlist[i].client_id );
780 close_clientlist[i].last_pinged = temp_time; 803 close_clientlist[i].last_pinged = temp_time;
781 } 804 }
805
782 /* if node is good. */ 806 /* if node is good. */
783 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { 807 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) {
784 index[num_nodes] = i; 808 index[num_nodes] = i;
@@ -796,15 +820,15 @@ static void doClose(void)
796 } 820 }
797} 821}
798 822
799void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) 823void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key)
800{ 824{
801 getnodes(ip_port, public_key, self_public_key); 825 getnodes(ip_port, public_key, self_public_key);
802} 826}
803 827
804/* send the given packet to node with client_id 828/* send the given packet to node with client_id
805 * returns -1 if failure 829 * returns -1 if failure
806 */ 830 */
807int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 831int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length)
808{ 832{
809 uint32_t i; 833 uint32_t i;
810 834
@@ -822,17 +846,17 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
822 * return 0 if we are connected to friend or if no ips were found. 846 * return 0 if we are connected to friend or if no ips were found.
823 * returns -1 if no such friend 847 * returns -1 if no such friend
824 */ 848 */
825static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) 849static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num)
826{ 850{
827 int num_ips = 0; 851 int num_ips = 0;
828 uint32_t i; 852 uint32_t i;
829 uint64_t temp_time = unix_time(); 853 uint64_t temp_time = unix_time();
830 854
831 if (friend_num >= num_friends) 855 if (friend_num >= num_friends)
832 return -1; 856 return -1;
833 857
834 Friend * friend = &friends_list[friend_num]; 858 Friend *friend = &friends_list[friend_num];
835 Client_data * client; 859 Client_data *client;
836 860
837 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 861 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
838 client = &friend->client_list[i]; 862 client = &friend->client_list[i];
@@ -847,22 +871,24 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
847 ++num_ips; 871 ++num_ips;
848 } 872 }
849 } 873 }
874
850 return num_ips; 875 return num_ips;
851} 876}
852 877
853/* Send the following packet to everyone who tells us they are connected to friend_id 878/* Send the following packet to everyone who tells us they are connected to friend_id
854 * returns the number of nodes it sent the packet to 879 * returns the number of nodes it sent the packet to
855 */ 880 */
856int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 881int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
857{ 882{
858 int num = friend_number(friend_id); 883 int num = friend_number(friend_id);
884
859 if (num == -1) 885 if (num == -1)
860 return 0; 886 return 0;
861 887
862 uint32_t i, sent = 0; 888 uint32_t i, sent = 0;
863 uint64_t temp_time = unix_time(); 889 uint64_t temp_time = unix_time();
864 Friend * friend = &friends_list[num]; 890 Friend *friend = &friends_list[num];
865 Client_data * client; 891 Client_data *client;
866 892
867 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 893 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
868 client = &friend->client_list[i]; 894 client = &friend->client_list[i];
@@ -874,20 +900,22 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
874 ++sent; 900 ++sent;
875 } 901 }
876 } 902 }
903
877 return sent; 904 return sent;
878} 905}
879 906
880/* Send the following packet to one random person who tells us they are connected to friend_id 907/* Send the following packet to one random person who tells us they are connected to friend_id
881* returns the number of nodes it sent the packet to 908* returns the number of nodes it sent the packet to
882*/ 909*/
883static int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 910static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
884{ 911{
885 int num = friend_number(friend_id); 912 int num = friend_number(friend_id);
913
886 if (num == -1) 914 if (num == -1)
887 return 0; 915 return 0;
888 916
889 Friend * friend = &friends_list[num]; 917 Friend *friend = &friends_list[num];
890 Client_data * client; 918 Client_data *client;
891 919
892 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 920 IP_Port ip_list[MAX_FRIEND_CLIENTS];
893 int n = 0; 921 int n = 0;
@@ -898,15 +926,18 @@ static int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t len
898 client = &friend->client_list[i]; 926 client = &friend->client_list[i];
899 927
900 /*If ip is not zero and node is good */ 928 /*If ip is not zero and node is good */
901 if(client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 929 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
902 ip_list[n] = client->ip_port; 930 ip_list[n] = client->ip_port;
903 ++n; 931 ++n;
904 } 932 }
905 } 933 }
934
906 if (n < 1) 935 if (n < 1)
907 return 0; 936 return 0;
937
908 if (sendpacket(ip_list[rand() % n], packet, length) == length) 938 if (sendpacket(ip_list[rand() % n], packet, length) == length)
909 return 1; 939 return 1;
940
910 return 0; 941 return 0;
911} 942}
912 943
@@ -916,21 +947,23 @@ static int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t len
916 * return 0 if we are connected to friend or if no ips were found. 947 * return 0 if we are connected to friend or if no ips were found.
917 * returns -1 if no such friend 948 * returns -1 if no such friend
918 */ 949 */
919int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) 950int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id)
920{ 951{
921 uint32_t i; 952 uint32_t i;
953
922 for (i = 0; i < num_friends; ++i) { 954 for (i = 0; i < num_friends; ++i) {
923 /* Equal */ 955 /* Equal */
924 if (id_equal(friends_list[i].client_id, friend_id)) 956 if (id_equal(friends_list[i].client_id, friend_id))
925 return friend_iplist(ip_portlist, i); 957 return friend_iplist(ip_portlist, i);
926 } 958 }
959
927 return -1; 960 return -1;
928} 961}
929 962
930/*----------------------------------------------------------------------------------*/ 963/*----------------------------------------------------------------------------------*/
931/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ 964/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/
932 965
933static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) 966static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type)
934{ 967{
935 uint8_t data[sizeof(uint64_t) + 1]; 968 uint8_t data[sizeof(uint64_t) + 1];
936 uint8_t packet[MAX_DATA_SIZE]; 969 uint8_t packet[MAX_DATA_SIZE];
@@ -952,20 +985,22 @@ static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
952 985
953 if (num == 0) 986 if (num == 0)
954 return -1; 987 return -1;
988
955 return num; 989 return num;
956} 990}
957 991
958/* Handle a received ping request for */ 992/* Handle a received ping request for */
959static int handle_NATping(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) 993static int handle_NATping(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
960{ 994{
961 uint64_t ping_id; 995 uint64_t ping_id;
962 memcpy(&ping_id, packet + 1, sizeof(uint64_t)); 996 memcpy(&ping_id, packet + 1, sizeof(uint64_t));
963 997
964 int friendnumber = friend_number(source_pubkey); 998 int friendnumber = friend_number(source_pubkey);
999
965 if (friendnumber == -1) 1000 if (friendnumber == -1)
966 return 1; 1001 return 1;
967 1002
968 Friend * friend = &friends_list[friendnumber]; 1003 Friend *friend = &friends_list[friendnumber];
969 1004
970 if (packet[0] == 0) { 1005 if (packet[0] == 0) {
971 /* 1 is reply */ 1006 /* 1 is reply */
@@ -979,31 +1014,35 @@ static int handle_NATping(IP_Port source, uint8_t * source_pubkey, uint8_t * pac
979 return 0; 1014 return 0;
980 } 1015 }
981 } 1016 }
1017
982 return 1; 1018 return 1;
983} 1019}
984 1020
985/* Get the most common ip in the ip_portlist 1021/* Get the most common ip in the ip_portlist
986 * Only return ip if it appears in list min_num or more 1022 * Only return ip if it appears in list min_num or more
987 * len must not be bigger than MAX_FRIEND_CLIENTS 1023 * len must not be bigger than MAX_FRIEND_CLIENTS
988 * return ip of 0 if failure 1024 * return ip of 0 if failure
989 */ 1025 */
990static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) 1026static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
991{ 1027{
992 IP zero = {{0}}; 1028 IP zero = {{0}};
993 if(len > MAX_FRIEND_CLIENTS) 1029
1030 if (len > MAX_FRIEND_CLIENTS)
994 return zero; 1031 return zero;
995 1032
996 uint32_t i, j; 1033 uint32_t i, j;
997 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; 1034 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
998 1035
999 for(i = 0; i < len; ++i) { 1036 for (i = 0; i < len; ++i) {
1000 for(j = 0; j < len; ++j) { 1037 for (j = 0; j < len; ++j) {
1001 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) 1038 if (ip_portlist[i].ip.i == ip_portlist[j].ip.i)
1002 ++numbers[i]; 1039 ++numbers[i];
1003 } 1040 }
1004 if(numbers[i] >= min_num) 1041
1042 if (numbers[i] >= min_num)
1005 return ip_portlist[i].ip; 1043 return ip_portlist[i].ip;
1006 } 1044 }
1045
1007 return zero; 1046 return zero;
1008} 1047}
1009 1048
@@ -1012,34 +1051,36 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
1012 * where len is the length of ip_portlist 1051 * where len is the length of ip_portlist
1013 * returns the number of ports and puts the list of ports in portlist 1052 * returns the number of ports and puts the list of ports in portlist
1014 */ 1053 */
1015static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip) 1054static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip)
1016{ 1055{
1017 uint32_t i; 1056 uint32_t i;
1018 uint16_t num = 0; 1057 uint16_t num = 0;
1019 1058
1020 for(i = 0; i < len; ++i) { 1059 for (i = 0; i < len; ++i) {
1021 if(ip_portlist[i].ip.i == ip.i) { 1060 if (ip_portlist[i].ip.i == ip.i) {
1022 portlist[num] = ntohs(ip_portlist[i].port); 1061 portlist[num] = ntohs(ip_portlist[i].port);
1023 ++num; 1062 ++num;
1024 } 1063 }
1025 } 1064 }
1065
1026 return num; 1066 return num;
1027} 1067}
1028 1068
1029static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) 1069static void punch_holes(IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num)
1030{ 1070{
1031 if(numports > MAX_FRIEND_CLIENTS || numports == 0) 1071 if (numports > MAX_FRIEND_CLIENTS || numports == 0)
1032 return; 1072 return;
1033 1073
1034 uint32_t i; 1074 uint32_t i;
1035 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1075 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1036 1076
1037 for(i = friends_list[friend_num].punching_index; i != top; i++) { 1077 for (i = friends_list[friend_num].punching_index; i != top; i++) {
1038 /*TODO: improve port guessing algorithm*/ 1078 /*TODO: improve port guessing algorithm*/
1039 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); 1079 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
1040 IP_Port pinging = {ip, htons(port)}; 1080 IP_Port pinging = {ip, htons(port)};
1041 send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id); 1081 send_ping_request(pinging, (clientid_t *) &friends_list[friend_num].client_id);
1042 } 1082 }
1083
1043 friends_list[friend_num].punching_index = i; 1084 friends_list[friend_num].punching_index = i;
1044} 1085}
1045 1086
@@ -1053,18 +1094,20 @@ static void doNAT(void)
1053 int num = friend_iplist(ip_list, i); 1094 int num = friend_iplist(ip_list, i);
1054 1095
1055 /*If already connected or friend is not online don't try to hole punch*/ 1096 /*If already connected or friend is not online don't try to hole punch*/
1056 if (num < MAX_FRIEND_CLIENTS/2) 1097 if (num < MAX_FRIEND_CLIENTS / 2)
1057 continue; 1098 continue;
1058 1099
1059 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { 1100 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1060 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 1101 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1061 friends_list[i].NATping_timestamp = temp_time; 1102 friends_list[i].NATping_timestamp = temp_time;
1062 } 1103 }
1104
1063 if (friends_list[i].hole_punching == 1 && 1105 if (friends_list[i].hole_punching == 1 &&
1064 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && 1106 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
1065 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) { 1107 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
1108
1109 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
1066 1110
1067 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1068 if (ip.i == 0) 1111 if (ip.i == 0)
1069 continue; 1112 continue;
1070 1113
@@ -1087,14 +1130,16 @@ static void doNAT(void)
1087 and are then removed from the list. 1130 and are then removed from the list.
1088 if the list is full the nodes farthest from our client_id are replaced 1131 if the list is full the nodes farthest from our client_id are replaced
1089 the purpose of this list is to enable quick integration of new nodes into the 1132 the purpose of this list is to enable quick integration of new nodes into the
1090 network while preventing amplification attacks. 1133 network while preventing amplification attacks.
1091 return 0 if node was added 1134 return 0 if node was added
1092 return -1 if node was not added */ 1135 return -1 if node was not added */
1093int add_toping(uint8_t *client_id, IP_Port ip_port) 1136int add_toping(uint8_t *client_id, IP_Port ip_port)
1094{ 1137{
1095 if (ip_port.ip.i == 0) 1138 if (ip_port.ip.i == 0)
1096 return -1; 1139 return -1;
1140
1097 uint32_t i; 1141 uint32_t i;
1142
1098 for (i = 0; i < MAX_TOPING; ++i) { 1143 for (i = 0; i < MAX_TOPING; ++i) {
1099 if (toping[i].ip_port.ip.i == 0) { 1144 if (toping[i].ip_port.ip.i == 0) {
1100 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); 1145 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE);
@@ -1103,6 +1148,7 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1103 return 0; 1148 return 0;
1104 } 1149 }
1105 } 1150 }
1151
1106 for (i = 0; i < MAX_TOPING; ++i) { 1152 for (i = 0; i < MAX_TOPING; ++i) {
1107 if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) { 1153 if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) {
1108 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); 1154 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE);
@@ -1111,6 +1157,7 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1111 return 0; 1157 return 0;
1112 } 1158 }
1113 } 1159 }
1160
1114 return -1; 1161 return -1;
1115} 1162}
1116 1163
@@ -1119,13 +1166,17 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1119static void do_toping() 1166static void do_toping()
1120{ 1167{
1121 uint64_t temp_time = unix_time(); 1168 uint64_t temp_time = unix_time();
1169
1122 if (!is_timeout(temp_time, last_toping, TIME_TOPING)) 1170 if (!is_timeout(temp_time, last_toping, TIME_TOPING))
1123 return; 1171 return;
1172
1124 last_toping = temp_time; 1173 last_toping = temp_time;
1125 uint32_t i; 1174 uint32_t i;
1175
1126 for (i = 0; i < MAX_TOPING; ++i) { 1176 for (i = 0; i < MAX_TOPING; ++i) {
1127 if (toping[i].ip_port.ip.i == 0) 1177 if (toping[i].ip_port.ip.i == 0)
1128 return; 1178 return;
1179
1129 send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id); 1180 send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id);
1130 toping[i].ip_port.ip.i = 0; 1181 toping[i].ip_port.ip.i = 0;
1131 } 1182 }
@@ -1156,7 +1207,7 @@ uint32_t DHT_size(void)
1156} 1207}
1157 1208
1158/* save the DHT in data where data is an array of size DHT_size() */ 1209/* save the DHT in data where data is an array of size DHT_size() */
1159void DHT_save(uint8_t * data) 1210void DHT_save(uint8_t *data)
1160{ 1211{
1161 memcpy(data, close_clientlist, sizeof(close_clientlist)); 1212 memcpy(data, close_clientlist, sizeof(close_clientlist));
1162 memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends); 1213 memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends);
@@ -1164,60 +1215,64 @@ void DHT_save(uint8_t * data)
1164 1215
1165/* load the DHT from data of size size; 1216/* load the DHT from data of size size;
1166 * return -1 if failure 1217 * return -1 if failure
1167 * return 0 if success 1218 * return 0 if success
1168 */ 1219 */
1169int DHT_load(uint8_t * data, uint32_t size) 1220int DHT_load(uint8_t *data, uint32_t size)
1170{ 1221{
1171 init_ping(); 1222 init_ping();
1172 1223
1173 if(size < sizeof(close_clientlist)) 1224 if (size < sizeof(close_clientlist))
1174 return -1; 1225 return -1;
1175 1226
1176 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1227 if ((size - sizeof(close_clientlist)) % sizeof(Friend) != 0)
1177 return -1; 1228 return -1;
1178 1229
1179 uint32_t i, j; 1230 uint32_t i, j;
1180 uint16_t temp; 1231 uint16_t temp;
1181 /* uint64_t temp_time = unix_time(); */ 1232 /* uint64_t temp_time = unix_time(); */
1182 1233
1183 Client_data * client; 1234 Client_data *client;
1184 1235
1185 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1236 temp = (size - sizeof(close_clientlist)) / sizeof(Friend);
1186 1237
1187 if(temp != 0) { 1238 if (temp != 0) {
1188 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1239 Friend *tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1189 1240
1190 for(i = 0; i < temp; ++i) { 1241 for (i = 0; i < temp; ++i) {
1191 DHT_addfriend(tempfriends_list[i].client_id); 1242 DHT_addfriend(tempfriends_list[i].client_id);
1192 1243
1193 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1244 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1194 client = &tempfriends_list[i].client_list[j]; 1245 client = &tempfriends_list[i].client_list[j];
1195 if(client->timestamp != 0) 1246
1247 if (client->timestamp != 0)
1196 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id); 1248 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id);
1197 } 1249 }
1198 } 1250 }
1199 } 1251 }
1200 Client_data * tempclose_clientlist = (Client_data *)data;
1201 1252
1202 for(i = 0; i < LCLIENT_LIST; ++i) { 1253 Client_data *tempclose_clientlist = (Client_data *)data;
1203 if(tempclose_clientlist[i].timestamp != 0) 1254
1204 DHT_bootstrap( tempclose_clientlist[i].ip_port, 1255 for (i = 0; i < LCLIENT_LIST; ++i) {
1256 if (tempclose_clientlist[i].timestamp != 0)
1257 DHT_bootstrap( tempclose_clientlist[i].ip_port,
1205 tempclose_clientlist[i].client_id ); 1258 tempclose_clientlist[i].client_id );
1206 } 1259 }
1260
1207 return 0; 1261 return 0;
1208} 1262}
1209 1263
1210/* returns 0 if we are not connected to the DHT 1264/* returns 0 if we are not connected to the DHT
1211 * returns 1 if we are 1265 * returns 1 if we are
1212 */ 1266 */
1213int DHT_isconnected(void) 1267int DHT_isconnected(void)
1214{ 1268{
1215 uint32_t i; 1269 uint32_t i;
1216 uint64_t temp_time = unix_time(); 1270 uint64_t temp_time = unix_time();
1217 1271
1218 for(i = 0; i < LCLIENT_LIST; ++i) { 1272 for (i = 0; i < LCLIENT_LIST; ++i) {
1219 if(!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) 1273 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT))
1220 return 1; 1274 return 1;
1221 } 1275 }
1276
1222 return 0; 1277 return 0;
1223} 1278}