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