summaryrefslogtreecommitdiff
path: root/core/DHT.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/DHT.c')
-rw-r--r--core/DHT.c806
1 files changed, 445 insertions, 361 deletions
diff --git a/core/DHT.c b/core/DHT.c
index 030c578e..857ac5e8 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -1,33 +1,28 @@
1/* DHT.c 1/* DHT.c
2* 2 *
3* An implementation of the DHT as seen in docs/DHT.txt 3 * An implementation of the DHT as seen in docs/DHT.txt
4* 4 *
5 5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 *
7 7 * This file is part of Tox.
8 This file is part of Tox. 8 *
9 9 * Tox is free software: you can redistribute it and/or modify
10 Tox is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by
11 it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or
12 the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version.
13 (at your option) any later version. 13 *
14 14 * Tox is distributed in the hope that it will be useful,
15 Tox is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details.
18 GNU General Public License for more details. 18 *
19 19 * You should have received a copy of the GNU General Public License
20 You should have received a copy of the GNU General Public License 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 *
22 22 */
23*/
24
25
26
27 23
28#include "DHT.h" 24#include "DHT.h"
29 25
30
31typedef struct 26typedef struct
32{ 27{
33 uint8_t client_id[CLIENT_ID_SIZE]; 28 uint8_t client_id[CLIENT_ID_SIZE];
@@ -38,17 +33,24 @@ typedef struct
38 (for nodes in friends_list) or us (for nodes in close_clientlist) */ 33 (for nodes in friends_list) or us (for nodes in close_clientlist) */
39 uint32_t ret_timestamp; 34 uint32_t ret_timestamp;
40}Client_data; 35}Client_data;
36
41/* maximum number of clients stored per friend. */ 37/* maximum number of clients stored per friend. */
42#define MAX_FRIEND_CLIENTS 8 38#define MAX_FRIEND_CLIENTS 8
39
43typedef struct 40typedef struct
44{ 41{
45 uint8_t client_id[CLIENT_ID_SIZE]; 42 uint8_t client_id[CLIENT_ID_SIZE];
46 Client_data client_list[MAX_FRIEND_CLIENTS]; 43 Client_data client_list[MAX_FRIEND_CLIENTS];
47 uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */ 44 uint32_t lastgetnode; /* time at which the last get_nodes request was sent. */
48 45
46 /*Symetric NAT hole punching stuff*/
47 uint8_t hole_punching; /*0 if not hole punching, 1 if currently hole punching */
48 uint32_t punching_index;
49 uint32_t punching_timestamp;
50 uint64_t NATping_id;
51 uint32_t NATping_timestamp;
49}Friend; 52}Friend;
50 53
51
52typedef struct 54typedef struct
53{ 55{
54 uint8_t client_id[CLIENT_ID_SIZE]; 56 uint8_t client_id[CLIENT_ID_SIZE];
@@ -72,13 +74,11 @@ uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
72#define LCLIENT_LIST 32 74#define LCLIENT_LIST 32
73static Client_data close_clientlist[LCLIENT_LIST]; 75static Client_data close_clientlist[LCLIENT_LIST];
74 76
75
76
77static Friend * friends_list; 77static Friend * friends_list;
78static uint16_t num_friends; 78static uint16_t num_friends;
79 79
80/* The list of ip ports along with the ping_id of what we sent them and a timestamp */ 80/* The list of ip ports along with the ping_id of what we sent them and a timestamp */
81#define LPING_ARRAY 128 81#define LPING_ARRAY 256
82 82
83static Pinged pings[LPING_ARRAY]; 83static Pinged pings[LPING_ARRAY];
84 84
@@ -86,7 +86,6 @@ static Pinged pings[LPING_ARRAY];
86 86
87static Pinged send_nodes[LSEND_NODES_ARRAY]; 87static Pinged send_nodes[LSEND_NODES_ARRAY];
88 88
89
90/* Compares client_id1 and client_id2 with client_id 89/* Compares client_id1 and client_id2 with client_id
91 return 0 if both are same distance 90 return 0 if both are same distance
92 return 1 if client_id1 is closer 91 return 1 if client_id1 is closer
@@ -94,17 +93,12 @@ static Pinged send_nodes[LSEND_NODES_ARRAY];
94int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ 93int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */
95{ 94{
96 uint32_t i; 95 uint32_t i;
97 for(i = 0; i < CLIENT_ID_SIZE; ++i) 96 for(i = 0; i < CLIENT_ID_SIZE; ++i) {
98 { 97 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i])) {
99 if(abs(client_id[i] ^ client_id1[i]) < abs(client_id[i] ^ client_id2[i]))
100 {
101 return 1; 98 return 1;
102 } 99 } else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i])) {
103 else if(abs(client_id[i] ^ client_id1[i]) > abs(client_id[i] ^ client_id2[i]))
104 {
105 return 2; 100 return 2;
106 } 101 }
107
108 } 102 }
109 103
110 return 0; 104 return 0;
@@ -121,17 +115,14 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
121 uint32_t i; 115 uint32_t i;
122 uint32_t temp_time = unix_time(); 116 uint32_t temp_time = unix_time();
123 117
124 for(i = 0; i < length; ++i) 118 for(i = 0; i < length; ++i) {
125 {
126 /*If ip_port is assigned to a different client_id replace it*/ 119 /*If ip_port is assigned to a different client_id replace it*/
127 if(list[i].ip_port.ip.i == ip_port.ip.i && 120 if(list[i].ip_port.ip.i == ip_port.ip.i &&
128 list[i].ip_port.port == ip_port.port) 121 list[i].ip_port.port == ip_port.port) {
129 {
130 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 122 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
131 } 123 }
132 124
133 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) 125 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
134 {
135 /* Refresh the client timestamp. */ 126 /* Refresh the client timestamp. */
136 list[i].timestamp = temp_time; 127 list[i].timestamp = temp_time;
137 list[i].ip_port.ip.i = ip_port.ip.i; 128 list[i].ip_port.ip.i = ip_port.ip.i;
@@ -148,10 +139,8 @@ int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_
148int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 139int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
149{ 140{
150 uint32_t i; 141 uint32_t i;
151 for(i = 0; i < length; ++i) 142 for(i = 0; i < length; ++i) {
152 { 143 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
153 if(memcmp(list[i].client_id, client_id, CLIENT_ID_SIZE) == 0)
154 {
155 144
156 return 1; 145 return 1;
157 } 146 }
@@ -160,14 +149,25 @@ int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id)
160 149
161} 150}
162 151
163 152/*Return the friend number from the client_id
153 Return -1 if failure, number of friend if success*/
154static int friend_number(uint8_t * client_id)
155{
156 uint32_t i;
157 for(i = 0; i < num_friends; ++i) {
158 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */
159 {
160 return i;
161 }
162 }
163 return -1;
164}
164 165
165/* the number of seconds for a non responsive node to become bad. */ 166/* the number of seconds for a non responsive node to become bad. */
166#define BAD_NODE_TIMEOUT 130 167#define BAD_NODE_TIMEOUT 70
167/* the max number of nodes to send with send nodes. */ 168/* the max number of nodes to send with send nodes. */
168#define MAX_SENT_NODES 8 169#define MAX_SENT_NODES 8
169 170
170
171/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request: 171/* Find MAX_SENT_NODES nodes closest to the client_id for the send nodes request:
172 put them in the nodes_list and return how many were found. 172 put them in the nodes_list and return how many were found.
173 TODO: Make this function much more efficient. */ 173 TODO: Make this function much more efficient. */
@@ -176,48 +176,35 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
176 uint32_t i, j, k; 176 uint32_t i, j, k;
177 int num_nodes=0; 177 int num_nodes=0;
178 uint32_t temp_time = unix_time(); 178 uint32_t temp_time = unix_time();
179 for(i = 0; i < LCLIENT_LIST; ++i) 179 for(i = 0; i < LCLIENT_LIST; ++i) {
180 {
181 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time && 180 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time &&
182 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) 181 !client_in_nodelist(nodes_list, MAX_SENT_NODES,close_clientlist[i].client_id)) {
183 /* if node is good and not already in list. */ 182 /* if node is good and not already in list. */
184 { 183 if(num_nodes < MAX_SENT_NODES) {
185 if(num_nodes < MAX_SENT_NODES)
186 {
187 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 184 memcpy(nodes_list[num_nodes].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
188 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 185 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
189 num_nodes++; 186 num_nodes++;
190 } 187 }
191 else for(j = 0; j < MAX_SENT_NODES; ++j) 188 else for(j = 0; j < MAX_SENT_NODES; ++j) {
192 { 189 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2) {
193 if(id_closest(client_id, nodes_list[j].client_id, close_clientlist[i].client_id) == 2)
194 {
195 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE); 190 memcpy(nodes_list[j].client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE);
196 nodes_list[j].ip_port = close_clientlist[i].ip_port; 191 nodes_list[j].ip_port = close_clientlist[i].ip_port;
197 break; 192 break;
198 } 193 }
199 } 194 }
200 } 195 }
201
202 } 196 }
203 for(i = 0; i < num_friends; ++i) 197 for(i = 0; i < num_friends; ++i) {
204 { 198 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
205 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
206 {
207 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time && 199 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time &&
208 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) 200 !client_in_nodelist(nodes_list, MAX_SENT_NODES,friends_list[i].client_list[j].client_id)) {
209 /* if node is good and not already in list. */ 201 /* if node is good and not already in list. */
210 { 202 if(num_nodes < MAX_SENT_NODES) {
211 if(num_nodes < MAX_SENT_NODES)
212 {
213 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 203 memcpy(nodes_list[num_nodes].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
214 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 204 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
215 num_nodes++; 205 num_nodes++;
216 } 206 } else for(k = 0; k < MAX_SENT_NODES; ++k) {
217 else for(k = 0; k < MAX_SENT_NODES; ++k) 207 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2) {
218 {
219 if(id_closest(client_id, nodes_list[k].client_id, friends_list[i].client_list[j].client_id) == 2)
220 {
221 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE); 208 memcpy(nodes_list[k].client_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE);
222 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 209 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
223 break; 210 break;
@@ -227,12 +214,9 @@ int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
227 } 214 }
228 } 215 }
229 216
230 return num_nodes; 217 return num_nodes;
231
232} 218}
233 219
234
235
236/* replace first bad (or empty) node with this one 220/* replace first bad (or empty) node with this one
237 return 0 if successful 221 return 0 if successful
238 return 1 if not (list contains no bad nodes) */ 222 return 1 if not (list contains no bad nodes) */
@@ -240,10 +224,8 @@ int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Por
240{ 224{
241 uint32_t i; 225 uint32_t i;
242 uint32_t temp_time = unix_time(); 226 uint32_t temp_time = unix_time();
243 for(i = 0; i < length; ++i) 227 for(i = 0; i < length; ++i) {
244 { 228 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */ {
245 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) /* if node is bad. */
246 {
247 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 229 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
248 list[i].ip_port = ip_port; 230 list[i].ip_port = ip_port;
249 list[i].timestamp = temp_time; 231 list[i].timestamp = temp_time;
@@ -263,10 +245,8 @@ int replace_good(Client_data * list, uint32_t length, uint8_t * client_id, IP_Po
263 uint32_t i; 245 uint32_t i;
264 uint32_t temp_time = unix_time(); 246 uint32_t temp_time = unix_time();
265 247
266 for(i = 0; i < length; ++i) 248 for(i = 0; i < length; ++i) {
267 { 249 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
268 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2)
269 {
270 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 250 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
271 list[i].ip_port = ip_port; 251 list[i].ip_port = ip_port;
272 list[i].timestamp = temp_time; 252 list[i].timestamp = temp_time;
@@ -286,23 +266,16 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
286 uint32_t i; 266 uint32_t i;
287 267
288 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */ 268 /* NOTE: current behavior if there are two clients with the same id is to replace the first ip by the second. */
289 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 269 if(!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
290 {
291 270
292 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) 271 if(replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
293 {
294 /* if we can't replace bad nodes we try replacing good ones */ 272 /* if we can't replace bad nodes we try replacing good ones */
295 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key); 273 replace_good(close_clientlist, LCLIENT_LIST, client_id, ip_port, self_public_key);
296 } 274 }
297
298 } 275 }
299 for(i = 0; i < num_friends; ++i) 276 for(i = 0; i < num_friends; ++i) {
300 { 277 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) {
301 if(!client_in_list(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) 278 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port)) {
302 {
303
304 if(replace_bad(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port))
305 {
306 /* if we can't replace bad nodes we try replacing good ones. */ 279 /* if we can't replace bad nodes we try replacing good ones. */
307 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id); 280 replace_good(friends_list[i].client_list, MAX_FRIEND_CLIENTS, client_id, ip_port, friends_list[i].client_id);
308 } 281 }
@@ -316,12 +289,9 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
316{ 289{
317 uint32_t i, j; 290 uint32_t i, j;
318 uint32_t temp_time = unix_time(); 291 uint32_t temp_time = unix_time();
319 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) 292 if(memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
320 { 293 for(i = 0; i < LCLIENT_LIST; ++i) {
321 for(i = 0; i < LCLIENT_LIST; ++i) 294 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
322 {
323 if(memcmp(nodeclient_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
324 {
325 close_clientlist[i].ret_ip_port = ip_port; 295 close_clientlist[i].ret_ip_port = ip_port;
326 close_clientlist[i].ret_timestamp = temp_time; 296 close_clientlist[i].ret_timestamp = temp_time;
327 return; 297 return;
@@ -329,14 +299,10 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
329 } 299 }
330 } 300 }
331 else 301 else
332 for(i = 0; i < num_friends; ++i) 302 for(i = 0; i < num_friends; ++i) {
333 { 303 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) {
334 if(memcmp(client_id, friends_list[i].client_id, CLIENT_ID_SIZE) == 0) 304 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
335 { 305 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0) {
336 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
337 {
338 if(memcmp(nodeclient_id, friends_list[i].client_list[j].client_id, CLIENT_ID_SIZE) == 0)
339 {
340 friends_list[i].client_list[j].ret_ip_port = ip_port; 306 friends_list[i].client_list[j].ret_ip_port = ip_port;
341 friends_list[i].client_list[j].ret_timestamp = temp_time; 307 friends_list[i].client_list[j].ret_timestamp = temp_time;
342 return; 308 return;
@@ -348,6 +314,7 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
348 314
349/* ping timeout in seconds */ 315/* ping timeout in seconds */
350#define PING_TIMEOUT 5 316#define PING_TIMEOUT 5
317
351/* check if we are currently pinging an ip_port and/or a ping_id 318/* check if we are currently pinging an ip_port and/or a ping_id
352 variables with values of zero will not be checked. 319 variables with values of zero will not be checked.
353 if we are already, return 1 320 if we are already, return 1
@@ -359,28 +326,22 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
359 uint8_t pinging; 326 uint8_t pinging;
360 uint32_t temp_time = unix_time(); 327 uint32_t temp_time = unix_time();
361 328
362 for(i = 0; i < LPING_ARRAY; ++i ) 329 for(i = 0; i < LPING_ARRAY; ++i ) {
363 { 330 if((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
364 if((pings[i].timestamp + PING_TIMEOUT) > temp_time)
365 {
366 pinging = 0; 331 pinging = 0;
367 if(ip_port.ip.i != 0) 332 if(ip_port.ip.i != 0) {
368 {
369 if(pings[i].ip_port.ip.i == ip_port.ip.i && 333 if(pings[i].ip_port.ip.i == ip_port.ip.i &&
370 pings[i].ip_port.port == ip_port.port) 334 pings[i].ip_port.port == ip_port.port) {
371 {
372 ++pinging; 335 ++pinging;
373 } 336 }
374 } 337 }
375 if(ping_id != 0) 338 if(ping_id != 0) {
376 {
377 if(pings[i].ping_id == ping_id) 339 if(pings[i].ping_id == ping_id)
378 { 340 {
379 ++pinging; 341 ++pinging;
380 } 342 }
381 } 343 }
382 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 344 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) {
383 {
384 return 1; 345 return 1;
385 } 346 }
386 347
@@ -391,7 +352,6 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
391 352
392} 353}
393 354
394
395/* Same as last function but for get_node requests. */ 355/* Same as last function but for get_node requests. */
396int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) 356int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
397{ 357{
@@ -399,28 +359,21 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
399 uint8_t pinging; 359 uint8_t pinging;
400 uint32_t temp_time = unix_time(); 360 uint32_t temp_time = unix_time();
401 361
402 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) 362 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
403 { 363 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
404 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time)
405 {
406 pinging = 0; 364 pinging = 0;
407 if(ip_port.ip.i != 0) 365 if(ip_port.ip.i != 0) {
408 {
409 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i && 366 if(send_nodes[i].ip_port.ip.i == ip_port.ip.i &&
410 send_nodes[i].ip_port.port == ip_port.port) 367 send_nodes[i].ip_port.port == ip_port.port) {
411 {
412 ++pinging; 368 ++pinging;
413 } 369 }
414 } 370 }
415 if(ping_id != 0) 371 if(ping_id != 0) {
416 { 372 if(send_nodes[i].ping_id == ping_id) {
417 if(send_nodes[i].ping_id == ping_id)
418 {
419 ++pinging; 373 ++pinging;
420 } 374 }
421 } 375 }
422 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 376 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) {
423 {
424 return 1; 377 return 1;
425 } 378 }
426 379
@@ -431,7 +384,6 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
431 384
432} 385}
433 386
434
435/* Add a new ping request to the list of ping requests 387/* Add a new ping request to the list of ping requests
436 returns the ping_id to put in the ping request 388 returns the ping_id to put in the ping request
437 returns 0 if problem. 389 returns 0 if problem.
@@ -442,12 +394,9 @@ uint64_t add_pinging(IP_Port ip_port)
442 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 394 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
443 uint32_t temp_time = unix_time(); 395 uint32_t temp_time = unix_time();
444 396
445 for(i = 0; i < PING_TIMEOUT; ++i ) 397 for(i = 0; i < PING_TIMEOUT; ++i ) {
446 { 398 for(j = 0; j < LPING_ARRAY; ++j ) {
447 for(j = 0; j < LPING_ARRAY; ++j ) 399 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time) {
448 {
449 if((pings[j].timestamp + PING_TIMEOUT - i) < temp_time)
450 {
451 pings[j].timestamp = temp_time; 400 pings[j].timestamp = temp_time;
452 pings[j].ip_port = ip_port; 401 pings[j].ip_port = ip_port;
453 pings[j].ping_id = ping_id; 402 pings[j].ping_id = ping_id;
@@ -466,12 +415,9 @@ uint64_t add_gettingnodes(IP_Port ip_port)
466 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 415 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
467 uint32_t temp_time = unix_time(); 416 uint32_t temp_time = unix_time();
468 417
469 for(i = 0; i < PING_TIMEOUT; ++i ) 418 for(i = 0; i < PING_TIMEOUT; ++i ) {
470 { 419 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
471 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) 420 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time) {
472 {
473 if((send_nodes[j].timestamp + PING_TIMEOUT - i) < temp_time)
474 {
475 send_nodes[j].timestamp = temp_time; 421 send_nodes[j].timestamp = temp_time;
476 send_nodes[j].ip_port = ip_port; 422 send_nodes[j].ip_port = ip_port;
477 send_nodes[j].ping_id = ping_id; 423 send_nodes[j].ping_id = ping_id;
@@ -483,25 +429,20 @@ uint64_t add_gettingnodes(IP_Port ip_port)
483 429
484} 430}
485 431
486
487
488/* send a ping request 432/* send a ping request
489 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */ 433 Ping request only works if none has been sent to that ip/port in the last 5 seconds. */
490static int pingreq(IP_Port ip_port, uint8_t * public_key) 434static int pingreq(IP_Port ip_port, uint8_t * public_key)
491{ 435{
492 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 436 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ {
493 {
494 return 1; 437 return 1;
495 } 438 }
496 439
497 if(is_pinging(ip_port, 0)) 440 if(is_pinging(ip_port, 0)) {
498 {
499 return 1; 441 return 1;
500 } 442 }
501 443
502 uint64_t ping_id = add_pinging(ip_port); 444 uint64_t ping_id = add_pinging(ip_port);
503 if(ping_id == 0) 445 if(ping_id == 0) {
504 {
505 return 1; 446 return 1;
506 } 447 }
507 448
@@ -511,8 +452,7 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
511 random_nonce(nonce); 452 random_nonce(nonce);
512 453
513 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 454 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
514 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 455 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) {
515 {
516 return -1; 456 return -1;
517 } 457 }
518 data[0] = 0; 458 data[0] = 0;
@@ -524,12 +464,11 @@ static int pingreq(IP_Port ip_port, uint8_t * public_key)
524 464
525} 465}
526 466
527
528/* send a ping response */ 467/* send a ping response */
529static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id) 468static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
530{ 469{
531 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 470 /* check if packet is gonna be sent to ourself */
532 { 471 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) {
533 return 1; 472 return 1;
534 } 473 }
535 474
@@ -539,8 +478,7 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
539 random_nonce(nonce); 478 random_nonce(nonce);
540 479
541 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt); 480 int len = encrypt_data(public_key, self_secret_key, nonce, (uint8_t *)&ping_id, sizeof(ping_id), encrypt);
542 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) 481 if(len != sizeof(ping_id) + ENCRYPTION_PADDING) {
543 {
544 return -1; 482 return -1;
545 } 483 }
546 data[0] = 1; 484 data[0] = 1;
@@ -555,20 +493,18 @@ static int pingres(IP_Port ip_port, uint8_t * public_key, uint64_t ping_id)
555/* send a getnodes request */ 493/* send a getnodes request */
556static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 494static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
557{ 495{
558 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 496 /* check if packet is gonna be sent to ourself */
559 { 497 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) {
560 return 1; 498 return 1;
561 } 499 }
562 500
563 if(is_gettingnodes(ip_port, 0)) 501 if(is_gettingnodes(ip_port, 0)) {
564 {
565 return 1; 502 return 1;
566 } 503 }
567 504
568 uint64_t ping_id = add_gettingnodes(ip_port); 505 uint64_t ping_id = add_gettingnodes(ip_port);
569 506
570 if(ping_id == 0) 507 if(ping_id == 0) {
571 {
572 return 1; 508 return 1;
573 } 509 }
574 510
@@ -583,8 +519,7 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
583 519
584 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt); 520 int len = encrypt_data(public_key, self_secret_key, nonce, plain, sizeof(ping_id) + CLIENT_ID_SIZE, encrypt);
585 521
586 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 522 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) {
587 {
588 return -1; 523 return -1;
589 } 524 }
590 data[0] = 2; 525 data[0] = 2;
@@ -595,12 +530,10 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
595 530
596} 531}
597 532
598
599/* send a send nodes response */ 533/* send a send nodes response */
600static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 534static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id)
601{ 535{
602 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ 536 if(memcmp(public_key, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is gonna be sent to ourself */ {
603 {
604 return 1; 537 return 1;
605 } 538 }
606 539
@@ -610,8 +543,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
610 Node_format nodes_list[MAX_SENT_NODES]; 543 Node_format nodes_list[MAX_SENT_NODES];
611 int num_nodes = get_close_nodes(client_id, nodes_list); 544 int num_nodes = get_close_nodes(client_id, nodes_list);
612 545
613 if(num_nodes == 0) 546 if(num_nodes == 0) {
614 {
615 return 0; 547 return 0;
616 } 548 }
617 549
@@ -626,8 +558,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
626 int len = encrypt_data(public_key, self_secret_key, nonce, plain, 558 int len = encrypt_data(public_key, self_secret_key, nonce, plain,
627 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt); 559 sizeof(ping_id) + num_nodes * sizeof(Node_format), encrypt);
628 560
629 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 561 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) {
630 {
631 return -1; 562 return -1;
632 } 563 }
633 564
@@ -640,20 +571,17 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
640 571
641} 572}
642 573
643
644
645/* Packet handling functions 574/* Packet handling functions
646 One to handle each types of packets we receive 575 One to handle each types of packets we receive
647 return 0 if handled correctly, 1 if packet is bad. */ 576 return 0 if handled correctly, 1 if packet is bad. */
648int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) 577int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
649{ 578{
650 uint64_t ping_id; 579 uint64_t ping_id;
651 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 580 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) {
652 {
653 return 1; 581 return 1;
654 } 582 }
655 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 583 /* check if packet is from ourself. */
656 { 584 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) {
657 return 1; 585 return 1;
658 } 586 }
659 587
@@ -662,8 +590,7 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
662 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 590 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
663 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 591 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
664 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 592 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
665 if(len != sizeof(ping_id)) 593 if(len != sizeof(ping_id)) {
666 {
667 return 1; 594 return 1;
668 } 595 }
669 596
@@ -679,12 +606,10 @@ int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source)
679int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source) 606int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
680{ 607{
681 uint64_t ping_id; 608 uint64_t ping_id;
682 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) 609 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING) {
683 {
684 return 1; 610 return 1;
685 } 611 }
686 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 612 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ {
687 {
688 return 1; 613 return 1;
689 } 614 }
690 615
@@ -693,13 +618,11 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
693 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE, 618 int len = decrypt_data(packet + 1, self_secret_key, packet + 1 + CLIENT_ID_SIZE,
694 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 619 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
695 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id); 620 sizeof(ping_id) + ENCRYPTION_PADDING, (uint8_t *)&ping_id);
696 if(len != sizeof(ping_id)) 621 if(len != sizeof(ping_id)) {
697 {
698 return 1; 622 return 1;
699 } 623 }
700 624
701 if(is_pinging(source, ping_id)) 625 if(is_pinging(source, ping_id)) {
702 {
703 addto_lists(source, packet + 1); 626 addto_lists(source, packet + 1);
704 return 0; 627 return 0;
705 } 628 }
@@ -710,12 +633,11 @@ int handle_pingres(uint8_t * packet, uint32_t length, IP_Port source)
710int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) 633int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
711{ 634{
712 uint64_t ping_id; 635 uint64_t ping_id;
713 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 636 if(length != 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) {
714 {
715 return 1; 637 return 1;
716 } 638 }
717 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) /* check if packet is from ourself. */ 639 /* check if packet is from ourself. */
718 { 640 if(memcmp(packet + 1, self_public_key, CLIENT_ID_SIZE) == 0) {
719 return 1; 641 return 1;
720 } 642 }
721 643
@@ -725,8 +647,7 @@ int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source)
725 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 647 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
726 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain); 648 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, plain);
727 649
728 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) 650 if(len != sizeof(ping_id) + CLIENT_ID_SIZE) {
729 {
730 return 1; 651 return 1;
731 } 652 }
732 653
@@ -748,8 +669,7 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
748 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 669 (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
749 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 || 670 + ENCRYPTION_PADDING)) % (sizeof(Node_format)) != 0 ||
750 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 671 length < 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
751 + sizeof(Node_format) + ENCRYPTION_PADDING) 672 + sizeof(Node_format) + ENCRYPTION_PADDING) {
752 {
753 return 1; 673 return 1;
754 } 674 }
755 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 675 uint32_t num_nodes = (length - (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
@@ -762,14 +682,12 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
762 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain); 682 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain);
763 683
764 684
765 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 685 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) {
766 {
767 return 1; 686 return 1;
768 } 687 }
769 688
770 memcpy(&ping_id, plain, sizeof(ping_id)); 689 memcpy(&ping_id, plain, sizeof(ping_id));
771 if(!is_gettingnodes(source, ping_id)) 690 if(!is_gettingnodes(source, ping_id)) {
772 {
773 return 1; 691 return 1;
774 } 692 }
775 693
@@ -779,8 +697,7 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
779 addto_lists(source, packet + 1); 697 addto_lists(source, packet + 1);
780 698
781 uint32_t i; 699 uint32_t i;
782 for(i = 0; i < num_nodes; ++i) 700 for(i = 0; i < num_nodes; ++i) {
783 {
784 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id); 701 pingreq(nodes_list[i].ip_port, nodes_list[i].client_id);
785 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 702 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
786 } 703 }
@@ -793,44 +710,36 @@ int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source)
793int DHT_addfriend(uint8_t * client_id) 710int DHT_addfriend(uint8_t * client_id)
794{ 711{
795 Friend * temp; 712 Friend * temp;
796 if(num_friends == 0) 713 if(num_friends == 0) {
797 {
798 temp = malloc(sizeof(Friend)); 714 temp = malloc(sizeof(Friend));
799 } 715 } else {
800 else
801 {
802 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 716 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
803 } 717 }
804 if(temp == NULL) 718 if(temp == NULL) {
805 {
806 return 1; 719 return 1;
807 } 720 }
808 721
809 friends_list = temp; 722 friends_list = temp;
810 memset(&friends_list[num_friends], 0, sizeof(Friend)); 723 memset(&friends_list[num_friends], 0, sizeof(Friend));
811 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE); 724 memcpy(friends_list[num_friends].client_id, client_id, CLIENT_ID_SIZE);
725 friends_list[num_friends].NATping_id = ((uint64_t)random_int() << 32) + random_int();
812 ++num_friends; 726 ++num_friends;
813 return 0; 727 return 0;
814} 728}
815 729
816
817
818int DHT_delfriend(uint8_t * client_id) 730int DHT_delfriend(uint8_t * client_id)
819{ 731{
820 uint32_t i; 732 uint32_t i;
821 Friend * temp; 733 Friend * temp;
822 for(i = 0; i < num_friends; ++i) 734 for(i = 0; i < num_friends; ++i) {
823 { 735 /* Equal */
824 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 736 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0){
825 {
826 --num_friends; 737 --num_friends;
827 if(num_friends != i) 738 if(num_friends != i) {
828 {
829 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE); 739 memcpy(friends_list[i].client_id, friends_list[num_friends].client_id, CLIENT_ID_SIZE);
830 } 740 }
831 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 741 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
832 if(temp != NULL) 742 if(temp != NULL) {
833 {
834 friends_list = temp; 743 friends_list = temp;
835 } 744 }
836 return 0; 745 return 0;
@@ -839,61 +748,27 @@ int DHT_delfriend(uint8_t * client_id)
839 return 1; 748 return 1;
840} 749}
841 750
842
843
844
845/* TODO: Optimize this. */ 751/* TODO: Optimize this. */
846IP_Port DHT_getfriendip(uint8_t * client_id) 752IP_Port DHT_getfriendip(uint8_t * client_id)
847{ 753{
848 uint32_t i, j; 754 uint32_t i, j;
849 IP_Port empty = {{{0}}, 0}; 755 IP_Port empty = {{{0}}, 0};
850 uint32_t temp_time = unix_time(); 756 uint32_t temp_time = unix_time();
851 for(i = 0; i < num_friends; ++i) 757 for(i = 0; i < num_friends; ++i) {
852 { 758 /* Equal */
853 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) /* Equal */ 759 if(memcmp(friends_list[i].client_id, client_id, CLIENT_ID_SIZE) == 0) {
854 { 760 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
855 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j)
856 {
857 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 && 761 if(memcmp(friends_list[i].client_list[j].client_id, client_id, CLIENT_ID_SIZE) == 0 &&
858 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) 762 friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) {
859 {
860 return friends_list[i].client_list[j].ip_port; 763 return friends_list[i].client_list[j].ip_port;
861 } 764 }
862 765 }
863 }
864
865 return empty; 766 return empty;
866 } 767 }
867 } 768 }
868 empty.ip.i = 1; 769 empty.ip.i = 1;
869 return empty; 770 return empty;
870 771
871}
872
873
874
875int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
876{
877 switch (packet[0]) {
878 case 0:
879 return handle_pingreq(packet, length, source);
880
881 case 1:
882 return handle_pingres(packet, length, source);
883
884 case 2:
885 return handle_getnodes(packet, length, source);
886
887 case 3:
888 return handle_sendnodes(packet, length, source);
889
890 default:
891 return 1;
892
893 }
894
895 return 0;
896
897} 772}
898 773
899/* The timeout after which a node is discarded completely. */ 774/* The timeout after which a node is discarded completely. */
@@ -907,8 +782,6 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
907 782
908/* Ping each client in the "friends" list every 60 seconds. 783/* Ping each client in the "friends" list every 60 seconds.
909 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */ 784 Send a get nodes request every 20 seconds to a random good node for each "friend" in our "friends" list. */
910
911
912void doDHTFriends() 785void doDHTFriends()
913{ 786{
914 uint32_t i, j; 787 uint32_t i, j;
@@ -916,27 +789,21 @@ void doDHTFriends()
916 uint32_t rand_node; 789 uint32_t rand_node;
917 uint32_t index[MAX_FRIEND_CLIENTS]; 790 uint32_t index[MAX_FRIEND_CLIENTS];
918 791
919 for(i = 0; i < num_friends; ++i) 792 for(i = 0; i < num_friends; ++i) {
920 {
921 uint32_t num_nodes = 0; 793 uint32_t num_nodes = 0;
922 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 794 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
923 { 795 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ {
924 if(friends_list[i].client_list[j].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ 796 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
925 {
926 if((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time)
927 {
928 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id); 797 pingreq(friends_list[i].client_list[j].ip_port, friends_list[i].client_list[j].client_id);
929 friends_list[i].client_list[j].last_pinged = temp_time; 798 friends_list[i].client_list[j].last_pinged = temp_time;
930 } 799 }
931 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ 800 if(friends_list[i].client_list[j].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ {
932 {
933 index[num_nodes] = j; 801 index[num_nodes] = j;
934 ++num_nodes; 802 ++num_nodes;
935 } 803 }
936 } 804 }
937 } 805 }
938 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) 806 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
939 {
940 rand_node = rand() % num_nodes; 807 rand_node = rand() % num_nodes;
941 getnodes(friends_list[i].client_list[index[rand_node]].ip_port, 808 getnodes(friends_list[i].client_list[index[rand_node]].ip_port,
942 friends_list[i].client_list[index[rand_node]].client_id, 809 friends_list[i].client_list[index[rand_node]].client_id,
@@ -958,66 +825,77 @@ void doClose() /* tested */
958 uint32_t rand_node; 825 uint32_t rand_node;
959 uint32_t index[LCLIENT_LIST]; 826 uint32_t index[LCLIENT_LIST];
960 827
961 for(i = 0; i < LCLIENT_LIST; ++i) 828 for(i = 0; i < LCLIENT_LIST; ++i) {
962 { 829 /* if node is not dead. */
963 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) /* if node is not dead. */ 830 if(close_clientlist[i].timestamp + Kill_NODE_TIMEOUT > temp_time) {
964 {
965 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) 831 if((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time)
966 { 832 {
967 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id); 833 pingreq(close_clientlist[i].ip_port, close_clientlist[i].client_id);
968 close_clientlist[i].last_pinged = temp_time; 834 close_clientlist[i].last_pinged = temp_time;
969 } 835 }
970 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) /* if node is good. */ 836 /* if node is good. */
971 { 837 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
972 index[num_nodes] = i; 838 index[num_nodes] = i;
973 ++num_nodes; 839 ++num_nodes;
974 } 840 }
975 } 841 }
976 } 842 }
977 843
978 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) 844 if(close_lastgetnodes + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
979 {
980 rand_node = rand() % num_nodes; 845 rand_node = rand() % num_nodes;
981 getnodes(close_clientlist[index[rand_node]].ip_port, 846 getnodes(close_clientlist[index[rand_node]].ip_port,
982 close_clientlist[index[rand_node]].client_id, 847 close_clientlist[index[rand_node]].client_id,
983 self_public_key); 848 self_public_key);
984 close_lastgetnodes = temp_time; 849 close_lastgetnodes = temp_time;
985 } 850 }
986
987}
988
989
990
991void doDHT()
992{
993 doClose();
994 doDHTFriends();
995} 851}
996 852
997
998
999void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) 853void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key)
1000{ 854{
1001 getnodes(ip_port, public_key, self_public_key); 855 getnodes(ip_port, public_key, self_public_key);
1002} 856}
1003 857
1004
1005
1006/* send the given packet to node with client_id 858/* send the given packet to node with client_id
1007 returns -1 if failure */ 859 returns -1 if failure */
1008int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 860int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
1009{ 861{
1010 uint32_t i; 862 uint32_t i;
1011 for(i = 0; i < LCLIENT_LIST; ++i) 863 for(i = 0; i < LCLIENT_LIST; ++i) {
1012 { 864 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0) {
1013 if(memcmp(client_id, close_clientlist[i].client_id, CLIENT_ID_SIZE) == 0)
1014 {
1015 return sendpacket(close_clientlist[i].ip_port, packet, length); 865 return sendpacket(close_clientlist[i].ip_port, packet, length);
1016 } 866 }
1017 } 867 }
1018 return -1; 868 return -1;
1019} 869}
1020 870
871/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist
872 ip_portlist must be at least MAX_FRIEND_CLIENTS big
873 returns the number of ips returned
874 return 0 if we are connected to friend or if no ips were found.
875 returns -1 if no such friend*/
876static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
877{
878 int num_ips = 0;
879 uint32_t i;
880 uint32_t temp_time = unix_time();
881 if(friend_num >= num_friends) {
882 return -1;
883 }
884 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i)
885 {
886 /*If ip is not zero and node is good */
887 if(friends_list[friend_num].client_list[i].ret_ip_port.ip.i != 0 &&
888 friends_list[friend_num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
889 if(memcmp(friends_list[friend_num].client_list[i].client_id, friends_list[friend_num].client_id, CLIENT_ID_SIZE) == 0 ) {
890 return 0;
891 }
892 ip_portlist[num_ips] = friends_list[friend_num].client_list[i].ret_ip_port;
893 ++num_ips;
894 }
895 }
896 return num_ips;
897}
898
1021/* Send the following packet to everyone who tells us they are connected to friend_id 899/* Send the following packet to everyone who tells us they are connected to friend_id
1022 returns the number of nodes it sent the packet to */ 900 returns the number of nodes it sent the packet to */
1023int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 901int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
@@ -1025,18 +903,14 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1025 uint32_t i, j; 903 uint32_t i, j;
1026 uint32_t sent = 0; 904 uint32_t sent = 0;
1027 uint32_t temp_time = unix_time(); 905 uint32_t temp_time = unix_time();
1028 for(i = 0; i < num_friends; ++i) 906 for(i = 0; i < num_friends; ++i) {
1029 { 907 /* Equal */
1030 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ 908 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
1031 { 909 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1032 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 910 /*If ip is not zero and node is good */
1033 {
1034 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 911 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 &&
1035 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 912 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
1036 /*If ip is not zero and node is good */ 913 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length) {
1037 {
1038 if(sendpacket(friends_list[i].client_list[j].ip_port, packet, length) == length)
1039 {
1040 ++sent; 914 ++sent;
1041 } 915 }
1042 } 916 }
@@ -1047,34 +921,255 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1047 return 0; 921 return 0;
1048} 922}
1049 923
924/* Send the following packet to one random person who tells us they are connected to friend_id
925 returns the number of nodes it sent the packet to */
926int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
927{
928 int num = friend_number(friend_id);
929 if(num == -1) {
930 return 0;
931 }
932
933 IP_Port ip_list[MAX_FRIEND_CLIENTS];
934 int n = 0;
935 uint32_t i;
936 uint32_t temp_time = unix_time();
937 for(i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
938 /*If ip is not zero and node is good */
939 if(friends_list[num].client_list[i].ret_ip_port.ip.i != 0 &&
940 friends_list[num].client_list[i].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) {
941 ip_list[n] = friends_list[num].client_list[i].ip_port;
942 ++n;
943 }
944 }
945 if(n < 1) {
946 return 0;
947 }
948 if(sendpacket(ip_list[rand() % n], packet, length) == length) {
949 return 1;
950 }
951 return 0;
952}
953
1050/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist 954/* Puts all the different ips returned by the nodes for a friend_id into array ip_portlist
1051 ip_portlist must be at least MAX_FRIEND_CLIENTS big 955 ip_portlist must be at least MAX_FRIEND_CLIENTS big
1052 returns the number of ips returned 956 returns the number of ips returned
957 return 0 if we are connected to friend or if no ips were found.
1053 returns -1 if no such friend*/ 958 returns -1 if no such friend*/
1054int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) 959int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id)
1055{ 960{
1056 int num_ips = 0; 961
962 uint32_t i;
963 for(i = 0; i < num_friends; ++i) {
964 /* Equal */
965 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) {
966 return friend_iplist(ip_portlist, i);
967 }
968 }
969 return -1;
970}
971
972/*BEGINNING OF NAT PUNCHING FUNCTIONS*/
973
974int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
975{
976 uint8_t data[sizeof(uint64_t) + 1];
977 data[0] = type;
978 memcpy(data + 1, &ping_id, sizeof(uint64_t));
979
980 uint8_t packet[MAX_DATA_SIZE];
981 int len = create_request(packet, public_key, data, sizeof(uint64_t) + 1, 254); /* 254 is NAT ping request packet id */
982 if(len == -1) {
983 return -1;
984 }
985 int num = 0;
986 if(type == 0) {
987 num = route_tofriend(public_key, packet, len);/*If packet is request use many people to route it*/
988 }
989 else if(type == 1) {
990 num = routeone_tofriend(public_key, packet, len);/*If packet is response use only one person to route it*/
991 }
992 if(num == 0) {
993 return -1;
994 }
995 return num;
996}
997
998/* Handle a recieved ping request for */
999int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source)
1000{
1001 if(length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
1002 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) {
1003 return 1;
1004 }
1005 /* check if request is for us. */
1006 if(memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1007 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
1008 uint8_t data[MAX_DATA_SIZE];
1009 int len = handle_request(public_key, data, packet, length);
1010 if(len != sizeof(uint64_t) + 1) {
1011 return 1;
1012 }
1013 uint64_t ping_id;
1014 memcpy(&ping_id, data + 1, sizeof(uint64_t));
1015
1016 int friendnumber = friend_number(public_key);
1017 if(friendnumber == -1) {
1018 return 1;
1019 }
1020
1021 if(data[0] == 0) {
1022 send_NATping(public_key, ping_id, 1);/*1 is reply*/
1023 return 0;
1024 } else if (data[0] == 1) {
1025 if(friends_list[friendnumber].NATping_id == ping_id)
1026 {
1027 friends_list[friendnumber].NATping_id = ((uint64_t)random_int() << 32) + random_int();
1028 friends_list[friendnumber].hole_punching = 1;
1029 return 0;
1030 }
1031 }
1032 return 1;
1033 }
1034 /* if request is not for us, try routing it. */
1035 else {
1036 if(route_packet(packet + 1, packet, length) == length) {
1037 return 0;
1038 }
1039 }
1040 return 0;
1041}
1042
1043/*Get the most common ip in the ip_portlist
1044 Only return ip if it appears in list min_num or more
1045 len must not be bigger than MAX_FRIEND_CLIENTS
1046 return ip of 0 if failure */
1047static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
1048{
1049 IP zero = {{0}};
1050 if(len > MAX_FRIEND_CLIENTS) {
1051 return zero;
1052 }
1053
1057 uint32_t i, j; 1054 uint32_t i, j;
1055 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
1056 for(i = 0; i < len; ++i) {
1057 for(j = 0; j < len; ++j) {
1058 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) {
1059 ++numbers[i];
1060 }
1061 }
1062 if(numbers[i] >= min_num) {
1063 return ip_portlist[i].ip;
1064 }
1065 }
1066 return zero;
1067}
1068
1069/*Return all the ports for one ip in a list
1070 portlist must be at least len long
1071 where len is the length of ip_portlist
1072 returns the number of ports and puts the list of ports in portlist*/
1073static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip)
1074{
1075 uint32_t i;
1076 uint16_t num = 0;
1077 for(i = 0; i < len; ++i) {
1078 if(ip_portlist[i].ip.i == ip.i) {
1079 portlist[num] = ntohs(ip_portlist[i].port);
1080 ++num;
1081 }
1082 }
1083 return num;
1084}
1085
1086#define MAX_PUNCHING_PORTS 32
1087
1088static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num)
1089{
1090 if(numports > MAX_FRIEND_CLIENTS || numports == 0) {
1091 return;
1092 }
1093 uint32_t i;
1094 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1095 for(i = friends_list[friend_num].punching_index; i != top; i++) {
1096 /*TODO: improve port guessing algorithm*/
1097 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1);
1098 IP_Port pinging = {ip, htons(port)};
1099 pingreq(pinging, friends_list[friend_num].client_id);
1100 }
1101 friends_list[friend_num].punching_index = i;
1102}
1103
1104/*Interval in seconds between punching attempts*/
1105#define PUNCH_INTERVAL 10
1106
1107static void doNAT()
1108{
1109 uint32_t i;
1058 uint32_t temp_time = unix_time(); 1110 uint32_t temp_time = unix_time();
1059 for(i = 0; i < num_friends; ++i) 1111 for(i = 0; i < num_friends; ++i) {
1060 { 1112 IP_Port ip_list[MAX_FRIEND_CLIENTS];
1061 if(memcmp(friends_list[i].client_id, friend_id, CLIENT_ID_SIZE) == 0) /* Equal */ 1113 int num = friend_iplist(ip_list, i);
1062 { 1114 /*If we are connected to friend or if friend is not online don't try to hole punch with him*/
1063 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1115 if(num < MAX_FRIEND_CLIENTS/2) {
1064 { 1116 continue;
1065 if(friends_list[i].client_list[j].ret_ip_port.ip.i != 0 && 1117 }
1066 friends_list[i].client_list[j].ret_timestamp + BAD_NODE_TIMEOUT > temp_time) 1118 if(friends_list[i].hole_punching != 1) {
1067 /*If ip is not zero and node is good */ 1119 if(friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1068 { 1120 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1069 ip_portlist[num_ips] = friends_list[i].client_list[j].ret_ip_port; 1121 friends_list[i].NATping_timestamp = temp_time;
1070 ++num_ips;
1071 }
1072 } 1122 }
1073 return num_ips;
1074 } 1123 }
1124 else if(friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time) {
1125 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1126 if(ip.i == 0) {
1127 continue;
1128 }
1129 uint16_t port_list[MAX_FRIEND_CLIENTS];
1130 uint16_t numports = NAT_getports(port_list, ip_list, num, ip);
1131 punch_holes(ip, port_list, numports, i);
1132
1133 friends_list[i].punching_timestamp = temp_time;
1134 friends_list[i].hole_punching = 0;
1135 }
1136 }
1137}
1138
1139/*END OF NAT PUNCHING FUNCTIONS*/
1140
1141int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source)
1142{
1143 switch (packet[0]) {
1144 case 0:
1145 return handle_pingreq(packet, length, source);
1146
1147 case 1:
1148 return handle_pingres(packet, length, source);
1149
1150 case 2:
1151 return handle_getnodes(packet, length, source);
1152
1153 case 3:
1154 return handle_sendnodes(packet, length, source);
1155
1156 case 254:
1157 return handle_NATping(packet, length, source);
1158
1159 default:
1160 return 1;
1075 1161
1076 } 1162 }
1163
1077 return 0; 1164 return 0;
1165
1166}
1167
1168void doDHT()
1169{
1170 doClose();
1171 doDHTFriends();
1172 doNAT();
1078} 1173}
1079 1174
1080/* get the size of the DHT (for saving) */ 1175/* get the size of the DHT (for saving) */
@@ -1095,12 +1190,10 @@ void DHT_save(uint8_t * data)
1095 return 0 if success */ 1190 return 0 if success */
1096int DHT_load(uint8_t * data, uint32_t size) 1191int DHT_load(uint8_t * data, uint32_t size)
1097{ 1192{
1098 if(size < sizeof(close_clientlist)) 1193 if(size < sizeof(close_clientlist)) {
1099 {
1100 return -1; 1194 return -1;
1101 } 1195 }
1102 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1196 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) {
1103 {
1104 return -1; 1197 return -1;
1105 } 1198 }
1106 uint32_t i, j; 1199 uint32_t i, j;
@@ -1109,17 +1202,13 @@ int DHT_load(uint8_t * data, uint32_t size)
1109 1202
1110 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1203 temp = (size - sizeof(close_clientlist))/sizeof(Friend);
1111 1204
1112 if(temp != 0) 1205 if(temp != 0) {
1113 {
1114 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1206 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1115 1207
1116 for(i = 0; i < temp; ++i) 1208 for(i = 0; i < temp; ++i) {
1117 {
1118 DHT_addfriend(tempfriends_list[i].client_id); 1209 DHT_addfriend(tempfriends_list[i].client_id);
1119 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) 1210 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1120 { 1211 if(tempfriends_list[i].client_list[j].timestamp != 0) {
1121 if(tempfriends_list[i].client_list[j].timestamp != 0)
1122 {
1123 getnodes(tempfriends_list[i].client_list[j].ip_port, 1212 getnodes(tempfriends_list[i].client_list[j].ip_port,
1124 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id); 1213 tempfriends_list[i].client_list[j].client_id, tempfriends_list[i].client_id);
1125 } 1214 }
@@ -1128,10 +1217,8 @@ int DHT_load(uint8_t * data, uint32_t size)
1128 } 1217 }
1129 Client_data * tempclose_clientlist = (Client_data *)data; 1218 Client_data * tempclose_clientlist = (Client_data *)data;
1130 1219
1131 for(i = 0; i < LCLIENT_LIST; ++i) 1220 for(i = 0; i < LCLIENT_LIST; ++i) {
1132 { 1221 if(tempclose_clientlist[i].timestamp != 0) {
1133 if(tempclose_clientlist[i].timestamp != 0)
1134 {
1135 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id); 1222 DHT_bootstrap(tempclose_clientlist[i].ip_port, tempclose_clientlist[i].client_id);
1136 } 1223 }
1137 } 1224 }
@@ -1144,13 +1231,10 @@ int DHT_isconnected()
1144{ 1231{
1145 uint32_t i; 1232 uint32_t i;
1146 uint32_t temp_time = unix_time(); 1233 uint32_t temp_time = unix_time();
1147 for(i = 0; i < LCLIENT_LIST; ++i) 1234 for(i = 0; i < LCLIENT_LIST; ++i) {
1148 { 1235 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) {
1149 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
1150 {
1151 return 1; 1236 return 1;
1152 } 1237 }
1153 } 1238 }
1154 return 0; 1239 return 0;
1155} 1240} \ No newline at end of file
1156