summaryrefslogtreecommitdiff
path: root/core/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/DHT.c')
-rw-r--r--core/DHT.c782
1 files changed, 501 insertions, 281 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 272641ee..f779ef18 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -115,26 +115,34 @@ static Pinged send_nodes[LSEND_NODES_ARRAY];
115/*----------------------------------------------------------------------------------*/ 115/*----------------------------------------------------------------------------------*/
116 116
117/* Compares client_id1 and client_id2 with client_id 117/* Compares client_id1 and client_id2 with client_id
118 return 0 if both are same distance 118 * return 0 if both are same distance
119 return 1 if client_id1 is closer 119 * return 1 if client_id1 is closer
120 return 2 if client_id2 is closer */ 120 * return 2 if client_id2 is closer
121int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ 121 */
122int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2)
122{ 123{
123 uint32_t i; 124 uint32_t i;
125 uint8_t tmp1, tmp2;
126
124 for(i = 0; i < CLIENT_ID_SIZE; ++i) { 127 for(i = 0; i < CLIENT_ID_SIZE; ++i) {
125 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) 128 tmp1 = abs(client_id[i] ^ client_id1[i]);
129 tmp2 = abs(client_id[i] ^ client_id2[i]);
130
131 if(tmp1 < tmp2)
126 return 1; 132 return 1;
127 else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) 133 else if(tmp1 > tmp2)
128 return 2; 134 return 2;
129 } 135 }
130 return 0; 136 return 0;
131} 137}
132 138
133/* check if client with client_id is already in list of length length. 139/* check if client with client_id is already in list of length length.
134 if it is set it's corresponding timestamp to current time. 140 * if it is then set its corresponding timestamp to current time.
135 if the id is already in the list with a different ip_port, update it. 141 * if the id is already in the list with a different ip_port, update it.
136 return True(1) or False(0) 142 * return True(1) or False(0)
137 TODO: maybe optimize this. */ 143 *
144 * TODO: maybe optimize this.
145 */
138int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) 146int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port)
139{ 147{
140 uint32_t i; 148 uint32_t i;
@@ -156,83 +164,131 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
156 } 164 }
157 } 165 }
158 return 0; 166 return 0;
159
160} 167}
161 168
162/* check if client with client_id is already in node format list of length length. 169/* check if client with client_id is already in node format list of length length.
163 return True(1) or False(0) */ 170 * return True(1) or False(0)
171 */
164int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 172int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
165{ 173{
166 uint32_t i; 174 uint32_t i;
167 for(i = 0; i < length; ++i) 175 for(i = 0; i < length; ++i) {
168 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 176 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
169 return 1; 177 return 1;
178 }
170 return 0; 179 return 0;
171} 180}
172 181
173/*Return the friend number from the client_id 182/* Returns the friend number from the client_id, or -1 if a failure occurs
174 Return -1 if failure, number of friend if success*/ 183 */
175static int friend_number(uint8_t * client_id) 184static int friend_number(uint8_t * client_id)
176{ 185{
177 uint32_t i; 186 uint32_t i;
178 for(i = 0; i < num_friends; ++i) 187 for(i = 0; i < num_friends; ++i) {
179 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 188 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
180 return i; 189 return i;
190 }
181 return -1; 191 return -1;
182} 192}
183 193
184/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 194/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
185 put them in the nodes_list and return how many were found. 195 * put them in the nodes_list and return how many were found.
186 TODO: Make this function much more efficient. */ 196 *
197 * TODO: For the love of based Allah make this function cleaner and much more efficient.
198 */
187int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 199int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
188{ 200{
189 uint32_t i, j, k; 201 uint32_t i, j, k;
190 int num_nodes=0; 202 int64_t temp_time = unix_time();
191 int64_t temp_time = unix_time(); 203 int num_nodes = 0, closest, tout, inlist;
192 for(i = 0; i < LCLIENT_LIST; ++i) 204
193 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 205 for (i = 0; i < LCLIENT_LIST; ++i) {
194 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) { 206 tout = close_clientlist[i].timestamp <= temp_time - BAD_NODE_TIMEOUT;
195 /* if node is good and not already in list. */ 207 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id);
208
209 /* if node isn't good or is already in list. */
210 if(tout || inlist)
211 continue;
212
213 if(num_nodes < MAX_SENT_NODES) {
214
215 memcpy( nodes_list[num_nodes].client_id,
216 close_clientlist[i].client_id,
217 CLIENT_ID_SIZE );
218
219 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
220 num_nodes++;
221 } else {
222 for(j = 0; j < MAX_SENT_NODES; ++j) {
223 closest = id_closest( client_id,
224 nodes_list[j].client_id,
225 close_clientlist[i].client_id );
226 if(closest == 2) {
227 memcpy( nodes_list[j].client_id,
228 close_clientlist[i].client_id,
229 CLIENT_ID_SIZE);
230
231 nodes_list[j].ip_port = close_clientlist[i].ip_port;
232 break;
233 }
234 }
235 }
236 }
237
238 for(i = 0; i < num_friends; ++i) {
239 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
240 tout = friends_list[i].client_list[j].timestamp <= temp_time - BAD_NODE_TIMEOUT;
241 inlist = client_in_nodelist( nodes_list,
242 MAX_SENT_NODES,
243 friends_list[i].client_list[j].client_id);
244
245 /* if node isn't good or is already in list. */
246 if(tout || inlist)
247 continue;
248
196 if(num_nodes < MAX_SENT_NODES) { 249 if(num_nodes < MAX_SENT_NODES) {
197 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 250
198 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 251 memcpy( nodes_list[num_nodes].client_id,
252 friends_list[i].client_list[j].client_id,
253 CLIENT_ID_SIZE);
254
255 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
199 num_nodes++; 256 num_nodes++;
200 } else for(j = 0; j < MAX_SENT_NODES; ++j) 257 } else {
201 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) { 258 for(k = 0; k < MAX_SENT_NODES; ++k) {
202 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 259
203 nodes_list[j].ip_port = close_clientlist[i].ip_port; 260 closest = id_closest( client_id,
261 nodes_list[k].client_id,
262 friends_list[i].client_list[j].client_id );
263 if(closest == 2) {
264 memcpy( nodes_list[k].client_id,
265 friends_list[i].client_list[j].client_id,
266 CLIENT_ID_SIZE );
267
268 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
204 break; 269 break;
205 } 270 }
206 } 271 }
207
208 for(i = 0; i < num_friends; ++i)
209 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
210 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
211 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
212 /* if node is good and not already in list. */
213 if(num_nodes < MAX_SENT_NODES) {
214 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
215 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
216 num_nodes++;
217 } else for(k = 0; k < MAX_SENT_NODES; ++k)
218 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
219 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
220 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
221 break;
222 }
223 } 272 }
273 }
274 }
224 return num_nodes; 275 return num_nodes;
225} 276}
226 277
227/* replace first bad (or empty) node with this one 278/* replace first bad (or empty) node with this one
228 return 0 if successful 279 * return 0 if successful
229 return 1 if not (list contains no bad nodes) */ 280 * return 1 if not (list contains no bad nodes)
230int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */ 281 */
282int replace_bad( Client_data * list,
283 uint32_t length,
284 uint8_t * client_id,
285 IP_Port ip_port )
231{ 286{
232 uint32_t i; 287 uint32_t i;
233 int64_t temp_time = unix_time(); 288 int64_t temp_time = unix_time();
234 for(i = 0; i < length; ++i) 289 for(i = 0; i < length; ++i) {
235 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { /* if node is bad. */ 290 /* if node is bad */
291 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) {
236 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 292 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
237 list[i].ip_port = ip_port; 293 list[i].ip_port = ip_port;
238 list[i].timestamp = temp_time; 294 list[i].timestamp = temp_time;
@@ -241,12 +297,17 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
241 list[i].ret_timestamp = 0; 297 list[i].ret_timestamp = 0;
242 return 0; 298 return 0;
243 } 299 }
300 }
244 301
245 return 1; 302 return 1;
246} 303}
247 304
248/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ 305/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */
249int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port, uint8_t * comp_client_id) 306int replace_good( Client_data * list,
307 uint32_t length,
308 uint8_t * client_id,
309 IP_Port ip_port,
310 uint8_t * comp_client_id )
250{ 311{
251 uint32_t i; 312 uint32_t i;
252 int64_t temp_time = unix_time(); 313 int64_t temp_time = unix_time();
@@ -265,72 +326,111 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
265 return 1; 326 return 1;
266} 327}
267 328
268/* Attempt to add client with ip_port and client_id to the friends client list and close_clientlist */ 329/* Attempt to add client with ip_port and client_id to the friends client list
330 * and close_clientlist
331 */
269void addto_lists(IP_Port ip_port, uint8_t * client_id) 332void addto_lists(IP_Port ip_port, uint8_t * client_id)
270{ 333{
271 uint32_t i; 334 uint32_t i;
272 335
273 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ 336 /* NOTE: current behavior if there are two clients with the same id is
274 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 337 * to replace the first ip by the second.
275 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 338 */
339 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
340 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
276 /* if we can't replace bad nodes we try replacing good ones */ 341 /* if we can't replace bad nodes we try replacing good ones */
277 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); 342 replace_good( close_clientlist,
343 LCLIENT_LIST,
344 client_id,
345 ip_port,
346 self_public_key );
347 }
348 }
278 349
279 for(i = 0; i < num_friends; ++i) 350 for (i = 0; i < num_friends; ++i) {
280 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 351 if (!client_in_list( friends_list[i].client_list,
281 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 352 MAX_FRIEND_CLIENTS,
353 client_id,
354 ip_port )) {
355
356 if (replace_bad( friends_list[i].client_list,
357 MAX_FRIEND_CLIENTS,
358 client_id,
359 ip_port )) {
282 /* if we can't replace bad nodes we try replacing good ones. */ 360 /* if we can't replace bad nodes we try replacing good ones. */
283 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); 361 replace_good( friends_list[i].client_list,
362 MAX_FRIEND_CLIENTS,
363 client_id,
364 ip_port,
365 friends_list[i].client_id );
366 }
367 }
368 }
284} 369}
285 370
286/* If client_id is a friend or us, update ret_ip_port 371/* If client_id is a friend or us, update ret_ip_port
287 nodeclient_id is the id of the node that sent us this info */ 372 * nodeclient_id is the id of the node that sent us this info
373 */
288void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) 374void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
289{ 375{
290 uint32_t i, j; 376 uint32_t i, j;
291 int64_t temp_time = unix_time(); 377 int64_t temp_time = unix_time();
292 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { 378
293 for(i = 0; i < LCLIENT_LIST; ++i) 379 if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
294 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) { 380 for (i = 0; i < LCLIENT_LIST; ++i) {
381
382 if (memcmp( nodeclient_id,
383 close_clientlist[i].client_id,
384 CLIENT_ID_SIZE ) == 0) {
295 close_clientlist[i].ret_ip_port = ip_port; 385 close_clientlist[i].ret_ip_port = ip_port;
296 close_clientlist[i].ret_timestamp = temp_time; 386 close_clientlist[i].ret_timestamp = temp_time;
297 return; 387 return;
298 } 388 }
299 } else 389 }
300 for(i = 0; i < num_friends; ++i) 390 } else {
301 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) 391 for (i = 0; i < num_friends; ++i) {
302 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 392 if (memcmp( client_id,
303 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) { 393 friends_list[i].client_id,
394 CLIENT_ID_SIZE ) == 0) {
395 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
396
397 if (memcmp( nodeclient_id,
398 friends_list[i].client_list[j].client_id,
399 CLIENT_ID_SIZE ) == 0) {
304 friends_list[i].client_list[j].ret_ip_port = ip_port; 400 friends_list[i].client_list[j].ret_ip_port = ip_port;
305 friends_list[i].client_list[j].ret_timestamp = temp_time; 401 friends_list[i].client_list[j].ret_timestamp = temp_time;
306 return; 402 return;
307 } 403 }
404 }
405 }
406 }
407 }
308} 408}
309 409
310/* check if we are currently pinging an ip_port and/or a ping_id 410/* check if we are currently pinging an ip_port and/or a ping_id variables with
311 variables with values of zero will not be checked. 411 * values of zero will not be checked. If we are already, return 1 else return 0
312 if we are already, return 1 412 *
313 else return 0 413 * TODO: optimize this
314TODO: optimize this */ 414 */
315int is_pinging(IP_Port ip_port, uint64_t ping_id) 415int is_pinging(IP_Port ip_port, uint64_t ping_id)
316{ 416{
317 uint32_t i; 417 uint32_t i;
318 uint8_t pinging; 418 uint8_t pinging;
319 int64_t temp_time = unix_time(); 419 int64_t temp_time = unix_time();
320 420
321 for(i = 0; i < LPING_ARRAY; ++i ) 421 for (i = 0; i < LPING_ARRAY; ++i ) {
322 if((pings[i].timestamp + PING_TIMEOUT) > temp_time) { 422 if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
323 pinging = 0; 423 pinging = 0;
324 if(ip_port.ip.i != 0) 424 if (ip_port.ip.i != 0 &&
325 if(pings[i].ip_port.ip.i == ip_port.ip.i && 425 pings[i].ip_port.ip.i == ip_port.ip.i &&
326 pings[i].ip_port.port == ip_port.port) 426 pings[i].ip_port.port == ip_port.port)
327 ++pinging; 427 ++pinging;
328 if(ping_id != 0) 428 if (ping_id != 0 && pings[i].ping_id == ping_id)
329 if(pings[i].ping_id == ping_id) 429 ++pinging;
330 ++pinging; 430 if (pinging == ((ping_id != 0) + (ip_port.ip.i != 0)))
331 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
332 return 1; 431 return 1;
333 } 432 }
433 }
334 434
335 return 0; 435 return 0;
336} 436}
@@ -342,42 +442,46 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
342 uint8_t pinging; 442 uint8_t pinging;
343 int64_t temp_time = unix_time(); 443 int64_t temp_time = unix_time();
344 444
345 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) 445 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
346 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { 446 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
347 pinging = 0; 447 pinging = 0;
348 if(ip_port.ip.i != 0) 448 if(ip_port.ip.i != 0 &&
349 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && 449 send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
350 send_nodes[i].ip_port.port == ip_port.port) 450 send_nodes[i].ip_port.port == ip_port.port)
351 ++pinging; 451 ++pinging;
352 if(ping_id != 0) 452 if(ping_id != 0 && send_nodes[i].ping_id == ping_id)
353 if(send_nodes[i].ping_id == ping_id)
354 ++pinging; 453 ++pinging;
355 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 454 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0))
356 return 1; 455 return 1;
357
358 } 456 }
457 }
359 458
360 return 0; 459 return 0;
361} 460}
362 461
363/* Add a new ping request to the list of ping requests 462/* Add a new ping request to the list of ping requests
364 returns the ping_id to put in the ping request 463 * returns the ping_id to put in the ping request
365 returns 0 if problem. 464 * returns 0 if problem.
366 TODO: optimize this */ 465 *
466 * TODO: optimize this
467 */
367uint64_t add_pinging(IP_Port ip_port) 468uint64_t add_pinging(IP_Port ip_port)
368{ 469{
369 uint32_t i, j; 470 uint32_t i, j;
370 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 471 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
371 int64_t temp_time = unix_time(); 472 int64_t temp_time = unix_time();
372 473
373 for(i = 0; i < PING_TIMEOUT; ++i ) 474
374 for(j = 0; j < LPING_ARRAY; ++j ) 475 for(i = 0; i < PING_TIMEOUT; ++i ) {
476 for(j = 0; j < LPING_ARRAY; ++j ) {
375 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) { 477 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
376 pings[j].timestamp = temp_time; 478 pings[j].timestamp = temp_time;
377 pings[j].ip_port = ip_port; 479 pings[j].ip_port = ip_port;
378 pings[j].ping_id = ping_id; 480 pings[j].ping_id = ping_id;
379 return ping_id; 481 return ping_id;
380 } 482 }
483 }
484 }
381 485
382 return 0; 486 return 0;
383} 487}
@@ -389,26 +493,28 @@ uint64_t add_gettingnodes(IP_Port ip_port)
389 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 493 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
390 int64_t temp_time = unix_time(); 494 int64_t temp_time = unix_time();
391 495
392 for(i = 0; i < PING_TIMEOUT; ++i ) 496 for(i = 0; i < PING_TIMEOUT; ++i ) {
393 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) 497 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
394 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) { 498 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
395 send_nodes[j].timestamp = temp_time; 499 send_nodes[j].timestamp = temp_time;
396 send_nodes[j].ip_port = ip_port; 500 send_nodes[j].ip_port = ip_port;
397 send_nodes[j].ping_id = ping_id; 501 send_nodes[j].ping_id = ping_id;
398 return ping_id; 502 return ping_id;
399 } 503 }
504 }
505 }
400 506
401 return 0; 507 return 0;
402} 508}
403 509
404/* send a ping request 510/* send a ping request, only works if none has been sent to that ip/port
405 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ 511 * in the last 5 seconds.
512 */
406static int pingreq(IP_Port ip_port, uint8_t * public_key) 513static int pingreq(IP_Port ip_port, uint8_t * public_key)
407{ 514{
408 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 515 /* check if packet is gonna be sent to ourself */
409 return 1; 516 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0
410 517 || is_pinging(ip_port, 0))
411 if(is_pinging(ip_port, 0))
412 return 1; 518 return 1;
413 519
414 uint64_t ping_id = add_pinging(ip_port); 520 uint64_t ping_id = add_pinging(ip_port);
@@ -420,9 +526,16 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
420 uint8_t nonce[crypto_box_NONCEBYTES]; 526 uint8_t nonce[crypto_box_NONCEBYTES];
421 random_nonce(nonce); 527 random_nonce(nonce);
422 528
423 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 529 int len = encrypt_data( public_key,
530 self_secret_key,
531 nonce,
532 (uint8_t *)&ping_id,
533 sizeof(ping_id),
534 encrypt );
535
424 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 536 if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
425 return -1; 537 return -1;
538
426 data[0] = 0; 539 data[0] = 0;
427 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 540 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
428 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 541 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
@@ -443,9 +556,15 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
443 uint8_t nonce[crypto_box_NONCEBYTES]; 556 uint8_t nonce[crypto_box_NONCEBYTES];
444 random_nonce(nonce); 557 random_nonce(nonce);
445 558
446 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 559 int len = encrypt_data( public_key,
560 self_secret_key, nonce,
561 (uint8_t *)&ping_id,
562 sizeof(ping_id),
563 encrypt );
564
447 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 565 if(len != sizeof(ping_id) + ENCRYPTION_PADDING)
448 return -1; 566 return -1;
567
449 data[0] = 1; 568 data[0] = 1;
450 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 569 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
451 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 570 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
@@ -458,10 +577,8 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
458static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 577static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
459{ 578{
460 /* check if packet is gonna be sent to ourself */ 579 /* check if packet is gonna be sent to ourself */
461 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) 580 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0
462 return 1; 581 || is_gettingnodes(ip_port, 0))
463
464 if(is_gettingnodes(ip_port, 0))
465 return 1; 582 return 1;
466 583
467 uint64_t ping_id = add_gettingnodes(ip_port); 584 uint64_t ping_id = add_gettingnodes(ip_port);
@@ -478,21 +595,29 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
478 memcpy(plain, &ping_id, sizeof(ping_id)); 595 memcpy(plain, &ping_id, sizeof(ping_id));
479 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 596 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
480 597
481 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); 598 int len = encrypt_data( public_key,
599 self_secret_key,
600 nonce,
601 plain,
602 sizeof(ping_id) + CLIENT_ID_SIZE,
603 encrypt );
482 604
483 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 605 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
484 return -1; 606 return -1;
607
485 data[0] = 2; 608 data[0] = 2;
486 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE); 609 memcpy(data + 1, self_public_key, CLIENT_ID_SIZE);
487 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 610 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
488 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 611 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
612
489 return sendpacket(ip_port, data, sizeof(data)); 613 return sendpacket(ip_port, data, sizeof(data));
490} 614}
491 615
492/* send a send nodes response */ 616/* send a send nodes response */
493static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 617static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
494{ 618{
495 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 619 /* check if packet is gonna be sent to ourself */
620 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0)
496 return 1; 621 return 1;
497 622
498 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 623 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
@@ -512,8 +637,12 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
512 memcpy(plain, &ping_id, sizeof(ping_id)); 637 memcpy(plain, &ping_id, sizeof(ping_id));
513 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 638 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
514 639
515 int len = encrypt_data(public_key, self_secret_key, nonce, plain, 640 int len = encrypt_data( public_key,
516 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); 641 self_secret_key,
642 nonce,
643 plain,
644 sizeof(ping_id) + num_nodes * sizeof(Node_format),
645 encrypt );
517 646
518 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 647 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
519 return -1; 648 return -1;
@@ -526,26 +655,30 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
526 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 655 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
527} 656}
528 657
529/* Packet handling functions 658/* Packet handling functions, one to handle each types of packets we receive
530 One to handle each types of packets we receive 659 * Returns 0 if handled correctly, 1 if packet is bad.
531 return 0 if handled correctly, 1 if packet is bad. */ 660 */
532int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) 661int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
533{ 662{
534 uint64_t ping_id; 663 uint64_t ping_id;
535 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 664 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
536 return 1; 665 return 1;
666
537 /* check if packet is from ourself. */ 667 /* check if packet is from ourself. */
538 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 668 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
539 return 1; 669 return 1;
540 670
541 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 671 int len = decrypt_data( packet + 1,
542 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 672 self_secret_key,
543 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 673 packet + 1 + CLIENT_ID_SIZE,
674 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
675 sizeof(ping_id) + ENCRYPTION_PADDING,
676 (uint8_t *)&ping_id );
677
544 if(len != sizeof(ping_id)) 678 if(len != sizeof(ping_id))
545 return 1; 679 return 1;
546 680
547 pingres(source, packet + 1, ping_id); 681 pingres(source, packet + 1, ping_id);
548
549 pingreq(source, packet + 1); /* TODO: make this smarter? */ 682 pingreq(source, packet + 1); /* TODO: make this smarter? */
550 683
551 return 0; 684 return 0;
@@ -556,12 +689,18 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
556 uint64_t ping_id; 689 uint64_t ping_id;
557 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 690 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING)
558 return 1; 691 return 1;
559 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 692
693 /* check if packet is from ourself. */
694 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
560 return 1; 695 return 1;
561 696
562 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 697 int len = decrypt_data( packet + 1,
563 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 698 self_secret_key,
564 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 699 packet + 1 + CLIENT_ID_SIZE,
700 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
701 sizeof(ping_id) + ENCRYPTION_PADDING,
702 (uint8_t *)&ping_id );
703
565 if(len != sizeof(ping_id)) 704 if(len != sizeof(ping_id))
566 return 1; 705 return 1;
567 706
@@ -570,25 +709,30 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
570 return 0; 709 return 0;
571 } 710 }
572 return 1; 711 return 1;
573
574} 712}
575 713
576int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 714int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
577{ 715{
578 uint64_t ping_id; 716 uint64_t ping_id;
579 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 717
718 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
719 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING ))
580 return 1; 720 return 1;
721
581 /* check if packet is from ourself. */ 722 /* check if packet is from ourself. */
582 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) 723 if (memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0)
583 return 1; 724 return 1;
584 725
585 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 726 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
586 727
587 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 728 int len = decrypt_data( packet + 1,
588 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 729 self_secret_key,
589 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); 730 packet + 1 + CLIENT_ID_SIZE,
731 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
732 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING,
733 plain );
590 734
591 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) 735 if (len != sizeof(ping_id) + CLIENT_ID_SIZE)
592 return 1; 736 return 1;
593 737
594 memcpy(&ping_id, plain, sizeof(ping_id)); 738 memcpy(&ping_id, plain, sizeof(ping_id));
@@ -597,29 +741,28 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
597 pingreq(source, packet + 1); /* TODO: make this smarter? */ 741 pingreq(source, packet + 1); /* TODO: make this smarter? */
598 742
599 return 0; 743 return 0;
600
601} 744}
602 745
603int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) 746int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
604{ 747{
605 uint64_t ping_id; 748 uint64_t ping_id;
606 /* TODO: make this more readable */ 749 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
607 if(length > (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 750 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
608 + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING) || 751
609 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 752 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) ||
610 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || 753 ((length - cid_size) % sizeof(Node_format)) != 0 ||
611 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 754 (length < cid_size + sizeof(Node_format)))
612 + sizeof(Node_format) + ENCRYPTION_PADDING) {
613 return 1; 755 return 1;
614 }
615 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
616 + sizeof(ping_id) + ENCRYPTION_PADDING)) / sizeof(Node_format);
617 756
757 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format);
618 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 758 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
619 759
620 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 760 int len = decrypt_data(
621 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 761 packet + 1,
622 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); 762 self_secret_key,
763 packet + 1 + CLIENT_ID_SIZE,
764 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
765 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain );
623 766
624 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 767 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
625 return 1; 768 return 1;
@@ -649,12 +792,13 @@ int DHT_addfriend(uint8_t * client_id)
649{ 792{
650 Friend * temp; 793 Friend * temp;
651 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 794 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
652 if(temp == NULL) 795 if (temp == NULL)
653 return 1; 796 return 1;
654 797
655 friends_list = temp; 798 friends_list = temp;
656 memset(&friends_list[num_friends], 0, sizeof(Friend)); 799 memset(&friends_list[num_friends], 0, sizeof(Friend));
657 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); 800 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE);
801
658 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 802 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
659 ++num_friends; 803 ++num_friends;
660 return 0; 804 return 0;
@@ -664,17 +808,21 @@ int DHT_delfriend(uint8_t * client_id)
664{ 808{
665 uint32_t i; 809 uint32_t i;
666 Friend * temp; 810 Friend * temp;
667 for(i = 0; i < num_friends; ++i) 811 for (i = 0; i < num_friends; ++i) {
668 /* Equal */ 812 /* Equal */
669 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 813 if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
670 --num_friends; 814 --num_friends;
671 if(num_friends != i) 815 if (num_friends != i) {
672 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); 816 memcpy( friends_list[i].client_id,
817 friends_list[num_friends].client_id,
818 CLIENT_ID_SIZE );
819 }
673 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 820 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
674 if(temp != NULL) 821 if (temp != NULL)
675 friends_list = temp; 822 friends_list = temp;
676 return 0; 823 return 0;
677 } 824 }
825 }
678 826
679 return 1; 827 return 1;
680} 828}
@@ -683,25 +831,29 @@ int DHT_delfriend(uint8_t * client_id)
683IP_Port DHT_getfriendip(uint8_t * client_id) 831IP_Port DHT_getfriendip(uint8_t * client_id)
684{ 832{
685 uint32_t i, j; 833 uint32_t i, j;
686 IP_Port empty = {{{0}}, 0};
687 int64_t temp_time = unix_time(); 834 int64_t temp_time = unix_time();
688 for(i = 0; i < num_friends; ++i) 835 IP_Port empty = {{{0}}, 0};
836
837 for (i = 0; i < num_friends; ++i) {
689 /* Equal */ 838 /* Equal */
690 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) { 839 if (memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
691 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 840 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
692 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && 841 if (memcmp( friends_list[i].client_list[j].client_id,
842 client_id,
843 CLIENT_ID_SIZE ) == 0 &&
693 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) 844 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time)
694 return friends_list[i].client_list[j].ip_port; 845 return friends_list[i].client_list[j].ip_port;
695 846 }
696 return empty; 847 return empty;
697 } 848 }
849 }
698 empty.ip.i = 1; 850 empty.ip.i = 1;
699 return empty; 851 return empty;
700
701} 852}
702 853
703/* Ping each client in the "friends" list every 60 seconds. 854/* Ping each client in the "friends" list every 60 seconds. Send a get nodes request
704 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ 855 * every 20 seconds to a random good node for each "friend" in our "friends" list.
856 */
705void doDHTFriends() 857void doDHTFriends()
706{ 858{
707 uint32_t i, j; 859 uint32_t i, j;
@@ -709,24 +861,28 @@ void doDHTFriends()
709 uint32_t rand_node; 861 uint32_t rand_node;
710 uint32_t index[MAX_FRIEND_CLIENTS]; 862 uint32_t index[MAX_FRIEND_CLIENTS];
711 863
712 for(i = 0; i < num_friends; ++i) { 864 for (i = 0; i < num_friends; ++i) {
713 uint32_t num_nodes = 0; 865 uint32_t num_nodes = 0;
714 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 866 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
715 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) { /* if node is not dead. */ 867 /* if node is not dead. */
716 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 868 if (friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) {
717 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); 869 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
870 pingreq( friends_list[i].client_list[j].ip_port,
871 friends_list[i].client_list[j].client_id );
718 friends_list[i].client_list[j].last_pinged = temp_time; 872 friends_list[i].client_list[j].last_pinged = temp_time;
719 } 873 }
720 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) { /* if node is good. */ 874 /* if node is good. */
875 if (friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) {
721 index[num_nodes] = j; 876 index[num_nodes] = j;
722 ++num_nodes; 877 ++num_nodes;
723 } 878 }
724 } 879 }
880 }
725 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 881 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
726 rand_node = rand() % num_nodes; 882 rand_node = rand() % num_nodes;
727 getnodes(friends_list[i].client_list[index[rand_node]].ip_port, 883 getnodes( friends_list[i].client_list[index[rand_node]].ip_port,
728 friends_list[i].client_list[index[rand_node]].client_id, 884 friends_list[i].client_list[index[rand_node]].client_id,
729 friends_list[i].client_id); 885 friends_list[i].client_id );
730 friends_list[i].lastgetnode = temp_time; 886 friends_list[i].lastgetnode = temp_time;
731 } 887 }
732 } 888 }
@@ -735,8 +891,9 @@ void doDHTFriends()
735static uint32_t close_lastgetnodes; 891static uint32_t close_lastgetnodes;
736 892
737/* Ping each client in the close nodes list every 60 seconds. 893/* Ping each client in the close nodes list every 60 seconds.
738 Send a get nodes request every 20 seconds to a random good node in the list. */ 894 * Send a get nodes request every 20 seconds to a random good node in the list.
739void doClose() /* tested */ 895 */
896void doClose()
740{ 897{
741 uint32_t i; 898 uint32_t i;
742 int64_t temp_time = unix_time(); 899 int64_t temp_time = unix_time();
@@ -744,25 +901,27 @@ void doClose() /* tested */
744 uint32_t rand_node; 901 uint32_t rand_node;
745 uint32_t index[LCLIENT_LIST]; 902 uint32_t index[LCLIENT_LIST];
746 903
747 for(i = 0; i < LCLIENT_LIST; ++i) 904 for (i = 0; i < LCLIENT_LIST; ++i) {
748 /* if node is not dead. */ 905 /* if node is not dead. */
749 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) { 906 if (close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
750 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 907 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
751 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); 908 pingreq( close_clientlist[i].ip_port,
909 close_clientlist[i].client_id );
752 close_clientlist[i].last_pinged = temp_time; 910 close_clientlist[i].last_pinged = temp_time;
753 } 911 }
754 /* if node is good. */ 912 /* if node is good. */
755 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) { 913 if (close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
756 index[num_nodes] = i; 914 index[num_nodes] = i;
757 ++num_nodes; 915 ++num_nodes;
758 } 916 }
759 } 917 }
918 }
760 919
761 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 920 if (close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
762 rand_node = rand() % num_nodes; 921 rand_node = rand() % num_nodes;
763 getnodes(close_clientlist[index[rand_node]].ip_port, 922 getnodes( close_clientlist[index[rand_node]].ip_port,
764 close_clientlist[index[rand_node]].client_id, 923 close_clientlist[index[rand_node]].client_id,
765 self_public_key); 924 self_public_key );
766 close_lastgetnodes = temp_time; 925 close_lastgetnodes = temp_time;
767 } 926 }
768} 927}
@@ -773,100 +932,129 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
773} 932}
774 933
775/* send the given packet to node with client_id 934/* send the given packet to node with client_id
776 returns -1 if failure */ 935 * returns -1 if failure
936 */
777int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 937int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
778{ 938{
779 uint32_t i; 939 uint32_t i;
780 for(i = 0; i < LCLIENT_LIST; ++i) 940 for (i = 0; i < LCLIENT_LIST; ++i) {
781 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) 941 if (memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
782 return sendpacket(close_clientlist[i].ip_port, packet, length); 942 return sendpacket(close_clientlist[i].ip_port, packet, length);
943 }
783 return -1; 944 return -1;
784} 945}
785 946
786/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist 947/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
787 ip_portlist must be at least MAX_FRIEND_CLIENTS big 948 * ip_portlist must be at least MAX_FRIEND_CLIENTS big
788 returns the number of ips returned 949 * returns the number of ips returned
789 return 0 if we are connected to friend or if no ips were found. 950 * return 0 if we are connected to friend or if no ips were found.
790 returns -1 if no such friend*/ 951 * returns -1 if no such friend
952 */
791static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) 953static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
792{ 954{
793 int num_ips = 0; 955 int num_ips = 0;
794 uint32_t i; 956 uint32_t i;
795 int64_t temp_time = unix_time(); 957 int64_t temp_time = unix_time();
796 if(friend_num >= num_friends) 958
959 if (friend_num >= num_friends)
797 return -1; 960 return -1;
798 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 961
962 Friend * friend = &friends_list[friend_num];
963 Client_data * client;
964
965 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
966 client = &friend->client_list[i];
967
799 /*If ip is not zero and node is good */ 968 /*If ip is not zero and node is good */
800 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 && 969 if (client->ret_ip_port.ip.i != 0 &&
801 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { 970 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
802 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) 971
972 if (memcmp(client->client_id, friend->client_id, CLIENT_ID_SIZE) == 0)
803 return 0; 973 return 0;
804 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port; 974
975 ip_portlist[num_ips] = client->ret_ip_port;
805 ++num_ips; 976 ++num_ips;
806 } 977 }
978 }
807 return num_ips; 979 return num_ips;
808} 980}
809 981
810/* Send the following packet to everyone who tells us they are connected to friend_id 982/* Send the following packet to everyone who tells us they are connected to friend_id
811 returns the number of nodes it sent the packet to */ 983 * returns the number of nodes it sent the packet to
984 */
812int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 985int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
813{ 986{
814 uint32_t i, j; 987 int num = friend_number(friend_id);
815 uint32_t sent = 0; 988 if (num == -1)
989 return 0;
990
991 uint32_t i, sent = 0;
816 int64_t temp_time = unix_time(); 992 int64_t temp_time = unix_time();
817 for(i = 0; i < num_friends; ++i) 993 Friend * friend = &friends_list[num];
818 /* Equal */ 994 Client_data * client;
819 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) { 995
820 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 996 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
821 /*If ip is not zero and node is good */ 997 client = &friend->client_list[i];
822 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 998
823 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 999 /*If ip is not zero and node is good */
824 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) 1000 if (client->ret_ip_port.ip.i != 0 &&
825 ++sent; 1001 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
826 return sent; 1002
1003 if (sendpacket(client->ip_port, packet, length) == length)
1004 ++sent;
827 } 1005 }
828 return 0; 1006 }
1007 return sent;
829} 1008}
830 1009
831/* Send the following packet to one random person who tells us they are connected to friend_id 1010/* Send the following packet to one random person who tells us they are connected to friend_id
832 returns the number of nodes it sent the packet to */ 1011* returns the number of nodes it sent the packet to
1012*/
833int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 1013int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
834{ 1014{
835 int num = friend_number(friend_id); 1015 int num = friend_number(friend_id);
836 if(num == -1) 1016 if (num == -1)
837 return 0; 1017 return 0;
838 1018
1019 Friend * friend = &friends_list[num];
1020 Client_data * client;
1021
839 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1022 IP_Port ip_list[MAX_FRIEND_CLIENTS];
840 int n = 0; 1023 int n = 0;
841 uint32_t i; 1024 uint32_t i, temp_time = unix_time();
842 int64_t temp_time = unix_time(); 1025 int64_t temp_time = unix_time();
843 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) 1026
1027 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1028 client = &friend->client_list[i];
1029
844 /*If ip is not zero and node is good */ 1030 /*If ip is not zero and node is good */
845 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 && 1031 if(client->ret_ip_port.ip.i != 0 &&
846 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) { 1032 client->ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
847 ip_list[n] = friends_list[num].client_list[i].ip_port; 1033 ip_list[n] = client->ip_port;
848 ++n; 1034 ++n;
849 } 1035 }
850 if(n < 1) 1036 }
1037 if (n < 1)
851 return 0; 1038 return 0;
852 if(sendpacket(ip_list[rand() % n], packet, length) == length) 1039 if (sendpacket(ip_list[rand() % n], packet, length) == length)
853 return 1; 1040 return 1;
854 return 0; 1041 return 0;
855} 1042}
856 1043
857/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 1044/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
858 ip_portlist must be at least MAX_FRIEND_CLIENTS big 1045 * ip_portlist must be at least MAX_FRIEND_CLIENTS big
859 returns the number of ips returned 1046 * returns the number of ips returned
860 return 0 if we are connected to friend or if no ips were found. 1047 * return 0 if we are connected to friend or if no ips were found.
861 returns -1 if no such friend*/ 1048 * returns -1 if no such friend
1049 */
862int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) 1050int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
863{ 1051{
864
865 uint32_t i; 1052 uint32_t i;
866 for(i = 0; i < num_friends; ++i) 1053 for (i = 0; i < num_friends; ++i) {
867 /* Equal */ 1054 /* Equal */
868 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) 1055 if (memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0)
869 return friend_iplist(ip_portlist, i); 1056 return friend_iplist(ip_portlist, i);
1057 }
870 return -1; 1058 return -1;
871} 1059}
872 1060
@@ -876,21 +1064,24 @@ int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
876int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) 1064int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
877{ 1065{
878 uint8_t data[sizeof(uint64_t) + 1]; 1066 uint8_t data[sizeof(uint64_t) + 1];
1067 uint8_t packet[MAX_DATA_SIZE];
1068
1069 /* 254 is NAT ping request packet id */
1070 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254);
1071 int num = 0;
1072
879 data[0] = type; 1073 data[0] = type;
880 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 1074 memcpy(data + 1, &ping_id, sizeof(uint64_t));
881 1075
882 uint8_t packet[MAX_DATA_SIZE]; 1076 if (len == -1)
883 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
884 if(len == -1)
885 return -1; 1077 return -1;
886 1078
887 int num = 0; 1079 if (type == 0) /*If packet is request use many people to route it*/
1080 num = route_tofriend(public_key, packet, len);
1081 else if (type == 1) /*If packet is response use only one person to route it*/
1082 num = routeone_tofriend(public_key, packet, len);
888 1083
889 if(type == 0) 1084 if (num == 0)
890 num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/
891 else if(type == 1)
892 num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/
893 if(num == 0)
894 return -1; 1085 return -1;
895 return num; 1086 return num;
896} 1087}
@@ -898,45 +1089,54 @@ int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
898/* Handle a recieved ping request for */ 1089/* Handle a recieved ping request for */
899int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) 1090int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
900{ 1091{
901 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 1092 if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING
902 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 1093 && length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
903 return 1; 1094 return 1;
1095
904 /* check if request is for us. */ 1096 /* check if request is for us. */
905 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 1097 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
906 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 1098 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
907 uint8_t data[MAX_DATA_SIZE]; 1099 uint8_t data[MAX_DATA_SIZE];
1100
908 int len = handle_request(public_key, data, packet, length); 1101 int len = handle_request(public_key, data, packet, length);
909 if(len != sizeof(uint64_t) + 1) 1102 if (len != sizeof(uint64_t) + 1)
910 return 1; 1103 return 1;
1104
911 uint64_t ping_id; 1105 uint64_t ping_id;
912 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 1106 memcpy(&ping_id, data + 1, sizeof(uint64_t));
913 1107
914 int friendnumber = friend_number(public_key); 1108 int friendnumber = friend_number(public_key);
915 if(friendnumber == -1) 1109 if (friendnumber == -1)
916 return 1; 1110 return 1;
917 1111
918 if(data[0] == 0) { 1112 Friend * friend = &friends_list[friendnumber];
919 send_NATping(public_key, ping_id, 1); /*1 is reply*/ 1113
920 friends_list[friendnumber].recvNATping_timestamp = unix_time(); 1114 if (data[0] == 0) {
1115 /* 1 is reply */
1116 send_NATping(public_key, ping_id, 1);
1117 friend->recvNATping_timestamp = unix_time();
921 return 0; 1118 return 0;
922 } else if (data[0] == 1) 1119 } else if (data[0] == 1) {
923 if(friends_list[friendnumber].NATping_id == ping_id) { 1120 if (friend->NATping_id == ping_id) {
924 friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int(); 1121 friend->NATping_id = ((uint64_t)random_int() << 32) + random_int();
925 friends_list[friendnumber].hole_punching = 1; 1122 friend->hole_punching = 1;
926 return 0; 1123 return 0;
927 } 1124 }
1125 }
928 return 1; 1126 return 1;
929 } 1127 }
1128
930 /* if request is not for us, try routing it. */ 1129 /* if request is not for us, try routing it. */
931 else if(route_packet(packet + 1, packet, length) == length) 1130 route_packet(packet + 1, packet, length);
932 return 0; 1131
933 return 0; 1132 return 0;
934} 1133}
935 1134
936/*Get the most common ip in the ip_portlist 1135/* Get the most common ip in the ip_portlist
937 Only return ip if it appears in list min_num or more 1136 * Only return ip if it appears in list min_num or more
938 len must not be bigger than MAX_FRIEND_CLIENTS 1137 * len must not be bigger than MAX_FRIEND_CLIENTS
939 return ip of 0 if failure */ 1138 * return ip of 0 if failure
1139 */
940static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) 1140static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
941{ 1141{
942 IP zero = {{0}}; 1142 IP zero = {{0}};
@@ -945,29 +1145,34 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
945 1145
946 uint32_t i, j; 1146 uint32_t i, j;
947 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; 1147 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
1148
948 for(i = 0; i < len; ++i) { 1149 for(i = 0; i < len; ++i) {
949 for(j = 0; j < len; ++j) 1150 for(j = 0; j < len; ++j) {
950 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) 1151 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i)
951 ++numbers[i]; 1152 ++numbers[i];
1153 }
952 if(numbers[i] >= min_num) 1154 if(numbers[i] >= min_num)
953 return ip_portlist[i].ip; 1155 return ip_portlist[i].ip;
954 } 1156 }
955 return zero; 1157 return zero;
956} 1158}
957 1159
958/*Return all the ports for one ip in a list 1160/* Return all the ports for one ip in a list
959 portlist must be at least len long 1161 * portlist must be at least len long
960 where len is the length of ip_portlist 1162 * where len is the length of ip_portlist
961 returns the number of ports and puts the list of ports in portlist*/ 1163 * returns the number of ports and puts the list of ports in portlist
1164 */
962static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip) 1165static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip)
963{ 1166{
964 uint32_t i; 1167 uint32_t i;
965 uint16_t num = 0; 1168 uint16_t num = 0;
966 for(i = 0; i < len; ++i) 1169
1170 for(i = 0; i < len; ++i) {
967 if(ip_portlist[i].ip.i == ip.i) { 1171 if(ip_portlist[i].ip.i == ip.i) {
968 portlist[num] = ntohs(ip_portlist[i].port); 1172 portlist[num] = ntohs(ip_portlist[i].port);
969 ++num; 1173 ++num;
970 } 1174 }
1175 }
971 return num; 1176 return num;
972} 1177}
973 1178
@@ -975,8 +1180,10 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
975{ 1180{
976 if(numports > MAX_FRIEND_CLIENTS || numports == 0) 1181 if(numports > MAX_FRIEND_CLIENTS || numports == 0)
977 return; 1182 return;
1183
978 uint32_t i; 1184 uint32_t i;
979 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1185 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1186
980 for(i = friends_list[friend_num].punching_index; i != top; i++) { 1187 for(i = friends_list[friend_num].punching_index; i != top; i++) {
981 /*TODO: improve port guessing algorithm*/ 1188 /*TODO: improve port guessing algorithm*/
982 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); 1189 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
@@ -990,23 +1197,25 @@ static void doNAT()
990{ 1197{
991 uint32_t i; 1198 uint32_t i;
992 int64_t temp_time = unix_time(); 1199 int64_t temp_time = unix_time();
993 for(i = 0; i < num_friends; ++i) { 1200
1201 for (i = 0; i < num_friends; ++i) {
994 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1202 IP_Port ip_list[MAX_FRIEND_CLIENTS];
995 int num = friend_iplist(ip_list, i); 1203 int num = friend_iplist(ip_list, i);
996 /*If we are connected to friend or if friend is not online don't try to hole punch with him*/
997 if(num < MAX_FRIEND_CLIENTS/2)
998 continue;
999 1204
1205 /*If already connected or friend is not online don't try to hole punch*/
1206 if (num < MAX_FRIEND_CLIENTS/2)
1207 continue;
1000 1208
1001 if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { 1209 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1002 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 1210 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1003 friends_list[i].NATping_timestamp = temp_time; 1211 friends_list[i].NATping_timestamp = temp_time;
1004 } 1212 }
1005 if(friends_list[i].hole_punching == 1 && 1213 if (friends_list[i].hole_punching == 1 &&
1006 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && 1214 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
1007 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) { 1215 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) {
1216
1008 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2); 1217 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1009 if(ip.i == 0) 1218 if (ip.i == 0)
1010 continue; 1219 continue;
1011 1220
1012 uint16_t port_list[MAX_FRIEND_CLIENTS]; 1221 uint16_t port_list[MAX_FRIEND_CLIENTS];
@@ -1069,17 +1278,22 @@ void DHT_save(uint8_t * data)
1069} 1278}
1070 1279
1071/* load the DHT from data of size size; 1280/* load the DHT from data of size size;
1072 return -1 if failure 1281 * return -1 if failure
1073 return 0 if success */ 1282 * return 0 if success
1283 */
1074int DHT_load(uint8_t * data, uint32_t size) 1284int DHT_load(uint8_t * data, uint32_t size)
1075{ 1285{
1076 if(size < sizeof(close_clientlist)) 1286 if(size < sizeof(close_clientlist))
1077 return -1; 1287 return -1;
1288
1078 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1289 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0)
1079 return -1; 1290 return -1;
1291
1080 uint32_t i, j; 1292 uint32_t i, j;
1081 /* int64_t temp_time = unix_time(); */
1082 uint16_t temp; 1293 uint16_t temp;
1294 /* int64_t temp_time = unix_time(); */
1295
1296 Client_data * client;
1083 1297
1084 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1298 temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1085 1299
@@ -1088,29 +1302,35 @@ int DHT_load(uint8_t * data, uint32_t size)
1088 1302
1089 for(i = 0; i < temp; ++i) { 1303 for(i = 0; i < temp; ++i) {
1090 DHT_addfriend(tempfriends_list[i].client_id); 1304 DHT_addfriend(tempfriends_list[i].client_id);
1091 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1305
1092 if(tempfriends_list[i].client_list[j].timestamp != 0) { 1306 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1093 getnodes(tempfriends_list[i].client_list[j].ip_port, 1307 client = &tempfriends_list[i].client_list[j];
1094 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); 1308 if(client->timestamp != 0)
1095 } 1309 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id);
1310 }
1096 } 1311 }
1097 } 1312 }
1098 Client_data * tempclose_clientlist = (Client_data *)data; 1313 Client_data * tempclose_clientlist = (Client_data *)data;
1099 1314
1100 for(i = 0; i < LCLIENT_LIST; ++i) 1315 for(i = 0; i < LCLIENT_LIST; ++i) {
1101 if(tempclose_clientlist[i].timestamp != 0) 1316 if(tempclose_clientlist[i].timestamp != 0)
1102 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); 1317 DHT_bootstrap( tempclose_clientlist[i].ip_port,
1318 tempclose_clientlist[i].client_id );
1319 }
1103 return 0; 1320 return 0;
1104} 1321}
1105 1322
1106/* returns 0 if we are not connected to the DHT 1323/* returns 0 if we are not connected to the DHT
1107 returns 1 if we are */ 1324 * returns 1 if we are
1325 */
1108int DHT_isconnected() 1326int DHT_isconnected()
1109{ 1327{
1110 uint32_t i; 1328 uint32_t i, temp_time = unix_time();
1111 int64_t temp_time = unix_time(); 1329 int64_t temp_time = unix_time();
1112 for(i = 0; i < LCLIENT_LIST; ++i) 1330
1331 for(i = 0; i < LCLIENT_LIST; ++i) {
1113 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) 1332 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
1114 return 1; 1333 return 1;
1334 }
1115 return 0; 1335 return 0;
1116} 1336}