diff options
-rw-r--r-- | core/DHT.c | 812 |
1 files changed, 303 insertions, 509 deletions
@@ -62,14 +62,14 @@ | |||
62 | /*----------------------------------------------------------------------------------*/ | 62 | /*----------------------------------------------------------------------------------*/ |
63 | 63 | ||
64 | typedef struct { | 64 | typedef 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 | ||
75 | typedef struct { | 75 | typedef 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 | */ | 121 | int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2) /* tested */ |
122 | int 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 | */ | ||
146 | int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) | 138 | int 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 | */ | ||
171 | int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) | 164 | int 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*/ |
183 | static int friend_number(uint8_t * client_id) | 175 | static 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 | */ | ||
198 | int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) | 187 | int 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 | */ | 230 | int replace_bad(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) /* tested */ |
280 | int 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 */ |
304 | int replace_good( Client_data * list, | 249 | int 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 | */ | ||
330 | void addto_lists(IP_Port ip_port, uint8_t * client_id) | 269 | void 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 | */ | ||
372 | void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) | 288 | void 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 | */ | 314 | TODO: optimize this */ |
412 | int is_pinging(IP_Port ip_port, uint64_t ping_id) | 315 | int 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. */ |
435 | int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) | 339 | int 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 | */ | ||
463 | uint64_t add_pinging(IP_Port ip_port) | 367 | uint64_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 | */ | ||
506 | static int pingreq(IP_Port ip_port, uint8_t * public_key) | 406 | static 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) | |||
570 | static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) | 458 | static 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 */ |
610 | static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) | 493 | static 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. */ |
654 | int handle_pingreq(uint8_t * packet, uint32_t length, IP_Port source) | 532 | int 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 | ||
707 | int handle_getnodes(uint8_t * packet, uint32_t length, IP_Port source) | 576 | int 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 | ||
739 | int handle_sendnodes(uint8_t * packet, uint32_t length, IP_Port source) | 603 | int 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. */ |
824 | IP_Port DHT_getfriendip(uint8_t * client_id) | 683 | IP_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 | */ | ||
849 | void doDHTFriends() | 705 | void 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() | |||
883 | static uint32_t close_lastgetnodes; | 735 | static 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 | */ | 739 | void doClose() /* tested */ |
888 | void 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 | */ | ||
929 | int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) | 777 | int 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 | */ | ||
945 | static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) | 791 | static 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 | */ | ||
976 | int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | 812 | int 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 | */ | ||
1003 | int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) | 833 | int 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 | */ | ||
1039 | int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) | 862 | int 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) | |||
1053 | int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | 876 | int 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 */ |
1079 | int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | 899 | int 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 | */ | ||
1129 | static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) | 940 | static 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 | */ | ||
1154 | static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip) | 962 | static 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 | ||
1185 | static void doNAT() | 989 | static 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 | ||
1221 | int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | 1025 | int 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 | */ | ||
1271 | int DHT_load(uint8_t * data, uint32_t size) | 1074 | int 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 | */ | ||
1313 | int DHT_isconnected() | 1108 | int 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 | } |