summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-08-16 13:11:09 -0400
committerirungentoo <irungentoo@gmail.com>2013-08-16 13:11:09 -0400
commit88ff81d9def5efe69cbaf91aa41906177ba7dde9 (patch)
treecb9f149e438bcd1f18d8c1eb5d8be6b0a22f58a4 /core
parentc5af8f44a9d040a0bbe0442ec074d9fc8562dd32 (diff)
Passed everything through astyle.
Diffstat (limited to 'core')
-rw-r--r--core/DHT.c461
-rw-r--r--core/DHT.h8
-rw-r--r--core/LAN_discovery.c32
-rw-r--r--core/Lossless_UDP.c247
-rw-r--r--core/Lossless_UDP.h30
-rw-r--r--core/Messenger.c320
-rw-r--r--core/Messenger.h56
-rw-r--r--core/friend_requests.c23
-rw-r--r--core/friend_requests.h4
-rw-r--r--core/net_crypto.c131
-rw-r--r--core/net_crypto.h22
-rw-r--r--core/network.c44
-rw-r--r--core/ping.c68
-rw-r--r--core/ping.h8
-rw-r--r--core/timer.c99
-rw-r--r--core/timer.h38
-rw-r--r--core/util.c4
-rw-r--r--core/util.h4
18 files changed, 952 insertions, 647 deletions
diff --git a/core/DHT.c b/core/DHT.c
index c3249846..226a38ca 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -77,7 +77,7 @@ typedef struct {
77 /* Symetric NAT hole punching stuff */ 77 /* Symetric NAT hole punching stuff */
78 78
79 /* 1 if currently hole punching, otherwise 0 */ 79 /* 1 if currently hole punching, otherwise 0 */
80 uint8_t hole_punching; 80 uint8_t hole_punching;
81 uint32_t punching_index; 81 uint32_t punching_index;
82 uint64_t punching_timestamp; 82 uint64_t punching_timestamp;
83 uint64_t recvNATping_timestamp; 83 uint64_t recvNATping_timestamp;
@@ -98,11 +98,11 @@ typedef struct {
98 98
99/*----------------------------------------------------------------------------------*/ 99/*----------------------------------------------------------------------------------*/
100 100
101 /* Our client id/public key */ 101/* Our client id/public key */
102uint8_t self_public_key[CLIENT_ID_SIZE]; 102uint8_t self_public_key[CLIENT_ID_SIZE];
103uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 103uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
104static Client_data close_clientlist[LCLIENT_LIST]; 104static Client_data close_clientlist[LCLIENT_LIST];
105static Friend * friends_list; 105static Friend *friends_list;
106static uint16_t num_friends; 106static uint16_t num_friends;
107static Pinged send_nodes[LSEND_NODES_ARRAY]; 107static Pinged send_nodes[LSEND_NODES_ARRAY];
108static Node_format toping[MAX_TOPING]; 108static Node_format toping[MAX_TOPING];
@@ -111,7 +111,7 @@ static uint64_t last_toping;
111/*----------------------------------------------------------------------------------*/ 111/*----------------------------------------------------------------------------------*/
112 112
113 113
114Client_data * DHT_get_close_list(void) 114Client_data *DHT_get_close_list(void)
115{ 115{
116 return close_clientlist; 116 return close_clientlist;
117} 117}
@@ -121,37 +121,39 @@ Client_data * DHT_get_close_list(void)
121 * return 1 if client_id1 is closer 121 * return 1 if client_id1 is closer
122 * return 2 if client_id2 is closer 122 * return 2 if client_id2 is closer
123 */ 123 */
124static int id_closest(uint8_t * id, uint8_t * id1, uint8_t * id2) 124static int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2)
125{ 125{
126 size_t i; 126 size_t i;
127 uint8_t distance1, distance2; 127 uint8_t distance1, distance2;
128 128
129 for(i = 0; i < CLIENT_ID_SIZE; ++i) { 129 for (i = 0; i < CLIENT_ID_SIZE; ++i) {
130 130
131 distance1 = abs(id[i] ^ id1[i]); 131 distance1 = abs(id[i] ^ id1[i]);
132 distance2 = abs(id[i] ^ id2[i]); 132 distance2 = abs(id[i] ^ id2[i]);
133 133
134 if(distance1 < distance2) 134 if (distance1 < distance2)
135 return 1; 135 return 1;
136 if(distance1 > distance2) 136
137 if (distance1 > distance2)
137 return 2; 138 return 2;
138 } 139 }
140
139 return 0; 141 return 0;
140} 142}
141 143
142static int ipport_equal(IP_Port a, IP_Port b) 144static int ipport_equal(IP_Port a, IP_Port b)
143{ 145{
144 return (a.ip.i == b.ip.i) && (a.port == b.port); 146 return (a.ip.i == b.ip.i) && (a.port == b.port);
145} 147}
146 148
147static int id_equal(uint8_t* a, uint8_t* b) 149static int id_equal(uint8_t *a, uint8_t *b)
148{ 150{
149 return memcmp(a, b, CLIENT_ID_SIZE) == 0; 151 return memcmp(a, b, CLIENT_ID_SIZE) == 0;
150} 152}
151 153
152static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout) 154static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
153{ 155{
154 return timestamp + timeout <= time_now; 156 return timestamp + timeout <= time_now;
155} 157}
156 158
157/* check if client with client_id is already in list of length length. 159/* check if client with client_id is already in list of length length.
@@ -161,18 +163,18 @@ static int is_timeout(uint64_t time_now, uint64_t timestamp, uint64_t timeout)
161 * 163 *
162 * TODO: maybe optimize this. 164 * TODO: maybe optimize this.
163 */ 165 */
164static int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) 166static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id, IP_Port ip_port)
165{ 167{
166 uint32_t i; 168 uint32_t i;
167 uint64_t temp_time = unix_time(); 169 uint64_t temp_time = unix_time();
168 170
169 for(i = 0; i < length; ++i) { 171 for (i = 0; i < length; ++i) {
170 /*If ip_port is assigned to a different client_id replace it*/ 172 /*If ip_port is assigned to a different client_id replace it*/
171 if(ipport_equal(list[i].ip_port, ip_port)) { 173 if (ipport_equal(list[i].ip_port, ip_port)) {
172 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 174 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
173 } 175 }
174 176
175 if(id_equal(list[i].client_id, client_id)) { 177 if (id_equal(list[i].client_id, client_id)) {
176 /* Refresh the client timestamp. */ 178 /* Refresh the client timestamp. */
177 list[i].timestamp = temp_time; 179 list[i].timestamp = temp_time;
178 list[i].ip_port.ip.i = ip_port.ip.i; 180 list[i].ip_port.ip.i = ip_port.ip.i;
@@ -180,18 +182,19 @@ static int client_in_list(Client_data * list, uint32_t length, uint8_t * client_
180 return 1; 182 return 1;
181 } 183 }
182 } 184 }
185
183 return 0; 186 return 0;
184} 187}
185 188
186/* check if client with client_id is already in node format list of length length. 189/* check if client with client_id is already in node format list of length length.
187 * return True(1) or False(0) 190 * return True(1) or False(0)
188 */ 191 */
189static int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * client_id) 192static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id)
190{ 193{
191 uint32_t i; 194 uint32_t i;
192 195
193 for(i = 0; i < length; ++i) { 196 for (i = 0; i < length; ++i) {
194 if(id_equal(list[i].client_id, client_id)) 197 if (id_equal(list[i].client_id, client_id))
195 return 1; 198 return 1;
196 } 199 }
197 200
@@ -200,12 +203,12 @@ static int client_in_nodelist(Node_format * list, uint32_t length, uint8_t * cli
200 203
201/* Returns the friend number from the client_id, or -1 if a failure occurs 204/* Returns the friend number from the client_id, or -1 if a failure occurs
202 */ 205 */
203static int friend_number(uint8_t * client_id) 206static int friend_number(uint8_t *client_id)
204{ 207{
205 uint32_t i; 208 uint32_t i;
206 209
207 for(i = 0; i < num_friends; ++i) { 210 for (i = 0; i < num_friends; ++i) {
208 if(id_equal(friends_list[i].client_id, client_id)) 211 if (id_equal(friends_list[i].client_id, client_id))
209 return i; 212 return i;
210 } 213 }
211 214
@@ -217,7 +220,7 @@ static int friend_number(uint8_t * client_id)
217 * 220 *
218 * TODO: For the love of based Allah make this function cleaner and much more efficient. 221 * TODO: For the love of based Allah make this function cleaner and much more efficient.
219 */ 222 */
220static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 223static int get_close_nodes(uint8_t *client_id, Node_format *nodes_list)
221{ 224{
222 uint32_t i, j, k; 225 uint32_t i, j, k;
223 uint64_t temp_time = unix_time(); 226 uint64_t temp_time = unix_time();
@@ -228,13 +231,13 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
228 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id); 231 inlist = client_in_nodelist(nodes_list, MAX_SENT_NODES, close_clientlist[i].client_id);
229 232
230 /* if node isn't good or is already in list. */ 233 /* if node isn't good or is already in list. */
231 if(tout || inlist) 234 if (tout || inlist)
232 continue; 235 continue;
233 236
234 if(num_nodes < MAX_SENT_NODES) { 237 if (num_nodes < MAX_SENT_NODES) {
235 238
236 memcpy( nodes_list[num_nodes].client_id, 239 memcpy( nodes_list[num_nodes].client_id,
237 close_clientlist[i].client_id, 240 close_clientlist[i].client_id,
238 CLIENT_ID_SIZE ); 241 CLIENT_ID_SIZE );
239 242
240 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port; 243 nodes_list[num_nodes].ip_port = close_clientlist[i].ip_port;
@@ -242,13 +245,14 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
242 245
243 } else { 246 } else {
244 247
245 for(j = 0; j < MAX_SENT_NODES; ++j) { 248 for (j = 0; j < MAX_SENT_NODES; ++j) {
246 closest = id_closest( client_id, 249 closest = id_closest( client_id,
247 nodes_list[j].client_id, 250 nodes_list[j].client_id,
248 close_clientlist[i].client_id ); 251 close_clientlist[i].client_id );
249 if(closest == 2) { 252
250 memcpy( nodes_list[j].client_id, 253 if (closest == 2) {
251 close_clientlist[i].client_id, 254 memcpy( nodes_list[j].client_id,
255 close_clientlist[i].client_id,
252 CLIENT_ID_SIZE); 256 CLIENT_ID_SIZE);
253 257
254 nodes_list[j].ip_port = close_clientlist[i].ip_port; 258 nodes_list[j].ip_port = close_clientlist[i].ip_port;
@@ -258,35 +262,36 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
258 } 262 }
259 } 263 }
260 264
261 for(i = 0; i < num_friends; ++i) { 265 for (i = 0; i < num_friends; ++i) {
262 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 266 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
263 267
264 tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT); 268 tout = is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT);
265 inlist = client_in_nodelist( nodes_list, 269 inlist = client_in_nodelist( nodes_list,
266 MAX_SENT_NODES, 270 MAX_SENT_NODES,
267 friends_list[i].client_list[j].client_id); 271 friends_list[i].client_list[j].client_id);
268 272
269 /* if node isn't good or is already in list. */ 273 /* if node isn't good or is already in list. */
270 if(tout || inlist) 274 if (tout || inlist)
271 continue; 275 continue;
272 276
273 if(num_nodes < MAX_SENT_NODES) { 277 if (num_nodes < MAX_SENT_NODES) {
274 278
275 memcpy( nodes_list[num_nodes].client_id, 279 memcpy( nodes_list[num_nodes].client_id,
276 friends_list[i].client_list[j].client_id, 280 friends_list[i].client_list[j].client_id,
277 CLIENT_ID_SIZE); 281 CLIENT_ID_SIZE);
278 282
279 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port; 283 nodes_list[num_nodes].ip_port = friends_list[i].client_list[j].ip_port;
280 num_nodes++; 284 num_nodes++;
281 } else { 285 } else {
282 for(k = 0; k < MAX_SENT_NODES; ++k) { 286 for (k = 0; k < MAX_SENT_NODES; ++k) {
283 287
284 closest = id_closest( client_id, 288 closest = id_closest( client_id,
285 nodes_list[k].client_id, 289 nodes_list[k].client_id,
286 friends_list[i].client_list[j].client_id ); 290 friends_list[i].client_list[j].client_id );
287 if(closest == 2) { 291
288 memcpy( nodes_list[k].client_id, 292 if (closest == 2) {
289 friends_list[i].client_list[j].client_id, 293 memcpy( nodes_list[k].client_id,
294 friends_list[i].client_list[j].client_id,
290 CLIENT_ID_SIZE ); 295 CLIENT_ID_SIZE );
291 296
292 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port; 297 nodes_list[k].ip_port = friends_list[i].client_list[j].ip_port;
@@ -296,6 +301,7 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
296 } 301 }
297 } 302 }
298 } 303 }
304
299 return num_nodes; 305 return num_nodes;
300} 306}
301 307
@@ -303,16 +309,17 @@ static int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
303 * return 0 if successful 309 * return 0 if successful
304 * return 1 if not (list contains no bad nodes) 310 * return 1 if not (list contains no bad nodes)
305 */ 311 */
306static int replace_bad( Client_data * list, 312static int replace_bad( Client_data *list,
307 uint32_t length, 313 uint32_t length,
308 uint8_t * client_id, 314 uint8_t *client_id,
309 IP_Port ip_port ) 315 IP_Port ip_port )
310{ 316{
311 uint32_t i; 317 uint32_t i;
312 uint64_t temp_time = unix_time(); 318 uint64_t temp_time = unix_time();
313 for(i = 0; i < length; ++i) { 319
320 for (i = 0; i < length; ++i) {
314 /* if node is bad */ 321 /* if node is bad */
315 if(is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) { 322 if (is_timeout(temp_time, list[i].timestamp, BAD_NODE_TIMEOUT)) {
316 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 323 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
317 list[i].ip_port = ip_port; 324 list[i].ip_port = ip_port;
318 list[i].timestamp = temp_time; 325 list[i].timestamp = temp_time;
@@ -325,42 +332,46 @@ static int replace_bad( Client_data * list,
325 332
326 return 1; 333 return 1;
327} 334}
328/*Sort the list. It will be sorted from furthest to closest. 335/*Sort the list. It will be sorted from furthest to closest.
329 TODO: this is innefficient and needs to be optimized.*/ 336 TODO: this is innefficient and needs to be optimized.*/
330static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) 337static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id)
331{ 338{
332 if(length == 0) 339 if (length == 0)
333 return; 340 return;
341
334 uint32_t i, count; 342 uint32_t i, count;
335 while(1) { 343
344 while (1) {
336 count = 0; 345 count = 0;
337 for(i = 0; i < (length - 1); ++i) { 346
338 if(id_closest(comp_client_id, list[i].client_id, list[i + 1].client_id) == 1) { 347 for (i = 0; i < (length - 1); ++i) {
348 if (id_closest(comp_client_id, list[i].client_id, list[i + 1].client_id) == 1) {
339 Client_data temp = list[i + 1]; 349 Client_data temp = list[i + 1];
340 list[i + 1] = list[i]; 350 list[i + 1] = list[i];
341 list[i] = temp; 351 list[i] = temp;
342 ++count; 352 ++count;
343 } 353 }
344 } 354 }
345 if(count == 0) 355
356 if (count == 0)
346 return; 357 return;
347 } 358 }
348} 359}
349 360
350 361
351/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */ 362/* replace the first good node that is further to the comp_client_id than that of the client_id in the list */
352static int replace_good( Client_data * list, 363static int replace_good( Client_data *list,
353 uint32_t length, 364 uint32_t length,
354 uint8_t * client_id, 365 uint8_t *client_id,
355 IP_Port ip_port, 366 IP_Port ip_port,
356 uint8_t * comp_client_id ) 367 uint8_t *comp_client_id )
357{ 368{
358 uint32_t i; 369 uint32_t i;
359 uint64_t temp_time = unix_time(); 370 uint64_t temp_time = unix_time();
360 sort_list(list, length, comp_client_id); 371 sort_list(list, length, comp_client_id);
361 372
362 for(i = 0; i < length; ++i) 373 for (i = 0; i < length; ++i)
363 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { 374 if (id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
364 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); 375 memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
365 list[i].ip_port = ip_port; 376 list[i].ip_port = ip_port;
366 list[i].timestamp = temp_time; 377 list[i].timestamp = temp_time;
@@ -373,42 +384,42 @@ static int replace_good( Client_data * list,
373 return 1; 384 return 1;
374} 385}
375 386
376/* Attempt to add client with ip_port and client_id to the friends client list 387/* Attempt to add client with ip_port and client_id to the friends client list
377 * and close_clientlist 388 * and close_clientlist
378 */ 389 */
379void addto_lists(IP_Port ip_port, uint8_t * client_id) 390void addto_lists(IP_Port ip_port, uint8_t *client_id)
380{ 391{
381 uint32_t i; 392 uint32_t i;
382 393
383 /* NOTE: current behavior if there are two clients with the same id is 394 /* NOTE: current behavior if there are two clients with the same id is
384 * to replace the first ip by the second. 395 * to replace the first ip by the second.
385 */ 396 */
386 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 397 if (!client_in_list(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
387 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 398 if (replace_bad(close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
388 /* if we can't replace bad nodes we try replacing good ones */ 399 /* if we can't replace bad nodes we try replacing good ones */
389 replace_good( close_clientlist, 400 replace_good( close_clientlist,
390 LCLIENT_LIST, 401 LCLIENT_LIST,
391 client_id, 402 client_id,
392 ip_port, 403 ip_port,
393 self_public_key ); 404 self_public_key );
394 } 405 }
395 } 406 }
396 407
397 for (i = 0; i < num_friends; ++i) { 408 for (i = 0; i < num_friends; ++i) {
398 if (!client_in_list( friends_list[i].client_list, 409 if (!client_in_list( friends_list[i].client_list,
399 MAX_FRIEND_CLIENTS, 410 MAX_FRIEND_CLIENTS,
400 client_id, 411 client_id,
401 ip_port )) { 412 ip_port )) {
402 413
403 if (replace_bad( friends_list[i].client_list, 414 if (replace_bad( friends_list[i].client_list,
404 MAX_FRIEND_CLIENTS, 415 MAX_FRIEND_CLIENTS,
405 client_id, 416 client_id,
406 ip_port )) { 417 ip_port )) {
407 /* if we can't replace bad nodes we try replacing good ones. */ 418 /* if we can't replace bad nodes we try replacing good ones. */
408 replace_good( friends_list[i].client_list, 419 replace_good( friends_list[i].client_list,
409 MAX_FRIEND_CLIENTS, 420 MAX_FRIEND_CLIENTS,
410 client_id, 421 client_id,
411 ip_port, 422 ip_port,
412 friends_list[i].client_id ); 423 friends_list[i].client_id );
413 } 424 }
414 } 425 }
@@ -418,7 +429,7 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
418/* If client_id is a friend or us, update ret_ip_port 429/* If client_id is a friend or us, update ret_ip_port
419 * nodeclient_id is the id of the node that sent us this info 430 * nodeclient_id is the id of the node that sent us this info
420 */ 431 */
421static void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) 432static void returnedip_ports(IP_Port ip_port, uint8_t *client_id, uint8_t *nodeclient_id)
422{ 433{
423 uint32_t i, j; 434 uint32_t i, j;
424 uint64_t temp_time = unix_time(); 435 uint64_t temp_time = unix_time();
@@ -458,17 +469,17 @@ static int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
458 uint8_t pinging; 469 uint8_t pinging;
459 uint64_t temp_time = unix_time(); 470 uint64_t temp_time = unix_time();
460 471
461 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) { 472 for (i = 0; i < LSEND_NODES_ARRAY; ++i ) {
462 if(!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) { 473 if (!is_timeout(temp_time, send_nodes[i].timestamp, PING_TIMEOUT)) {
463 pinging = 0; 474 pinging = 0;
464 475
465 if(ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port)) 476 if (ip_port.ip.i != 0 && ipport_equal(send_nodes[i].ip_port, ip_port))
466 ++pinging; 477 ++pinging;
467 478
468 if(ping_id != 0 && send_nodes[i].ping_id == ping_id) 479 if (ping_id != 0 && send_nodes[i].ping_id == ping_id)
469 ++pinging; 480 ++pinging;
470 481
471 if(pinging == (ping_id != 0) + (ip_port.ip.i != 0)) 482 if (pinging == (ping_id != 0) + (ip_port.ip.i != 0))
472 return 1; 483 return 1;
473 } 484 }
474 } 485 }
@@ -483,9 +494,9 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
483 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 494 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
484 uint64_t temp_time = unix_time(); 495 uint64_t temp_time = unix_time();
485 496
486 for(i = 0; i < PING_TIMEOUT; ++i ) { 497 for (i = 0; i < PING_TIMEOUT; ++i ) {
487 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) { 498 for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
488 if(is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) { 499 if (is_timeout(temp_time, send_nodes[j].timestamp, PING_TIMEOUT - i)) {
489 send_nodes[j].timestamp = temp_time; 500 send_nodes[j].timestamp = temp_time;
490 send_nodes[j].ip_port = ip_port; 501 send_nodes[j].ip_port = ip_port;
491 send_nodes[j].ping_id = ping_id; 502 send_nodes[j].ping_id = ping_id;
@@ -498,15 +509,15 @@ static uint64_t add_gettingnodes(IP_Port ip_port)
498} 509}
499 510
500/* send a getnodes request */ 511/* send a getnodes request */
501static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id) 512static int getnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id)
502{ 513{
503 /* check if packet is gonna be sent to ourself */ 514 /* check if packet is gonna be sent to ourself */
504 if(id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0)) 515 if (id_equal(public_key, self_public_key) || is_gettingnodes(ip_port, 0))
505 return 1; 516 return 1;
506 517
507 uint64_t ping_id = add_gettingnodes(ip_port); 518 uint64_t ping_id = add_gettingnodes(ip_port);
508 519
509 if(ping_id == 0) 520 if (ping_id == 0)
510 return 1; 521 return 1;
511 522
512 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 523 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
@@ -518,14 +529,14 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
518 memcpy(plain, &ping_id, sizeof(ping_id)); 529 memcpy(plain, &ping_id, sizeof(ping_id));
519 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 530 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
520 531
521 int len = encrypt_data( public_key, 532 int len = encrypt_data( public_key,
522 self_secret_key, 533 self_secret_key,
523 nonce, 534 nonce,
524 plain, 535 plain,
525 sizeof(ping_id) + CLIENT_ID_SIZE, 536 sizeof(ping_id) + CLIENT_ID_SIZE,
526 encrypt ); 537 encrypt );
527 538
528 if(len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 539 if (len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING)
529 return -1; 540 return -1;
530 541
531 data[0] = 2; 542 data[0] = 2;
@@ -537,10 +548,10 @@ static int getnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id)
537} 548}
538 549
539/* send a send nodes response */ 550/* send a send nodes response */
540static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id, uint64_t ping_id) 551static int sendnodes(IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id)
541{ 552{
542 /* check if packet is gonna be sent to ourself */ 553 /* check if packet is gonna be sent to ourself */
543 if(id_equal(public_key, self_public_key)) 554 if (id_equal(public_key, self_public_key))
544 return 1; 555 return 1;
545 556
546 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 557 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id)
@@ -549,7 +560,7 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
549 Node_format nodes_list[MAX_SENT_NODES]; 560 Node_format nodes_list[MAX_SENT_NODES];
550 int num_nodes = get_close_nodes(client_id, nodes_list); 561 int num_nodes = get_close_nodes(client_id, nodes_list);
551 562
552 if(num_nodes == 0) 563 if (num_nodes == 0)
553 return 0; 564 return 0;
554 565
555 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 566 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
@@ -560,14 +571,14 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
560 memcpy(plain, &ping_id, sizeof(ping_id)); 571 memcpy(plain, &ping_id, sizeof(ping_id));
561 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format)); 572 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));
562 573
563 int len = encrypt_data( public_key, 574 int len = encrypt_data( public_key,
564 self_secret_key, 575 self_secret_key,
565 nonce, 576 nonce,
566 plain, 577 plain,
567 sizeof(ping_id) + num_nodes * sizeof(Node_format), 578 sizeof(ping_id) + num_nodes * sizeof(Node_format),
568 encrypt ); 579 encrypt );
569 580
570 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING) 581 if (len != sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING)
571 return -1; 582 return -1;
572 583
573 data[0] = 3; 584 data[0] = 3;
@@ -578,11 +589,11 @@ static int sendnodes(IP_Port ip_port, uint8_t * public_key, uint8_t * client_id,
578 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 589 return sendpacket(ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
579} 590}
580 591
581static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length) 592static int handle_getnodes(IP_Port source, uint8_t *packet, uint32_t length)
582{ 593{
583 uint64_t ping_id; 594 uint64_t ping_id;
584 595
585 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 596 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
586 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING )) 597 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING ))
587 return 1; 598 return 1;
588 599
@@ -592,11 +603,11 @@ static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length)
592 603
593 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 604 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
594 605
595 int len = decrypt_data( packet + 1, 606 int len = decrypt_data( packet + 1,
596 self_secret_key, 607 self_secret_key,
597 packet + 1 + CLIENT_ID_SIZE, 608 packet + 1 + CLIENT_ID_SIZE,
598 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 609 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
599 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, 610 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING,
600 plain ); 611 plain );
601 612
602 if (len != sizeof(ping_id) + CLIENT_ID_SIZE) 613 if (len != sizeof(ping_id) + CLIENT_ID_SIZE)
@@ -610,32 +621,33 @@ static int handle_getnodes(IP_Port source, uint8_t * packet, uint32_t length)
610 return 0; 621 return 0;
611} 622}
612 623
613static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length) 624static int handle_sendnodes(IP_Port source, uint8_t *packet, uint32_t length)
614{ 625{
615 uint64_t ping_id; 626 uint64_t ping_id;
616 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 627 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
617 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 628 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING;
618 629
619 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) || 630 if (length > (cid_size + sizeof(Node_format) * MAX_SENT_NODES) ||
620 ((length - cid_size) % sizeof(Node_format)) != 0 || 631 ((length - cid_size) % sizeof(Node_format)) != 0 ||
621 (length < cid_size + sizeof(Node_format))) 632 (length < cid_size + sizeof(Node_format)))
622 return 1; 633 return 1;
623 634
624 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format); 635 uint32_t num_nodes = (length - cid_size) / sizeof(Node_format);
625 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES]; 636 uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
626 637
627 int len = decrypt_data( 638 int len = decrypt_data(
628 packet + 1, 639 packet + 1,
629 self_secret_key, 640 self_secret_key,
630 packet + 1 + CLIENT_ID_SIZE, 641 packet + 1 + CLIENT_ID_SIZE,
631 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 642 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
632 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain ); 643 sizeof(ping_id) + num_nodes * sizeof(Node_format) + ENCRYPTION_PADDING, plain );
633 644
634 if(len != sizeof(ping_id) + num_nodes * sizeof(Node_format)) 645 if (len != sizeof(ping_id) + num_nodes * sizeof(Node_format))
635 return 1; 646 return 1;
636 647
637 memcpy(&ping_id, plain, sizeof(ping_id)); 648 memcpy(&ping_id, plain, sizeof(ping_id));
638 if(!is_gettingnodes(source, ping_id)) 649
650 if (!is_gettingnodes(source, ping_id))
639 return 1; 651 return 1;
640 652
641 Node_format nodes_list[MAX_SENT_NODES]; 653 Node_format nodes_list[MAX_SENT_NODES];
@@ -644,8 +656,9 @@ static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length)
644 addto_lists(source, packet + 1); 656 addto_lists(source, packet + 1);
645 657
646 uint32_t i; 658 uint32_t i;
647 for(i = 0; i < num_nodes; ++i) { 659
648 send_ping_request(nodes_list[i].ip_port, (clientid_t*) &nodes_list[i].client_id); 660 for (i = 0; i < num_nodes; ++i) {
661 send_ping_request(nodes_list[i].ip_port, (clientid_t *) &nodes_list[i].client_id);
649 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); 662 returnedip_ports(nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1);
650 } 663 }
651 664
@@ -655,12 +668,14 @@ static int handle_sendnodes(IP_Port source, uint8_t * packet, uint32_t length)
655/*----------------------------------------------------------------------------------*/ 668/*----------------------------------------------------------------------------------*/
656/*------------------------END of packet handling functions--------------------------*/ 669/*------------------------END of packet handling functions--------------------------*/
657 670
658int DHT_addfriend(uint8_t * client_id) 671int DHT_addfriend(uint8_t *client_id)
659{ 672{
660 if(friend_number(client_id) != -1) /*Is friend already in DHT?*/ 673 if (friend_number(client_id) != -1) /*Is friend already in DHT?*/
661 return 1; 674 return 1;
662 Friend * temp; 675
676 Friend *temp;
663 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1)); 677 temp = realloc(friends_list, sizeof(Friend) * (num_friends + 1));
678
664 if (temp == NULL) 679 if (temp == NULL)
665 return 1; 680 return 1;
666 681
@@ -673,22 +688,24 @@ int DHT_addfriend(uint8_t * client_id)
673 return 0; 688 return 0;
674} 689}
675 690
676int DHT_delfriend(uint8_t * client_id) 691int DHT_delfriend(uint8_t *client_id)
677{ 692{
678 uint32_t i; 693 uint32_t i;
679 Friend * temp; 694 Friend *temp;
695
680 for (i = 0; i < num_friends; ++i) { 696 for (i = 0; i < num_friends; ++i) {
681 /* Equal */ 697 /* Equal */
682 if (id_equal(friends_list[i].client_id, client_id)) { 698 if (id_equal(friends_list[i].client_id, client_id)) {
683 --num_friends; 699 --num_friends;
684 700
685 if (num_friends != i) { 701 if (num_friends != i) {
686 memcpy( friends_list[i].client_id, 702 memcpy( friends_list[i].client_id,
687 friends_list[num_friends].client_id, 703 friends_list[num_friends].client_id,
688 CLIENT_ID_SIZE ); 704 CLIENT_ID_SIZE );
689 } 705 }
690 706
691 temp = realloc(friends_list, sizeof(Friend) * (num_friends)); 707 temp = realloc(friends_list, sizeof(Friend) * (num_friends));
708
692 if (temp == NULL) 709 if (temp == NULL)
693 return 1; 710 return 1;
694 711
@@ -701,7 +718,7 @@ int DHT_delfriend(uint8_t * client_id)
701} 718}
702 719
703/* TODO: Optimize this. */ 720/* TODO: Optimize this. */
704IP_Port DHT_getfriendip(uint8_t * client_id) 721IP_Port DHT_getfriendip(uint8_t *client_id)
705{ 722{
706 uint32_t i, j; 723 uint32_t i, j;
707 uint64_t temp_time = unix_time(); 724 uint64_t temp_time = unix_time();
@@ -711,18 +728,21 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
711 /* Equal */ 728 /* Equal */
712 if (id_equal(friends_list[i].client_id, client_id)) { 729 if (id_equal(friends_list[i].client_id, client_id)) {
713 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 730 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
714 if (id_equal(friends_list[i].client_list[j].client_id, client_id) && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) 731 if (id_equal(friends_list[i].client_list[j].client_id, client_id)
732 && !is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT))
715 return friends_list[i].client_list[j].ip_port; 733 return friends_list[i].client_list[j].ip_port;
716 } 734 }
735
717 return empty; 736 return empty;
718 } 737 }
719 } 738 }
739
720 empty.ip.i = 1; 740 empty.ip.i = 1;
721 return empty; 741 return empty;
722} 742}
723 743
724/* Ping each client in the "friends" list every 60 seconds. Send a get nodes request 744/* Ping each client in the "friends" list every 60 seconds. Send a get nodes request
725 * every 20 seconds to a random good node for each "friend" in our "friends" list. 745 * every 20 seconds to a random good node for each "friend" in our "friends" list.
726 */ 746 */
727static void doDHTFriends(void) 747static void doDHTFriends(void)
728{ 748{
@@ -733,22 +753,25 @@ static void doDHTFriends(void)
733 753
734 for (i = 0; i < num_friends; ++i) { 754 for (i = 0; i < num_friends; ++i) {
735 uint32_t num_nodes = 0; 755 uint32_t num_nodes = 0;
756
736 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 757 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
737 /* if node is not dead. */ 758 /* if node is not dead. */
738 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) { 759 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, Kill_NODE_TIMEOUT)) {
739 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) { 760 if ((friends_list[i].client_list[j].last_pinged + PING_INTERVAL) <= temp_time) {
740 send_ping_request( friends_list[i].client_list[j].ip_port, 761 send_ping_request( friends_list[i].client_list[j].ip_port,
741 (clientid_t*) &friends_list[i].client_list[j].client_id ); 762 (clientid_t *) &friends_list[i].client_list[j].client_id );
742 friends_list[i].client_list[j].last_pinged = temp_time; 763 friends_list[i].client_list[j].last_pinged = temp_time;
743 } 764 }
765
744 /* if node is good. */ 766 /* if node is good. */
745 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { 767 if (!is_timeout(temp_time, friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) {
746 index[num_nodes] = j; 768 index[num_nodes] = j;
747 ++num_nodes; 769 ++num_nodes;
748 } 770 }
749 } 771 }
750 } 772 }
751 if(friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) { 773
774 if (friends_list[i].lastgetnode + GET_NODE_INTERVAL <= temp_time && num_nodes != 0) {
752 rand_node = rand() % num_nodes; 775 rand_node = rand() % num_nodes;
753 getnodes( friends_list[i].client_list[index[rand_node]].ip_port, 776 getnodes( friends_list[i].client_list[index[rand_node]].ip_port,
754 friends_list[i].client_list[index[rand_node]].client_id, 777 friends_list[i].client_list[index[rand_node]].client_id,
@@ -775,10 +798,11 @@ static void doClose(void)
775 /* if node is not dead. */ 798 /* if node is not dead. */
776 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) { 799 if (!is_timeout(temp_time, close_clientlist[i].timestamp, Kill_NODE_TIMEOUT)) {
777 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) { 800 if ((close_clientlist[i].last_pinged + PING_INTERVAL) <= temp_time) {
778 send_ping_request( close_clientlist[i].ip_port, 801 send_ping_request( close_clientlist[i].ip_port,
779 (clientid_t*) &close_clientlist[i].client_id ); 802 (clientid_t *) &close_clientlist[i].client_id );
780 close_clientlist[i].last_pinged = temp_time; 803 close_clientlist[i].last_pinged = temp_time;
781 } 804 }
805
782 /* if node is good. */ 806 /* if node is good. */
783 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) { 807 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) {
784 index[num_nodes] = i; 808 index[num_nodes] = i;
@@ -796,15 +820,15 @@ static void doClose(void)
796 } 820 }
797} 821}
798 822
799void DHT_bootstrap(IP_Port ip_port, uint8_t * public_key) 823void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key)
800{ 824{
801 getnodes(ip_port, public_key, self_public_key); 825 getnodes(ip_port, public_key, self_public_key);
802} 826}
803 827
804/* send the given packet to node with client_id 828/* send the given packet to node with client_id
805 * returns -1 if failure 829 * returns -1 if failure
806 */ 830 */
807int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length) 831int route_packet(uint8_t *client_id, uint8_t *packet, uint32_t length)
808{ 832{
809 uint32_t i; 833 uint32_t i;
810 834
@@ -822,17 +846,17 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
822 * return 0 if we are connected to friend or if no ips were found. 846 * return 0 if we are connected to friend or if no ips were found.
823 * returns -1 if no such friend 847 * returns -1 if no such friend
824 */ 848 */
825static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) 849static int friend_iplist(IP_Port *ip_portlist, uint16_t friend_num)
826{ 850{
827 int num_ips = 0; 851 int num_ips = 0;
828 uint32_t i; 852 uint32_t i;
829 uint64_t temp_time = unix_time(); 853 uint64_t temp_time = unix_time();
830 854
831 if (friend_num >= num_friends) 855 if (friend_num >= num_friends)
832 return -1; 856 return -1;
833 857
834 Friend * friend = &friends_list[friend_num]; 858 Friend *friend = &friends_list[friend_num];
835 Client_data * client; 859 Client_data *client;
836 860
837 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 861 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
838 client = &friend->client_list[i]; 862 client = &friend->client_list[i];
@@ -847,22 +871,24 @@ static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
847 ++num_ips; 871 ++num_ips;
848 } 872 }
849 } 873 }
874
850 return num_ips; 875 return num_ips;
851} 876}
852 877
853/* Send the following packet to everyone who tells us they are connected to friend_id 878/* Send the following packet to everyone who tells us they are connected to friend_id
854 * returns the number of nodes it sent the packet to 879 * returns the number of nodes it sent the packet to
855 */ 880 */
856int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 881int route_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
857{ 882{
858 int num = friend_number(friend_id); 883 int num = friend_number(friend_id);
884
859 if (num == -1) 885 if (num == -1)
860 return 0; 886 return 0;
861 887
862 uint32_t i, sent = 0; 888 uint32_t i, sent = 0;
863 uint64_t temp_time = unix_time(); 889 uint64_t temp_time = unix_time();
864 Friend * friend = &friends_list[num]; 890 Friend *friend = &friends_list[num];
865 Client_data * client; 891 Client_data *client;
866 892
867 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 893 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
868 client = &friend->client_list[i]; 894 client = &friend->client_list[i];
@@ -874,20 +900,22 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
874 ++sent; 900 ++sent;
875 } 901 }
876 } 902 }
903
877 return sent; 904 return sent;
878} 905}
879 906
880/* Send the following packet to one random person who tells us they are connected to friend_id 907/* Send the following packet to one random person who tells us they are connected to friend_id
881* returns the number of nodes it sent the packet to 908* returns the number of nodes it sent the packet to
882*/ 909*/
883static int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length) 910static int routeone_tofriend(uint8_t *friend_id, uint8_t *packet, uint32_t length)
884{ 911{
885 int num = friend_number(friend_id); 912 int num = friend_number(friend_id);
913
886 if (num == -1) 914 if (num == -1)
887 return 0; 915 return 0;
888 916
889 Friend * friend = &friends_list[num]; 917 Friend *friend = &friends_list[num];
890 Client_data * client; 918 Client_data *client;
891 919
892 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 920 IP_Port ip_list[MAX_FRIEND_CLIENTS];
893 int n = 0; 921 int n = 0;
@@ -898,15 +926,18 @@ static int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t len
898 client = &friend->client_list[i]; 926 client = &friend->client_list[i];
899 927
900 /*If ip is not zero and node is good */ 928 /*If ip is not zero and node is good */
901 if(client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { 929 if (client->ret_ip_port.ip.i != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) {
902 ip_list[n] = client->ip_port; 930 ip_list[n] = client->ip_port;
903 ++n; 931 ++n;
904 } 932 }
905 } 933 }
934
906 if (n < 1) 935 if (n < 1)
907 return 0; 936 return 0;
937
908 if (sendpacket(ip_list[rand() % n], packet, length) == length) 938 if (sendpacket(ip_list[rand() % n], packet, length) == length)
909 return 1; 939 return 1;
940
910 return 0; 941 return 0;
911} 942}
912 943
@@ -916,21 +947,23 @@ static int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t len
916 * return 0 if we are connected to friend or if no ips were found. 947 * return 0 if we are connected to friend or if no ips were found.
917 * returns -1 if no such friend 948 * returns -1 if no such friend
918 */ 949 */
919int friend_ips(IP_Port * ip_portlist, uint8_t * friend_id) 950int friend_ips(IP_Port *ip_portlist, uint8_t *friend_id)
920{ 951{
921 uint32_t i; 952 uint32_t i;
953
922 for (i = 0; i < num_friends; ++i) { 954 for (i = 0; i < num_friends; ++i) {
923 /* Equal */ 955 /* Equal */
924 if (id_equal(friends_list[i].client_id, friend_id)) 956 if (id_equal(friends_list[i].client_id, friend_id))
925 return friend_iplist(ip_portlist, i); 957 return friend_iplist(ip_portlist, i);
926 } 958 }
959
927 return -1; 960 return -1;
928} 961}
929 962
930/*----------------------------------------------------------------------------------*/ 963/*----------------------------------------------------------------------------------*/
931/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ 964/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/
932 965
933static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) 966static int send_NATping(uint8_t *public_key, uint64_t ping_id, uint8_t type)
934{ 967{
935 uint8_t data[sizeof(uint64_t) + 1]; 968 uint8_t data[sizeof(uint64_t) + 1];
936 uint8_t packet[MAX_DATA_SIZE]; 969 uint8_t packet[MAX_DATA_SIZE];
@@ -952,20 +985,22 @@ static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type)
952 985
953 if (num == 0) 986 if (num == 0)
954 return -1; 987 return -1;
988
955 return num; 989 return num;
956} 990}
957 991
958/* Handle a received ping request for */ 992/* Handle a received ping request for */
959static int handle_NATping(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) 993static int handle_NATping(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
960{ 994{
961 uint64_t ping_id; 995 uint64_t ping_id;
962 memcpy(&ping_id, packet + 1, sizeof(uint64_t)); 996 memcpy(&ping_id, packet + 1, sizeof(uint64_t));
963 997
964 int friendnumber = friend_number(source_pubkey); 998 int friendnumber = friend_number(source_pubkey);
999
965 if (friendnumber == -1) 1000 if (friendnumber == -1)
966 return 1; 1001 return 1;
967 1002
968 Friend * friend = &friends_list[friendnumber]; 1003 Friend *friend = &friends_list[friendnumber];
969 1004
970 if (packet[0] == 0) { 1005 if (packet[0] == 0) {
971 /* 1 is reply */ 1006 /* 1 is reply */
@@ -979,31 +1014,35 @@ static int handle_NATping(IP_Port source, uint8_t * source_pubkey, uint8_t * pac
979 return 0; 1014 return 0;
980 } 1015 }
981 } 1016 }
1017
982 return 1; 1018 return 1;
983} 1019}
984 1020
985/* Get the most common ip in the ip_portlist 1021/* Get the most common ip in the ip_portlist
986 * Only return ip if it appears in list min_num or more 1022 * Only return ip if it appears in list min_num or more
987 * len must not be bigger than MAX_FRIEND_CLIENTS 1023 * len must not be bigger than MAX_FRIEND_CLIENTS
988 * return ip of 0 if failure 1024 * return ip of 0 if failure
989 */ 1025 */
990static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num) 1026static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
991{ 1027{
992 IP zero = {{0}}; 1028 IP zero = {{0}};
993 if(len > MAX_FRIEND_CLIENTS) 1029
1030 if (len > MAX_FRIEND_CLIENTS)
994 return zero; 1031 return zero;
995 1032
996 uint32_t i, j; 1033 uint32_t i, j;
997 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0}; 1034 uint16_t numbers[MAX_FRIEND_CLIENTS] = {0};
998 1035
999 for(i = 0; i < len; ++i) { 1036 for (i = 0; i < len; ++i) {
1000 for(j = 0; j < len; ++j) { 1037 for (j = 0; j < len; ++j) {
1001 if(ip_portlist[i].ip.i == ip_portlist[j].ip.i) 1038 if (ip_portlist[i].ip.i == ip_portlist[j].ip.i)
1002 ++numbers[i]; 1039 ++numbers[i];
1003 } 1040 }
1004 if(numbers[i] >= min_num) 1041
1042 if (numbers[i] >= min_num)
1005 return ip_portlist[i].ip; 1043 return ip_portlist[i].ip;
1006 } 1044 }
1045
1007 return zero; 1046 return zero;
1008} 1047}
1009 1048
@@ -1012,34 +1051,36 @@ static IP NAT_commonip(IP_Port * ip_portlist, uint16_t len, uint16_t min_num)
1012 * where len is the length of ip_portlist 1051 * where len is the length of ip_portlist
1013 * returns the number of ports and puts the list of ports in portlist 1052 * returns the number of ports and puts the list of ports in portlist
1014 */ 1053 */
1015static uint16_t NAT_getports(uint16_t * portlist, IP_Port * ip_portlist, uint16_t len, IP ip) 1054static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip)
1016{ 1055{
1017 uint32_t i; 1056 uint32_t i;
1018 uint16_t num = 0; 1057 uint16_t num = 0;
1019 1058
1020 for(i = 0; i < len; ++i) { 1059 for (i = 0; i < len; ++i) {
1021 if(ip_portlist[i].ip.i == ip.i) { 1060 if (ip_portlist[i].ip.i == ip.i) {
1022 portlist[num] = ntohs(ip_portlist[i].port); 1061 portlist[num] = ntohs(ip_portlist[i].port);
1023 ++num; 1062 ++num;
1024 } 1063 }
1025 } 1064 }
1065
1026 return num; 1066 return num;
1027} 1067}
1028 1068
1029static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t friend_num) 1069static void punch_holes(IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num)
1030{ 1070{
1031 if(numports > MAX_FRIEND_CLIENTS || numports == 0) 1071 if (numports > MAX_FRIEND_CLIENTS || numports == 0)
1032 return; 1072 return;
1033 1073
1034 uint32_t i; 1074 uint32_t i;
1035 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS; 1075 uint32_t top = friends_list[friend_num].punching_index + MAX_PUNCHING_PORTS;
1036 1076
1037 for(i = friends_list[friend_num].punching_index; i != top; i++) { 1077 for (i = friends_list[friend_num].punching_index; i != top; i++) {
1038 /*TODO: improve port guessing algorithm*/ 1078 /*TODO: improve port guessing algorithm*/
1039 uint16_t port = port_list[(i/2) % numports] + (i/(2*numports))*((i % 2) ? -1 : 1); 1079 uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1);
1040 IP_Port pinging = {ip, htons(port)}; 1080 IP_Port pinging = {ip, htons(port)};
1041 send_ping_request(pinging, (clientid_t*) &friends_list[friend_num].client_id); 1081 send_ping_request(pinging, (clientid_t *) &friends_list[friend_num].client_id);
1042 } 1082 }
1083
1043 friends_list[friend_num].punching_index = i; 1084 friends_list[friend_num].punching_index = i;
1044} 1085}
1045 1086
@@ -1053,18 +1094,20 @@ static void doNAT(void)
1053 int num = friend_iplist(ip_list, i); 1094 int num = friend_iplist(ip_list, i);
1054 1095
1055 /*If already connected or friend is not online don't try to hole punch*/ 1096 /*If already connected or friend is not online don't try to hole punch*/
1056 if (num < MAX_FRIEND_CLIENTS/2) 1097 if (num < MAX_FRIEND_CLIENTS / 2)
1057 continue; 1098 continue;
1058 1099
1059 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) { 1100 if (friends_list[i].NATping_timestamp + PUNCH_INTERVAL < temp_time) {
1060 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/ 1101 send_NATping(friends_list[i].client_id, friends_list[i].NATping_id, 0); /*0 is request*/
1061 friends_list[i].NATping_timestamp = temp_time; 1102 friends_list[i].NATping_timestamp = temp_time;
1062 } 1103 }
1104
1063 if (friends_list[i].hole_punching == 1 && 1105 if (friends_list[i].hole_punching == 1 &&
1064 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && 1106 friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time &&
1065 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL*2 >= temp_time) { 1107 friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) {
1108
1109 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2);
1066 1110
1067 IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS/2);
1068 if (ip.i == 0) 1111 if (ip.i == 0)
1069 continue; 1112 continue;
1070 1113
@@ -1087,14 +1130,16 @@ static void doNAT(void)
1087 and are then removed from the list. 1130 and are then removed from the list.
1088 if the list is full the nodes farthest from our client_id are replaced 1131 if the list is full the nodes farthest from our client_id are replaced
1089 the purpose of this list is to enable quick integration of new nodes into the 1132 the purpose of this list is to enable quick integration of new nodes into the
1090 network while preventing amplification attacks. 1133 network while preventing amplification attacks.
1091 return 0 if node was added 1134 return 0 if node was added
1092 return -1 if node was not added */ 1135 return -1 if node was not added */
1093int add_toping(uint8_t *client_id, IP_Port ip_port) 1136int add_toping(uint8_t *client_id, IP_Port ip_port)
1094{ 1137{
1095 if (ip_port.ip.i == 0) 1138 if (ip_port.ip.i == 0)
1096 return -1; 1139 return -1;
1140
1097 uint32_t i; 1141 uint32_t i;
1142
1098 for (i = 0; i < MAX_TOPING; ++i) { 1143 for (i = 0; i < MAX_TOPING; ++i) {
1099 if (toping[i].ip_port.ip.i == 0) { 1144 if (toping[i].ip_port.ip.i == 0) {
1100 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); 1145 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE);
@@ -1103,6 +1148,7 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1103 return 0; 1148 return 0;
1104 } 1149 }
1105 } 1150 }
1151
1106 for (i = 0; i < MAX_TOPING; ++i) { 1152 for (i = 0; i < MAX_TOPING; ++i) {
1107 if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) { 1153 if (id_closest(self_public_key, toping[i].client_id, client_id) == 2) {
1108 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE); 1154 memcpy(toping[i].client_id, client_id, CLIENT_ID_SIZE);
@@ -1111,6 +1157,7 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1111 return 0; 1157 return 0;
1112 } 1158 }
1113 } 1159 }
1160
1114 return -1; 1161 return -1;
1115} 1162}
1116 1163
@@ -1119,13 +1166,17 @@ int add_toping(uint8_t *client_id, IP_Port ip_port)
1119static void do_toping() 1166static void do_toping()
1120{ 1167{
1121 uint64_t temp_time = unix_time(); 1168 uint64_t temp_time = unix_time();
1169
1122 if (!is_timeout(temp_time, last_toping, TIME_TOPING)) 1170 if (!is_timeout(temp_time, last_toping, TIME_TOPING))
1123 return; 1171 return;
1172
1124 last_toping = temp_time; 1173 last_toping = temp_time;
1125 uint32_t i; 1174 uint32_t i;
1175
1126 for (i = 0; i < MAX_TOPING; ++i) { 1176 for (i = 0; i < MAX_TOPING; ++i) {
1127 if (toping[i].ip_port.ip.i == 0) 1177 if (toping[i].ip_port.ip.i == 0)
1128 return; 1178 return;
1179
1129 send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id); 1180 send_ping_request(toping[i].ip_port, (clientid_t *) toping[i].client_id);
1130 toping[i].ip_port.ip.i = 0; 1181 toping[i].ip_port.ip.i = 0;
1131 } 1182 }
@@ -1156,7 +1207,7 @@ uint32_t DHT_size(void)
1156} 1207}
1157 1208
1158/* save the DHT in data where data is an array of size DHT_size() */ 1209/* save the DHT in data where data is an array of size DHT_size() */
1159void DHT_save(uint8_t * data) 1210void DHT_save(uint8_t *data)
1160{ 1211{
1161 memcpy(data, close_clientlist, sizeof(close_clientlist)); 1212 memcpy(data, close_clientlist, sizeof(close_clientlist));
1162 memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends); 1213 memcpy(data + sizeof(close_clientlist), friends_list, sizeof(Friend) * num_friends);
@@ -1164,60 +1215,64 @@ void DHT_save(uint8_t * data)
1164 1215
1165/* load the DHT from data of size size; 1216/* load the DHT from data of size size;
1166 * return -1 if failure 1217 * return -1 if failure
1167 * return 0 if success 1218 * return 0 if success
1168 */ 1219 */
1169int DHT_load(uint8_t * data, uint32_t size) 1220int DHT_load(uint8_t *data, uint32_t size)
1170{ 1221{
1171 init_ping(); 1222 init_ping();
1172 1223
1173 if(size < sizeof(close_clientlist)) 1224 if (size < sizeof(close_clientlist))
1174 return -1; 1225 return -1;
1175 1226
1176 if((size - sizeof(close_clientlist)) % sizeof(Friend) != 0) 1227 if ((size - sizeof(close_clientlist)) % sizeof(Friend) != 0)
1177 return -1; 1228 return -1;
1178 1229
1179 uint32_t i, j; 1230 uint32_t i, j;
1180 uint16_t temp; 1231 uint16_t temp;
1181 /* uint64_t temp_time = unix_time(); */ 1232 /* uint64_t temp_time = unix_time(); */
1182 1233
1183 Client_data * client; 1234 Client_data *client;
1184 1235
1185 temp = (size - sizeof(close_clientlist))/sizeof(Friend); 1236 temp = (size - sizeof(close_clientlist)) / sizeof(Friend);
1186 1237
1187 if(temp != 0) { 1238 if (temp != 0) {
1188 Friend * tempfriends_list = (Friend *)(data + sizeof(close_clientlist)); 1239 Friend *tempfriends_list = (Friend *)(data + sizeof(close_clientlist));
1189 1240
1190 for(i = 0; i < temp; ++i) { 1241 for (i = 0; i < temp; ++i) {
1191 DHT_addfriend(tempfriends_list[i].client_id); 1242 DHT_addfriend(tempfriends_list[i].client_id);
1192 1243
1193 for(j = 0; j < MAX_FRIEND_CLIENTS; ++j) { 1244 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1194 client = &tempfriends_list[i].client_list[j]; 1245 client = &tempfriends_list[i].client_list[j];
1195 if(client->timestamp != 0) 1246
1247 if (client->timestamp != 0)
1196 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id); 1248 getnodes(client->ip_port, client->client_id, tempfriends_list[i].client_id);
1197 } 1249 }
1198 } 1250 }
1199 } 1251 }
1200 Client_data * tempclose_clientlist = (Client_data *)data;
1201 1252
1202 for(i = 0; i < LCLIENT_LIST; ++i) { 1253 Client_data *tempclose_clientlist = (Client_data *)data;
1203 if(tempclose_clientlist[i].timestamp != 0) 1254
1204 DHT_bootstrap( tempclose_clientlist[i].ip_port, 1255 for (i = 0; i < LCLIENT_LIST; ++i) {
1256 if (tempclose_clientlist[i].timestamp != 0)
1257 DHT_bootstrap( tempclose_clientlist[i].ip_port,
1205 tempclose_clientlist[i].client_id ); 1258 tempclose_clientlist[i].client_id );
1206 } 1259 }
1260
1207 return 0; 1261 return 0;
1208} 1262}
1209 1263
1210/* returns 0 if we are not connected to the DHT 1264/* returns 0 if we are not connected to the DHT
1211 * returns 1 if we are 1265 * returns 1 if we are
1212 */ 1266 */
1213int DHT_isconnected(void) 1267int DHT_isconnected(void)
1214{ 1268{
1215 uint32_t i; 1269 uint32_t i;
1216 uint64_t temp_time = unix_time(); 1270 uint64_t temp_time = unix_time();
1217 1271
1218 for(i = 0; i < LCLIENT_LIST; ++i) { 1272 for (i = 0; i < LCLIENT_LIST; ++i) {
1219 if(!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT)) 1273 if (!is_timeout(temp_time, close_clientlist[i].timestamp, BAD_NODE_TIMEOUT))
1220 return 1; 1274 return 1;
1221 } 1275 }
1276
1222 return 0; 1277 return 0;
1223} 1278}
diff --git a/core/DHT.h b/core/DHT.h
index c6ca4ce1..8cb0436a 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -39,13 +39,13 @@ typedef struct {
39 IP_Port ip_port; 39 IP_Port ip_port;
40 uint64_t timestamp; 40 uint64_t timestamp;
41 uint64_t last_pinged; 41 uint64_t last_pinged;
42 42
43 /* Returned by this node. Either our friend or us */ 43 /* Returned by this node. Either our friend or us */
44 IP_Port ret_ip_port; 44 IP_Port ret_ip_port;
45 uint64_t ret_timestamp; 45 uint64_t ret_timestamp;
46} Client_data; 46} Client_data;
47 47
48Client_data * DHT_get_close_list(void); 48Client_data *DHT_get_close_list(void);
49 49
50/* Add a new friend to the friends list 50/* Add a new friend to the friends list
51 client_id must be CLIENT_ID_SIZE bytes long. 51 client_id must be CLIENT_ID_SIZE bytes long.
@@ -80,7 +80,7 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
80 and are then removed from the list. 80 and are then removed from the list.
81 if the list is full the nodes farthest from our client_id are replaced 81 if the list is full the nodes farthest from our client_id are replaced
82 the purpose of this list is to enable quick integration of new nodes into the 82 the purpose of this list is to enable quick integration of new nodes into the
83 network while preventing amplification attacks. 83 network while preventing amplification attacks.
84 return 0 if node was added 84 return 0 if node was added
85 return -1 if node was not added */ 85 return -1 if node was not added */
86int add_toping(uint8_t *client_id, IP_Port ip_port); 86int add_toping(uint8_t *client_id, IP_Port ip_port);
@@ -123,7 +123,7 @@ int DHT_load(uint8_t *data, uint32_t size);
123 returns 1 if we are */ 123 returns 1 if we are */
124int DHT_isconnected(); 124int DHT_isconnected();
125 125
126void addto_lists(IP_Port ip_port, uint8_t * client_id); 126void addto_lists(IP_Port ip_port, uint8_t *client_id);
127 127
128#ifdef __cplusplus 128#ifdef __cplusplus
129} 129}
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c
index 67dc656b..ad1337ef 100644
--- a/core/LAN_discovery.c
+++ b/core/LAN_discovery.c
@@ -41,7 +41,7 @@ static uint32_t get_broadcast(void)
41 int i = 0; 41 int i = 0;
42 42
43 /* configure ifconf for the ioctl call */ 43 /* configure ifconf for the ioctl call */
44 if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 44 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
45 perror("[!] get_broadcast: socket() error"); 45 perror("[!] get_broadcast: socket() error");
46 return 0; 46 return 0;
47 } 47 }
@@ -51,15 +51,16 @@ static uint32_t get_broadcast(void)
51 ifconf.ifc_buf = (char *)i_faces; 51 ifconf.ifc_buf = (char *)i_faces;
52 ifconf.ifc_len = sizeof(i_faces); 52 ifconf.ifc_len = sizeof(i_faces);
53 count = ifconf.ifc_len / sizeof(struct ifreq); 53 count = ifconf.ifc_len / sizeof(struct ifreq);
54 if(ioctl(sock, SIOCGIFCONF, &ifconf) < 0) { 54
55 if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
55 perror("get_broadcast: ioctl() error"); 56 perror("get_broadcast: ioctl() error");
56 return 0; 57 return 0;
57 } 58 }
58 59
59 for(i = 0; i < count; i++) { 60 for (i = 0; i < count; i++) {
60 /* skip the loopback interface, as it's useless */ 61 /* skip the loopback interface, as it's useless */
61 if(strcmp(i_faces[i].ifr_name, "lo") != 0) { 62 if (strcmp(i_faces[i].ifr_name, "lo") != 0) {
62 if(ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { 63 if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
63 perror("[!] get_broadcast: ioctl error"); 64 perror("[!] get_broadcast: ioctl error");
64 return 0; 65 return 0;
65 } 66 }
@@ -69,8 +70,10 @@ static uint32_t get_broadcast(void)
69 break; 70 break;
70 } 71 }
71 } 72 }
73
72 close(sock); 74 close(sock);
73 if(sock_holder == NULL) { 75
76 if (sock_holder == NULL) {
74 perror("[!] no broadcast device found"); 77 perror("[!] no broadcast device found");
75 return 0; 78 return 0;
76 } 79 }
@@ -83,14 +86,16 @@ static uint32_t get_broadcast(void)
83static IP broadcast_ip(void) 86static IP broadcast_ip(void)
84{ 87{
85 IP ip; 88 IP ip;
86 #ifdef __linux 89#ifdef __linux
87 ip.i = get_broadcast(); 90 ip.i = get_broadcast();
88 if(ip.i == 0) 91
92 if (ip.i == 0)
89 /* error errored, but try anyway? */ 93 /* error errored, but try anyway? */
90 ip.i = ~0; 94 ip.i = ~0;
91 #else 95
96#else
92 ip.i = ~0; 97 ip.i = ~0;
93 #endif 98#endif
94 return ip; 99 return ip;
95} 100}
96 101
@@ -100,14 +105,19 @@ static int LAN_ip(IP ip)
100{ 105{
101 if (ip.c[0] == 127)/* Loopback */ 106 if (ip.c[0] == 127)/* Loopback */
102 return 0; 107 return 0;
108
103 if (ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */ 109 if (ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */
104 return 0; 110 return 0;
111
105 if (ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */ 112 if (ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */
106 return 0; 113 return 0;
114
107 if (ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */ 115 if (ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */
108 return 0; 116 return 0;
117
109 if (ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */ 118 if (ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */
110 return 0; 119 return 0;
120
111 return -1; 121 return -1;
112} 122}
113 123
@@ -115,8 +125,10 @@ static int handle_LANdiscovery(IP_Port source, uint8_t *packet, uint32_t length)
115{ 125{
116 if (LAN_ip(source.ip) == -1) 126 if (LAN_ip(source.ip) == -1)
117 return 1; 127 return 1;
128
118 if (length != crypto_box_PUBLICKEYBYTES + 1) 129 if (length != crypto_box_PUBLICKEYBYTES + 1)
119 return 1; 130 return 1;
131
120 DHT_bootstrap(source, packet + 1); 132 DHT_bootstrap(source, packet + 1);
121 return 0; 133 return 0;
122} 134}
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 002e2cf8..fa5f9144 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -21,7 +21,7 @@
21 * 21 *
22 */ 22 */
23 23
24/* 24/*
25 * TODO: clean this file a bit. 25 * TODO: clean this file a bit.
26 * There are a couple of useless variables to get rid of. 26 * There are a couple of useless variables to get rid of.
27 */ 27 */
@@ -59,9 +59,9 @@ typedef struct {
59 */ 59 */
60 uint8_t status; 60 uint8_t status;
61 61
62 /* 62 /*
63 * 1 or 2 if connection was initiated by someone else, 0 if not. 63 * 1 or 2 if connection was initiated by someone else, 0 if not.
64 * 2 if incoming_connection() has not returned it yet, 1 if it has. 64 * 2 if incoming_connection() has not returned it yet, 1 if it has.
65 */ 65 */
66 uint8_t inbound; 66 uint8_t inbound;
67 67
@@ -81,31 +81,31 @@ typedef struct {
81 uint32_t handshake_id2; 81 uint32_t handshake_id2;
82 82
83 /* number of data packets received (also used as handshake_id1) */ 83 /* number of data packets received (also used as handshake_id1) */
84 uint32_t recv_packetnum; 84 uint32_t recv_packetnum;
85 85
86 /* number of packets received by the other peer */ 86 /* number of packets received by the other peer */
87 uint32_t orecv_packetnum; 87 uint32_t orecv_packetnum;
88 88
89 /* number of data packets sent */ 89 /* number of data packets sent */
90 uint32_t sent_packetnum; 90 uint32_t sent_packetnum;
91 91
92 /* number of packets sent by the other peer. */ 92 /* number of packets sent by the other peer. */
93 uint32_t osent_packetnum; 93 uint32_t osent_packetnum;
94 94
95 /* number of latest packet written onto the sendbuffer */ 95 /* number of latest packet written onto the sendbuffer */
96 uint32_t sendbuff_packetnum; 96 uint32_t sendbuff_packetnum;
97 97
98 /* we know all packets before that number were successfully sent */ 98 /* we know all packets before that number were successfully sent */
99 uint32_t successful_sent; 99 uint32_t successful_sent;
100 100
101 /* packet number of last packet read with the read_packet function */ 101 /* packet number of last packet read with the read_packet function */
102 uint32_t successful_read; 102 uint32_t successful_read;
103 103
104 /* list of currently requested packet numbers(by the other person) */ 104 /* list of currently requested packet numbers(by the other person) */
105 uint32_t req_packets[BUFFER_PACKET_NUM]; 105 uint32_t req_packets[BUFFER_PACKET_NUM];
106 106
107 /* total number of currently requested packets(by the other person) */ 107 /* total number of currently requested packets(by the other person) */
108 uint16_t num_req_paquets; 108 uint16_t num_req_paquets;
109 109
110 uint8_t recv_counter; 110 uint8_t recv_counter;
111 uint8_t send_counter; 111 uint8_t send_counter;
@@ -113,7 +113,7 @@ typedef struct {
113} Connection; 113} Connection;
114 114
115 115
116static Connection * connections; 116static Connection *connections;
117 117
118static uint32_t connections_length; /* Length of connections array */ 118static uint32_t connections_length; /* Length of connections array */
119static uint32_t connections_number; /* Number of connections in connections array */ 119static uint32_t connections_number; /* Number of connections in connections array */
@@ -122,7 +122,7 @@ static uint32_t connections_number; /* Number of connections in connections arra
122 122
123/* Functions */ 123/* Functions */
124 124
125/* 125/*
126 * Get connection id from IP_Port 126 * Get connection id from IP_Port
127 * Return -1 if there are no connections like we are looking for 127 * Return -1 if there are no connections like we are looking for
128 * Return id if it found it 128 * Return id if it found it
@@ -130,10 +130,11 @@ static uint32_t connections_number; /* Number of connections in connections arra
130int getconnection_id(IP_Port ip_port) 130int getconnection_id(IP_Port ip_port)
131{ 131{
132 uint32_t i; 132 uint32_t i;
133
133 for (i = 0; i < MAX_CONNECTIONS; ++i) { 134 for (i = 0; i < MAX_CONNECTIONS; ++i) {
134 if (connections[i].ip_port.ip.i == ip_port.ip.i && 135 if (connections[i].ip_port.ip.i == ip_port.ip.i &&
135 connections[i].ip_port.port == ip_port.port && 136 connections[i].ip_port.port == ip_port.port &&
136 connections[i].status > 0) 137 connections[i].status > 0)
137 return i; 138 return i;
138 } 139 }
139 140
@@ -143,7 +144,7 @@ int getconnection_id(IP_Port ip_port)
143/* table of random numbers used below. */ 144/* table of random numbers used below. */
144static uint32_t randtable[6][256]; 145static uint32_t randtable[6][256];
145 146
146/* 147/*
147 * Generate a handshake_id which depends on the ip_port. 148 * Generate a handshake_id which depends on the ip_port.
148 * This function will always give one unique handshake_id per ip_port. 149 * This function will always give one unique handshake_id per ip_port.
149 * 150 *
@@ -152,18 +153,21 @@ static uint32_t randtable[6][256];
152static uint32_t handshake_id(IP_Port source) 153static uint32_t handshake_id(IP_Port source)
153{ 154{
154 uint32_t id = 0, i; 155 uint32_t id = 0, i;
156
155 for (i = 0; i < 6; ++i) { 157 for (i = 0; i < 6; ++i) {
156 if(randtable[i][((uint8_t *)&source)[i]] == 0) 158 if (randtable[i][((uint8_t *)&source)[i]] == 0)
157 randtable[i][((uint8_t *)&source)[i]] = random_int(); 159 randtable[i][((uint8_t *)&source)[i]] = random_int();
160
158 id ^= randtable[i][((uint8_t *)&source)[i]]; 161 id ^= randtable[i][((uint8_t *)&source)[i]];
159 } 162 }
163
160 if (id == 0) /* id can't be zero */ 164 if (id == 0) /* id can't be zero */
161 id = 1; 165 id = 1;
162 166
163 return id; 167 return id;
164} 168}
165 169
166/* 170/*
167 * Change the hanshake id associated with that ip_port 171 * Change the hanshake id associated with that ip_port
168 * 172 *
169 * TODO: make this better 173 * TODO: make this better
@@ -174,7 +178,7 @@ static void change_handshake(IP_Port source)
174 randtable[rand][((uint8_t *)&source)[rand]] = random_int(); 178 randtable[rand][((uint8_t *)&source)[rand]] = random_int();
175} 179}
176 180
177/* 181/*
178 * Initialize a new connection to ip_port 182 * Initialize a new connection to ip_port
179 * Returns an integer corresponding to the connection idt 183 * Returns an integer corresponding to the connection idt
180 * Return -1 if it could not initialize the connectiont 184 * Return -1 if it could not initialize the connectiont
@@ -183,53 +187,56 @@ static void change_handshake(IP_Port source)
183int new_connection(IP_Port ip_port) 187int new_connection(IP_Port ip_port)
184{ 188{
185 int connect = getconnection_id(ip_port); 189 int connect = getconnection_id(ip_port);
190
186 if (connect != -1) 191 if (connect != -1)
187 return connect; 192 return connect;
188 193
189 if(connections_number == connections_length) { 194 if (connections_number == connections_length) {
190 Connection * temp; 195 Connection *temp;
191 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 196 temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
192 197
193 if(temp == NULL) 198 if (temp == NULL)
194 return -1; 199 return -1;
195 200
196 memset(&temp[connections_length], 0, sizeof(Connection)); 201 memset(&temp[connections_length], 0, sizeof(Connection));
197 ++connections_length; 202 ++connections_length;
198 connections = temp; 203 connections = temp;
199 } 204 }
200 205
201 uint32_t i; 206 uint32_t i;
207
202 for (i = 0; i < MAX_CONNECTIONS; ++i) { 208 for (i = 0; i < MAX_CONNECTIONS; ++i) {
203 if(connections[i].status == 0) { 209 if (connections[i].status == 0) {
204 memset(&connections[i], 0, sizeof(Connection)); 210 memset(&connections[i], 0, sizeof(Connection));
205 uint32_t handshake_id1 = handshake_id(ip_port); 211 uint32_t handshake_id1 = handshake_id(ip_port);
206 212
207 connections[i] = (Connection) { 213 connections[i] = (Connection) {
208 .ip_port = ip_port, 214 .ip_port = ip_port,
209 .status = 1, 215 .status = 1,
210 .inbound = 0, 216 .inbound = 0,
211 .handshake_id1 = handshake_id1, 217 .handshake_id1 = handshake_id1,
212 .sent_packetnum = handshake_id1, 218 .sent_packetnum = handshake_id1,
213 .sendbuff_packetnum = handshake_id1, 219 .sendbuff_packetnum = handshake_id1,
214 .successful_sent = handshake_id1, 220 .successful_sent = handshake_id1,
215 .SYNC_rate = SYNC_RATE, 221 .SYNC_rate = SYNC_RATE,
216 .data_rate = DATA_SYNC_RATE, 222 .data_rate = DATA_SYNC_RATE,
217 .last_recvSYNC = current_time(), 223 .last_recvSYNC = current_time(),
218 .last_sent = current_time(), 224 .last_sent = current_time(),
219 .killat = ~0, 225 .killat = ~0,
220 .send_counter = 0, 226 .send_counter = 0,
221 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 227 /* add randomness to timeout to prevent connections getting stuck in a loop. */
222 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT 228 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
223 }; 229 };
224 ++connections_number; 230 ++connections_number;
225 231
226 return i; 232 return i;
227 } 233 }
228 } 234 }
235
229 return -1; 236 return -1;
230} 237}
231 238
232/* 239/*
233 * Initialize a new inbound connection from ip_port 240 * Initialize a new inbound connection from ip_port
234 * Returns an integer corresponding to the connection id. 241 * Returns an integer corresponding to the connection id.
235 * Return -1 if it could not initialize the connection. 242 * Return -1 if it could not initialize the connection.
@@ -238,55 +245,58 @@ static int new_inconnection(IP_Port ip_port)
238{ 245{
239 if (getconnection_id(ip_port) != -1) 246 if (getconnection_id(ip_port) != -1)
240 return -1; 247 return -1;
241 248
242 if(connections_number == connections_length) { 249 if (connections_number == connections_length) {
243 Connection * temp; 250 Connection *temp;
244 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 251 temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
245 252
246 if(temp == NULL) 253 if (temp == NULL)
247 return -1; 254 return -1;
248 255
249 memset(&temp[connections_length], 0, sizeof(Connection)); 256 memset(&temp[connections_length], 0, sizeof(Connection));
250 ++connections_length; 257 ++connections_length;
251 connections = temp; 258 connections = temp;
252 } 259 }
253 260
254 uint32_t i; 261 uint32_t i;
262
255 for (i = 0; i < MAX_CONNECTIONS; ++i) { 263 for (i = 0; i < MAX_CONNECTIONS; ++i) {
256 if (connections[i].status == 0) { 264 if (connections[i].status == 0) {
257 memset(&connections[i], 0, sizeof(Connection)); 265 memset(&connections[i], 0, sizeof(Connection));
258 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 266 uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
259 267
260 connections[i] = (Connection){ 268 connections[i] = (Connection) {
261 .ip_port = ip_port, 269 .ip_port = ip_port,
262 .status = 2, 270 .status = 2,
263 .inbound = 2, 271 .inbound = 2,
264 .SYNC_rate = SYNC_RATE, 272 .SYNC_rate = SYNC_RATE,
265 .data_rate = DATA_SYNC_RATE, 273 .data_rate = DATA_SYNC_RATE,
266 .last_recvSYNC = current_time(), 274 .last_recvSYNC = current_time(),
267 .last_sent = current_time(), 275 .last_sent = current_time(),
268 .send_counter = 127, 276 .send_counter = 127,
269 277
270 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 278 /* add randomness to timeout to prevent connections getting stuck in a loop. */
271 .timeout = timeout, 279 .timeout = timeout,
272 280
273 /* if this connection isn't handled within the timeout kill it. */ 281 /* if this connection isn't handled within the timeout kill it. */
274 .killat = current_time() + 1000000UL*timeout 282 .killat = current_time() + 1000000UL * timeout
275 }; 283 };
276 ++connections_number; 284 ++connections_number;
277 return i; 285 return i;
278 } 286 }
279 } 287 }
288
280 return -1; 289 return -1;
281} 290}
282 291
283/* 292/*
284 * Returns an integer corresponding to the next connection in our incoming connection list. 293 * Returns an integer corresponding to the next connection in our incoming connection list.
285 * Return -1 if there are no new incoming connections in the list. 294 * Return -1 if there are no new incoming connections in the list.
286 */ 295 */
287int incoming_connection(void) 296int incoming_connection(void)
288{ 297{
289 uint32_t i; 298 uint32_t i;
299
290 for (i = 0; i < MAX_CONNECTIONS; ++i) { 300 for (i = 0; i < MAX_CONNECTIONS; ++i) {
291 if (connections[i].inbound == 2) { 301 if (connections[i].inbound == 2) {
292 connections[i].inbound = 1; 302 connections[i].inbound = 1;
@@ -301,23 +311,25 @@ int incoming_connection(void)
301static void free_connections(void) 311static void free_connections(void)
302{ 312{
303 uint32_t i; 313 uint32_t i;
304 for(i = connections_length; i != 0; --i) 314
315 for (i = connections_length; i != 0; --i)
305 if (connections[i - 1].status != 0) 316 if (connections[i - 1].status != 0)
306 break; 317 break;
307 318
308 if(connections_length == i) 319 if (connections_length == i)
309 return; 320 return;
310 321
311 Connection * temp; 322 Connection *temp;
312 temp = realloc(connections, sizeof(Connection) * i); 323 temp = realloc(connections, sizeof(Connection) * i);
313 if(temp == NULL && i != 0) 324
325 if (temp == NULL && i != 0)
314 return; 326 return;
315 327
316 connections = temp; 328 connections = temp;
317 connections_length = i; 329 connections_length = i;
318} 330}
319 331
320/* 332/*
321 * Return -1 if it could not kill the connection. 333 * Return -1 if it could not kill the connection.
322 * Return 0 if killed successfully 334 * Return 0 if killed successfully
323 */ 335 */
@@ -332,10 +344,11 @@ int kill_connection(int connection_id)
332 return 0; 344 return 0;
333 } 345 }
334 } 346 }
347
335 return -1; 348 return -1;
336} 349}
337 350
338/* 351/*
339 * Kill connection in seconds. 352 * Kill connection in seconds.
340 * Return -1 if it can not kill the connection. 353 * Return -1 if it can not kill the connection.
341 * Return 0 if it will kill it. 354 * Return 0 if it will kill it.
@@ -344,14 +357,15 @@ int kill_connection_in(int connection_id, uint32_t seconds)
344{ 357{
345 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 358 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
346 if (connections[connection_id].status > 0) { 359 if (connections[connection_id].status > 0) {
347 connections[connection_id].killat = current_time() + 1000000UL*seconds; 360 connections[connection_id].killat = current_time() + 1000000UL * seconds;
348 return 0; 361 return 0;
349 } 362 }
350 } 363 }
364
351 return -1; 365 return -1;
352} 366}
353 367
354/* 368/*
355 * Check if connection is connected: 369 * Check if connection is connected:
356 * Return 0 no. 370 * Return 0 no.
357 * Return 1 if attempting handshake. 371 * Return 1 if attempting handshake.
@@ -363,6 +377,7 @@ int is_connected(int connection_id)
363{ 377{
364 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 378 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
365 return connections[connection_id].status; 379 return connections[connection_id].status;
380
366 return 0; 381 return 0;
367} 382}
368 383
@@ -371,6 +386,7 @@ IP_Port connection_ip(int connection_id)
371{ 386{
372 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 387 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
373 return connections[connection_id].ip_port; 388 return connections[connection_id].ip_port;
389
374 IP_Port zero = {{{0}}, 0}; 390 IP_Port zero = {{{0}}, 0};
375 return zero; 391 return zero;
376} 392}
@@ -380,6 +396,7 @@ uint32_t sendqueue(int connection_id)
380{ 396{
381 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 397 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
382 return 0; 398 return 0;
399
383 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; 400 return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent;
384} 401}
385 402
@@ -388,6 +405,7 @@ uint32_t recvqueue(int connection_id)
388{ 405{
389 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 406 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
390 return 0; 407 return 0;
408
391 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; 409 return connections[connection_id].recv_packetnum - connections[connection_id].successful_read;
392} 410}
393 411
@@ -406,7 +424,7 @@ char id_packet(int connection_id)
406 424
407/* return 0 if there is no received data in the buffer. 425/* return 0 if there is no received data in the buffer.
408 return length of received packet if successful */ 426 return length of received packet if successful */
409int read_packet(int connection_id, uint8_t * data) 427int read_packet(int connection_id, uint8_t *data)
410{ 428{
411 if (recvqueue(connection_id) != 0) { 429 if (recvqueue(connection_id) != 0) {
412 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 430 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
@@ -416,14 +434,15 @@ int read_packet(int connection_id, uint8_t * data)
416 connections[connection_id].recvbuffer[index].size = 0; 434 connections[connection_id].recvbuffer[index].size = 0;
417 return size; 435 return size;
418 } 436 }
437
419 return 0; 438 return 0;
420} 439}
421 440
422/* 441/*
423 * Return 0 if data could not be put in packet queue 442 * Return 0 if data could not be put in packet queue
424 * Return 1 if data was put into the queue 443 * Return 1 if data was put into the queue
425 */ 444 */
426int write_packet(int connection_id, uint8_t * data, uint32_t length) 445int write_packet(int connection_id, uint8_t *data, uint32_t length)
427{ 446{
428 if (length > MAX_DATA_SIZE || length == 0) 447 if (length > MAX_DATA_SIZE || length == 0)
429 return 0; 448 return 0;
@@ -440,31 +459,31 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length)
440} 459}
441 460
442/* put the packet numbers the we are missing in requested and return the number */ 461/* put the packet numbers the we are missing in requested and return the number */
443uint32_t missing_packets(int connection_id, uint32_t * requested) 462uint32_t missing_packets(int connection_id, uint32_t *requested)
444{ 463{
445 uint32_t number = 0; 464 uint32_t number = 0;
446 uint32_t i; 465 uint32_t i;
447 uint32_t temp; 466 uint32_t temp;
448 467
449 /* don't request packets if the buffer is full. */ 468 /* don't request packets if the buffer is full. */
450 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) 469 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1))
451 return 0; 470 return 0;
452 471
453 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { 472 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) {
454 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { 473 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
455 temp = htonl(i); 474 temp = htonl(i);
456 memcpy(requested + number, &temp, 4); 475 memcpy(requested + number, &temp, 4);
457 ++number; 476 ++number;
458 } 477 }
459 } 478 }
460 479
461 if(number == 0) 480 if (number == 0)
462 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; 481 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
463 482
464 return number; 483 return number;
465} 484}
466 485
467/* 486/*
468 * BEGIN Packet sending functions 487 * BEGIN Packet sending functions
469 * One per packet type. 488 * One per packet type.
470 * see http://wiki.tox.im/index.php/Lossless_UDP for more information. 489 * see http://wiki.tox.im/index.php/Lossless_UDP for more information.
@@ -486,7 +505,7 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand
486 505
487static int send_SYNC(uint32_t connection_id) 506static int send_SYNC(uint32_t connection_id)
488{ 507{
489 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; 508 uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)];
490 uint16_t index = 0; 509 uint16_t index = 0;
491 510
492 IP_Port ip_port = connections[connection_id].ip_port; 511 IP_Port ip_port = connections[connection_id].ip_port;
@@ -507,7 +526,7 @@ static int send_SYNC(uint32_t connection_id)
507 index += 4; 526 index += 4;
508 memcpy(packet + index, requested, 4 * number); 527 memcpy(packet + index, requested, 4 * number);
509 528
510 return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2)); 529 return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2));
511 530
512} 531}
513 532
@@ -530,6 +549,7 @@ static int send_DATA(uint32_t connection_id)
530{ 549{
531 int ret; 550 int ret;
532 uint32_t buffer[BUFFER_PACKET_NUM]; 551 uint32_t buffer[BUFFER_PACKET_NUM];
552
533 if (connections[connection_id].num_req_paquets > 0) { 553 if (connections[connection_id].num_req_paquets > 0) {
534 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); 554 ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
535 connections[connection_id].num_req_paquets--; 555 connections[connection_id].num_req_paquets--;
@@ -537,15 +557,17 @@ static int send_DATA(uint32_t connection_id)
537 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); 557 memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4);
538 return ret; 558 return ret;
539 } 559 }
560
540 if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { 561 if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) {
541 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); 562 ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum);
542 connections[connection_id].sent_packetnum++; 563 connections[connection_id].sent_packetnum++;
543 return ret; 564 return ret;
544 } 565 }
566
545 return 0; 567 return 0;
546} 568}
547 569
548/* 570/*
549 * END of packet sending functions 571 * END of packet sending functions
550 * 572 *
551 * 573 *
@@ -555,7 +577,7 @@ static int send_DATA(uint32_t connection_id)
555 577
556 578
557/* Return 0 if handled correctly, 1 if packet is bad. */ 579/* Return 0 if handled correctly, 1 if packet is bad. */
558static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length) 580static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length)
559{ 581{
560 if (length != (1 + 4 + 4)) 582 if (length != (1 + 4 + 4))
561 return 1; 583 return 1;
@@ -573,11 +595,12 @@ static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length)
573 send_handshake(source, handshake_id(source), handshake_id1); 595 send_handshake(source, handshake_id(source), handshake_id1);
574 return 0; 596 return 0;
575 } 597 }
598
576 if (is_connected(connection) != 1) 599 if (is_connected(connection) != 1)
577 return 1; 600 return 1;
578 601
579 /* if handshake_id2 is what we sent previously as handshake_id1 */ 602 /* if handshake_id2 is what we sent previously as handshake_id1 */
580 if (handshake_id2 == connections[connection].handshake_id1) { 603 if (handshake_id2 == connections[connection].handshake_id1) {
581 connections[connection].status = 2; 604 connections[connection].status = 2;
582 /* NOTE: is this necessary? 605 /* NOTE: is this necessary?
583 connections[connection].handshake_id2 = handshake_id1; */ 606 connections[connection].handshake_id2 = handshake_id1; */
@@ -595,9 +618,11 @@ static int SYNC_valid(uint32_t length)
595{ 618{
596 if (length < 4 + 4 + 2) 619 if (length < 4 + 4 + 2)
597 return 0; 620 return 0;
598 if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || 621
599 ((length - 4 - 4 - 2) % 4) != 0) 622 if (length > (BUFFER_PACKET_NUM * 4 + 4 + 4 + 2) ||
623 ((length - 4 - 4 - 2) % 4) != 0)
600 return 0; 624 return 0;
625
601 return 1; 626 return 1;
602} 627}
603 628
@@ -606,6 +631,7 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
606{ 631{
607 if (handshake_id(source) == recv_packetnum) { 632 if (handshake_id(source) == recv_packetnum) {
608 int x = new_inconnection(source); 633 int x = new_inconnection(source);
634
609 if (x != -1) { 635 if (x != -1) {
610 connections[x].orecv_packetnum = recv_packetnum; 636 connections[x].orecv_packetnum = recv_packetnum;
611 connections[x].sent_packetnum = recv_packetnum; 637 connections[x].sent_packetnum = recv_packetnum;
@@ -618,6 +644,7 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
618 return x; 644 return x;
619 } 645 }
620 } 646 }
647
621 return -1; 648 return -1;
622} 649}
623 650
@@ -632,11 +659,13 @@ static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packet
632 send_SYNC(connection_id); 659 send_SYNC(connection_id);
633 return 0; 660 return 0;
634 } 661 }
662
635 return 1; 663 return 1;
636} 664}
637/* case 3 in handle_SYNC: */ 665/* case 3 in handle_SYNC: */
638static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, 666static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum,
639 uint16_t number) 667 uint32_t *req_packets,
668 uint16_t number)
640{ 669{
641 uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); 670 uint8_t comp_counter = (counter - connections[connection_id].recv_counter );
642 uint32_t i, temp; 671 uint32_t i, temp;
@@ -646,9 +675,9 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet
646 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); 675 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
647 676
648 /* packet valid */ 677 /* packet valid */
649 if (comp_1 <= BUFFER_PACKET_NUM && 678 if (comp_1 <= BUFFER_PACKET_NUM &&
650 comp_2 <= BUFFER_PACKET_NUM && 679 comp_2 <= BUFFER_PACKET_NUM &&
651 comp_counter < 10 && comp_counter != 0) { 680 comp_counter < 10 && comp_counter != 0) {
652 681
653 connections[connection_id].orecv_packetnum = recv_packetnum; 682 connections[connection_id].orecv_packetnum = recv_packetnum;
654 connections[connection_id].osent_packetnum = sent_packetnum; 683 connections[connection_id].osent_packetnum = sent_packetnum;
@@ -666,6 +695,7 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet
666 connections[connection_id].num_req_paquets = number; 695 connections[connection_id].num_req_paquets = number;
667 return 0; 696 return 0;
668 } 697 }
698
669 return 1; 699 return 1;
670} 700}
671 701
@@ -680,12 +710,12 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
680 uint32_t temp; 710 uint32_t temp;
681 uint32_t recv_packetnum, sent_packetnum; 711 uint32_t recv_packetnum, sent_packetnum;
682 uint32_t req_packets[BUFFER_PACKET_NUM]; 712 uint32_t req_packets[BUFFER_PACKET_NUM];
683 uint16_t number = (length - 4 - 4 - 2)/ 4; 713 uint16_t number = (length - 4 - 4 - 2) / 4;
684 714
685 memcpy(&counter, packet + 1, 1); 715 memcpy(&counter, packet + 1, 1);
686 memcpy(&temp, packet + 2, 4); 716 memcpy(&temp, packet + 2, 4);
687 recv_packetnum = ntohl(temp); 717 recv_packetnum = ntohl(temp);
688 memcpy(&temp,packet + 6, 4); 718 memcpy(&temp, packet + 6, 4);
689 sent_packetnum = ntohl(temp); 719 sent_packetnum = ntohl(temp);
690 720
691 if (number != 0) 721 if (number != 0)
@@ -695,17 +725,18 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
695 return handle_SYNC1(source, recv_packetnum, sent_packetnum); 725 return handle_SYNC1(source, recv_packetnum, sent_packetnum);
696 726
697 if (connections[connection].status == 2) 727 if (connections[connection].status == 2)
698 return handle_SYNC2(connection, counter, 728 return handle_SYNC2(connection, counter,
699 recv_packetnum, sent_packetnum); 729 recv_packetnum, sent_packetnum);
700 730
701 if (connections[connection].status == 3) 731 if (connections[connection].status == 3)
702 return handle_SYNC3(connection, counter, recv_packetnum, 732 return handle_SYNC3(connection, counter, recv_packetnum,
703 sent_packetnum, req_packets, number); 733 sent_packetnum, req_packets, number);
734
704 return 0; 735 return 0;
705} 736}
706 737
707/* 738/*
708 * Add a packet to the received buffer and set the recv_packetnum of the 739 * Add a packet to the received buffer and set the recv_packetnum of the
709 * connection to its proper value. Return 1 if data was too big, 0 if not. 740 * connection to its proper value. Return 1 if data was too big, 0 if not.
710 */ 741 */
711static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) 742static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
@@ -766,8 +797,8 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length)
766 return add_recv(connection, number, packet + 5, size); 797 return add_recv(connection, number, packet + 5, size);
767} 798}
768 799
769/* 800/*
770 * END of packet handling functions 801 * END of packet handling functions
771 */ 802 */
772 803
773void LosslessUDP_init(void) 804void LosslessUDP_init(void)
@@ -785,17 +816,18 @@ static void doNew(void)
785{ 816{
786 uint32_t i; 817 uint32_t i;
787 uint64_t temp_time = current_time(); 818 uint64_t temp_time = current_time();
819
788 for (i = 0; i < MAX_CONNECTIONS; ++i) { 820 for (i = 0; i < MAX_CONNECTIONS; ++i) {
789 if (connections[i].status == 1) 821 if (connections[i].status == 1)
790 if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { 822 if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) {
791 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); 823 send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
792 connections[i].last_sent = temp_time; 824 connections[i].last_sent = temp_time;
793 } 825 }
794 826
795 /* kill all timed out connections */ 827 /* kill all timed out connections */
796 if (connections[i].status > 0 && 828 if (connections[i].status > 0 &&
797 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 829 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
798 connections[i].status != 4) { 830 connections[i].status != 4) {
799 connections[i].status = 4; 831 connections[i].status = 4;
800 /* kill_connection(i); */ 832 /* kill_connection(i); */
801 } 833 }
@@ -809,9 +841,10 @@ static void doSYNC(void)
809{ 841{
810 uint32_t i; 842 uint32_t i;
811 uint64_t temp_time = current_time(); 843 uint64_t temp_time = current_time();
844
812 for (i = 0; i < MAX_CONNECTIONS; ++i) { 845 for (i = 0; i < MAX_CONNECTIONS; ++i) {
813 if (connections[i].status == 2 || connections[i].status == 3) 846 if (connections[i].status == 2 || connections[i].status == 3)
814 if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { 847 if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) {
815 send_SYNC(i); 848 send_SYNC(i);
816 connections[i].last_SYNC = temp_time; 849 connections[i].last_SYNC = temp_time;
817 } 850 }
@@ -823,18 +856,20 @@ static void doData(void)
823 uint32_t i; 856 uint32_t i;
824 uint64_t j; 857 uint64_t j;
825 uint64_t temp_time = current_time(); 858 uint64_t temp_time = current_time();
859
826 for (i = 0; i < MAX_CONNECTIONS; ++i) 860 for (i = 0; i < MAX_CONNECTIONS; ++i)
827 if (connections[i].status == 3 && sendqueue(i) != 0) 861 if (connections[i].status == 3 && sendqueue(i) != 0)
828 if ((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) { 862 if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) {
829 for (j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) 863 for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate))
830 send_DATA(i); 864 send_DATA(i);
865
831 connections[i].last_sent = temp_time; 866 connections[i].last_sent = temp_time;
832 } 867 }
833} 868}
834 869
835#define MAX_SYNC_RATE 10 870#define MAX_SYNC_RATE 10
836 871
837/* 872/*
838 * Automatically adjusts send rates of packets for optimal transmission. 873 * Automatically adjusts send rates of packets for optimal transmission.
839 * 874 *
840 * TODO: flow control. 875 * TODO: flow control.
@@ -843,9 +878,11 @@ static void adjustRates(void)
843{ 878{
844 uint32_t i; 879 uint32_t i;
845 uint64_t temp_time = current_time(); 880 uint64_t temp_time = current_time();
881
846 for (i = 0; i < MAX_CONNECTIONS; ++i) { 882 for (i = 0; i < MAX_CONNECTIONS; ++i) {
847 if (connections[i].status == 1 || connections[i].status == 2) 883 if (connections[i].status == 1 || connections[i].status == 2)
848 connections[i].SYNC_rate = MAX_SYNC_RATE; 884 connections[i].SYNC_rate = MAX_SYNC_RATE;
885
849 if (connections[i].status == 3) { 886 if (connections[i].status == 3) {
850 if (sendqueue(i) != 0) { 887 if (sendqueue(i) != 0) {
851 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; 888 connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index 53afe606..bd426ee0 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -33,7 +33,7 @@ extern "C" {
33/* maximum length of the data in the data packets */ 33/* maximum length of the data in the data packets */
34#define MAX_DATA_SIZE 1024 34#define MAX_DATA_SIZE 1024
35 35
36/* 36/*
37 * Initialize a new connection to ip_port 37 * Initialize a new connection to ip_port
38 * Returns an integer corresponding to the connection id. 38 * Returns an integer corresponding to the connection id.
39 * Return -1 if it could not initialize the connection. 39 * Return -1 if it could not initialize the connection.
@@ -41,51 +41,51 @@ extern "C" {
41 */ 41 */
42int new_connection(IP_Port ip_port); 42int new_connection(IP_Port ip_port);
43 43
44/* 44/*
45 * Get connection id from IP_Port. 45 * Get connection id from IP_Port.
46 * Return -1 if there are no connections like we are looking for. 46 * Return -1 if there are no connections like we are looking for.
47 * Return id if it found it . 47 * Return id if it found it .
48 */ 48 */
49int getconnection_id(IP_Port ip_port); 49int getconnection_id(IP_Port ip_port);
50 50
51/* 51/*
52 * Returns an int corresponding to the next connection in our imcoming connection list 52 * Returns an int corresponding to the next connection in our imcoming connection list
53 * Return -1 if there are no new incoming connections in the list. 53 * Return -1 if there are no new incoming connections in the list.
54 */ 54 */
55int incoming_connection(void); 55int incoming_connection(void);
56 56
57/* 57/*
58 * Return -1 if it could not kill the connection. 58 * Return -1 if it could not kill the connection.
59 * Return 0 if killed successfully 59 * Return 0 if killed successfully
60 */ 60 */
61int kill_connection(int connection_id); 61int kill_connection(int connection_id);
62 62
63/* 63/*
64 * Kill connection in seconds seconds. 64 * Kill connection in seconds seconds.
65 * Return -1 if it can not kill the connection. 65 * Return -1 if it can not kill the connection.
66 * Return 0 if it will kill it 66 * Return 0 if it will kill it
67 */ 67 */
68int kill_connection_in(int connection_id, uint32_t seconds); 68int kill_connection_in(int connection_id, uint32_t seconds);
69 69
70/* 70/*
71 * Returns the ip_port of the corresponding connection. 71 * Returns the ip_port of the corresponding connection.
72 * Return 0 if there is no such connection. 72 * Return 0 if there is no such connection.
73 */ 73 */
74IP_Port connection_ip(int connection_id); 74IP_Port connection_ip(int connection_id);
75 75
76/* 76/*
77 * Returns the id of the next packet in the queue 77 * Returns the id of the next packet in the queue
78 * Return -1 if no packet in queue 78 * Return -1 if no packet in queue
79 */ 79 */
80char id_packet(int connection_id); 80char id_packet(int connection_id);
81 81
82/* 82/*
83 * Return 0 if there is no received data in the buffer. 83 * Return 0 if there is no received data in the buffer.
84 * Return length of received packet if successful 84 * Return length of received packet if successful
85 */ 85 */
86int read_packet(int connection_id, uint8_t *data); 86int read_packet(int connection_id, uint8_t *data);
87 87
88/* 88/*
89 * Return 0 if data could not be put in packet queue 89 * Return 0 if data could not be put in packet queue
90 * Return 1 if data was put into the queue 90 * Return 1 if data was put into the queue
91 */ 91 */
@@ -94,8 +94,8 @@ int write_packet(int connection_id, uint8_t *data, uint32_t length);
94/* Returns the number of packets in the queue waiting to be successfully sent. */ 94/* Returns the number of packets in the queue waiting to be successfully sent. */
95uint32_t sendqueue(int connection_id); 95uint32_t sendqueue(int connection_id);
96 96
97/* 97/*
98 * returns the number of packets in the queue waiting to be successfully 98 * returns the number of packets in the queue waiting to be successfully
99 * read with read_packet(...) 99 * read with read_packet(...)
100 */ 100 */
101uint32_t recvqueue(int connection_id); 101uint32_t recvqueue(int connection_id);
@@ -112,7 +112,7 @@ int is_connected(int connection_id);
112/* Call this function a couple times per second It's the main loop. */ 112/* Call this function a couple times per second It's the main loop. */
113void doLossless_UDP(void); 113void doLossless_UDP(void);
114 114
115/* 115/*
116 * This function sets up LosslessUDP packet handling. 116 * This function sets up LosslessUDP packet handling.
117 */ 117 */
118void LosslessUDP_init(void); 118void LosslessUDP_init(void);
diff --git a/core/Messenger.c b/core/Messenger.c
index 4ed8bc41..09032067 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -35,11 +35,14 @@ static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_i
35 35
36/* set the size of the friend list to numfriends 36/* set the size of the friend list to numfriends
37 return -1 if realloc fails */ 37 return -1 if realloc fails */
38int realloc_friendlist(Messenger *m, uint32_t num) { 38int realloc_friendlist(Messenger *m, uint32_t num)
39 Friend *newfriendlist = realloc(m->friendlist, num*sizeof(Friend)); 39{
40 Friend *newfriendlist = realloc(m->friendlist, num * sizeof(Friend));
41
40 if (newfriendlist == NULL) 42 if (newfriendlist == NULL)
41 return -1; 43 return -1;
42 memset(&newfriendlist[num-1], 0, sizeof(Friend)); 44
45 memset(&newfriendlist[num - 1], 0, sizeof(Friend));
43 m->friendlist = newfriendlist; 46 m->friendlist = newfriendlist;
44 return 0; 47 return 0;
45} 48}
@@ -85,8 +88,10 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
85 uint8_t checksum[2] = {0}; 88 uint8_t checksum[2] = {0};
86 uint16_t check; 89 uint16_t check;
87 uint32_t i; 90 uint32_t i;
88 for(i = 0; i < len; ++i) 91
92 for (i = 0; i < len; ++i)
89 checksum[i % 2] ^= address[i]; 93 checksum[i % 2] ^= address[i];
94
90 memcpy(&check, checksum, sizeof(check)); 95 memcpy(&check, checksum, sizeof(check));
91 return check; 96 return check;
92} 97}
@@ -125,25 +130,33 @@ void getaddress(Messenger *m, uint8_t *address)
125int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) 130int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
126{ 131{
127 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES 132 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
128 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES 133 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
129 + crypto_box_ZEROBYTES)) 134 + crypto_box_ZEROBYTES))
130 return FAERR_TOOLONG; 135 return FAERR_TOOLONG;
136
131 uint8_t client_id[crypto_box_PUBLICKEYBYTES]; 137 uint8_t client_id[crypto_box_PUBLICKEYBYTES];
132 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES); 138 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
133 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); 139 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
134 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check)); 140 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
141
135 if (check != checksum) 142 if (check != checksum)
136 return FAERR_BADCHECKSUM; 143 return FAERR_BADCHECKSUM;
144
137 if (length < 1) 145 if (length < 1)
138 return FAERR_NOMESSAGE; 146 return FAERR_NOMESSAGE;
147
139 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 148 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
140 return FAERR_OWNKEY; 149 return FAERR_OWNKEY;
150
141 int friend_id = getfriend_id(m, client_id); 151 int friend_id = getfriend_id(m, client_id);
152
142 if (friend_id != -1) { 153 if (friend_id != -1) {
143 uint32_t nospam; 154 uint32_t nospam;
144 memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam)); 155 memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam));
145 if(m->friendlist[friend_id].friendrequest_nospam == nospam) 156
157 if (m->friendlist[friend_id].friendrequest_nospam == nospam)
146 return FAERR_ALREADYSENT; 158 return FAERR_ALREADYSENT;
159
147 m->friendlist[friend_id].friendrequest_nospam = nospam; 160 m->friendlist[friend_id].friendrequest_nospam = nospam;
148 return FAERR_SETNEWNOSPAM; 161 return FAERR_SETNEWNOSPAM;
149 } 162 }
@@ -153,6 +166,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
153 return FAERR_NOMEM; 166 return FAERR_NOMEM;
154 167
155 uint32_t i; 168 uint32_t i;
169
156 for (i = 0; i <= m->numfriends; ++i) { 170 for (i = 0; i <= m->numfriends; ++i) {
157 if (m->friendlist[i].status == NOFRIEND) { 171 if (m->friendlist[i].status == NOFRIEND) {
158 DHT_addfriend(client_id); 172 DHT_addfriend(client_id);
@@ -173,10 +187,11 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
173 return i; 187 return i;
174 } 188 }
175 } 189 }
190
176 return FAERR_UNKNOWN; 191 return FAERR_UNKNOWN;
177} 192}
178 193
179int m_addfriend_norequest(Messenger *m, uint8_t * client_id) 194int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
180{ 195{
181 if (getfriend_id(m, client_id) != -1) 196 if (getfriend_id(m, client_id) != -1)
182 return -1; 197 return -1;
@@ -186,8 +201,9 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
186 return FAERR_NOMEM; 201 return FAERR_NOMEM;
187 202
188 uint32_t i; 203 uint32_t i;
204
189 for (i = 0; i <= m->numfriends; ++i) { 205 for (i = 0; i <= m->numfriends; ++i) {
190 if(m->friendlist[i].status == NOFRIEND) { 206 if (m->friendlist[i].status == NOFRIEND) {
191 DHT_addfriend(client_id); 207 DHT_addfriend(client_id);
192 m->friendlist[i].status = FRIEND_REQUESTED; 208 m->friendlist[i].status = FRIEND_REQUESTED;
193 m->friendlist[i].crypt_connection_id = -1; 209 m->friendlist[i].crypt_connection_id = -1;
@@ -202,6 +218,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
202 return i; 218 return i;
203 } 219 }
204 } 220 }
221
205 return -1; 222 return -1;
206} 223}
207 224
@@ -220,9 +237,10 @@ int m_delfriend(Messenger *m, int friendnumber)
220 uint32_t i; 237 uint32_t i;
221 238
222 for (i = m->numfriends; i != 0; --i) { 239 for (i = m->numfriends; i != 0; --i) {
223 if (m->friendlist[i-1].status != NOFRIEND) 240 if (m->friendlist[i - 1].status != NOFRIEND)
224 break; 241 break;
225 } 242 }
243
226 m->numfriends = i; 244 m->numfriends = i;
227 245
228 if (realloc_friendlist(m, m->numfriends + 1) != 0) 246 if (realloc_friendlist(m, m->numfriends + 1) != 0)
@@ -240,6 +258,7 @@ int m_friendstatus(Messenger *m, int friendnumber)
240{ 258{
241 if (friendnumber < 0 || friendnumber >= m->numfriends) 259 if (friendnumber < 0 || friendnumber >= m->numfriends)
242 return NOFRIEND; 260 return NOFRIEND;
261
243 return m->friendlist[friendnumber].status; 262 return m->friendlist[friendnumber].status;
244} 263}
245 264
@@ -250,10 +269,13 @@ uint32_t m_sendmessage(Messenger *m, int friendnumber, uint8_t *message, uint32_
250{ 269{
251 if (friendnumber < 0 || friendnumber >= m->numfriends) 270 if (friendnumber < 0 || friendnumber >= m->numfriends)
252 return 0; 271 return 0;
272
253 uint32_t msgid = ++m->friendlist[friendnumber].message_id; 273 uint32_t msgid = ++m->friendlist[friendnumber].message_id;
274
254 if (msgid == 0) 275 if (msgid == 0)
255 msgid = 1; /* otherwise, false error */ 276 msgid = 1; /* otherwise, false error */
256 if(m_sendmessage_withid(m, friendnumber, msgid, message, length)) { 277
278 if (m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
257 return msgid; 279 return msgid;
258 } 280 }
259 281
@@ -264,6 +286,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, ui
264{ 286{
265 if (length >= (MAX_DATA_SIZE - sizeof(theid))) 287 if (length >= (MAX_DATA_SIZE - sizeof(theid)))
266 return 0; 288 return 0;
289
267 uint8_t temp[MAX_DATA_SIZE]; 290 uint8_t temp[MAX_DATA_SIZE];
268 theid = htonl(theid); 291 theid = htonl(theid);
269 memcpy(temp, &theid, sizeof(theid)); 292 memcpy(temp, &theid, sizeof(theid));
@@ -281,20 +304,22 @@ int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t lengt
281 304
282/* send a name packet to friendnumber 305/* send a name packet to friendnumber
283 length is the length with the NULL terminator*/ 306 length is the length with the NULL terminator*/
284static int m_sendname(Messenger *m, int friendnumber, uint8_t * name, uint16_t length) 307static int m_sendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t length)
285{ 308{
286 if(length > MAX_NAME_LENGTH || length == 0) 309 if (length > MAX_NAME_LENGTH || length == 0)
287 return 0; 310 return 0;
311
288 return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length); 312 return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length);
289} 313}
290 314
291/* set the name of a friend 315/* set the name of a friend
292 return 0 if success 316 return 0 if success
293 return -1 if failure */ 317 return -1 if failure */
294static int setfriendname(Messenger *m, int friendnumber, uint8_t * name) 318static int setfriendname(Messenger *m, int friendnumber, uint8_t *name)
295{ 319{
296 if (friendnumber >= m->numfriends || friendnumber < 0) 320 if (friendnumber >= m->numfriends || friendnumber < 0)
297 return -1; 321 return -1;
322
298 memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH); 323 memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
299 return 0; 324 return 0;
300} 325}
@@ -305,15 +330,18 @@ static int setfriendname(Messenger *m, int friendnumber, uint8_t * name)
305 length is the length of name with the NULL terminator 330 length is the length of name with the NULL terminator
306 return 0 if success 331 return 0 if success
307 return -1 if failure */ 332 return -1 if failure */
308int setname(Messenger *m, uint8_t * name, uint16_t length) 333int setname(Messenger *m, uint8_t *name, uint16_t length)
309{ 334{
310 if (length > MAX_NAME_LENGTH || length == 0) 335 if (length > MAX_NAME_LENGTH || length == 0)
311 return -1; 336 return -1;
337
312 memcpy(m->name, name, length); 338 memcpy(m->name, name, length);
313 m->name_length = length; 339 m->name_length = length;
314 uint32_t i; 340 uint32_t i;
341
315 for (i = 0; i < m->numfriends; ++i) 342 for (i = 0; i < m->numfriends; ++i)
316 m->friendlist[i].name_sent = 0; 343 m->friendlist[i].name_sent = 0;
344
317 return 0; 345 return 0;
318} 346}
319 347
@@ -340,10 +368,11 @@ uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen)
340 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 368 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
341 return 0 if success 369 return 0 if success
342 return -1 if failure */ 370 return -1 if failure */
343int getname(Messenger *m, int friendnumber, uint8_t * name) 371int getname(Messenger *m, int friendnumber, uint8_t *name)
344{ 372{
345 if (friendnumber >= m->numfriends || friendnumber < 0) 373 if (friendnumber >= m->numfriends || friendnumber < 0)
346 return -1; 374 return -1;
375
347 memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH); 376 memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH);
348 return 0; 377 return 0;
349} 378}
@@ -352,12 +381,15 @@ int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length)
352{ 381{
353 if (length > MAX_STATUSMESSAGE_LENGTH) 382 if (length > MAX_STATUSMESSAGE_LENGTH)
354 return -1; 383 return -1;
384
355 memcpy(m->statusmessage, status, length); 385 memcpy(m->statusmessage, status, length);
356 m->statusmessage_length = length; 386 m->statusmessage_length = length;
357 387
358 uint32_t i; 388 uint32_t i;
389
359 for (i = 0; i < m->numfriends; ++i) 390 for (i = 0; i < m->numfriends; ++i)
360 m->friendlist[i].statusmessage_sent = 0; 391 m->friendlist[i].statusmessage_sent = 0;
392
361 return 0; 393 return 0;
362} 394}
363 395
@@ -366,10 +398,13 @@ int m_set_userstatus(Messenger *m, USERSTATUS status)
366 if (status >= USERSTATUS_INVALID) { 398 if (status >= USERSTATUS_INVALID) {
367 return -1; 399 return -1;
368 } 400 }
401
369 m->userstatus = status; 402 m->userstatus = status;
370 uint32_t i; 403 uint32_t i;
404
371 for (i = 0; i < m->numfriends; ++i) 405 for (i = 0; i < m->numfriends; ++i)
372 m->friendlist[i].userstatus_sent = 0; 406 m->friendlist[i].userstatus_sent = 0;
407
373 return 0; 408 return 0;
374} 409}
375 410
@@ -379,21 +414,23 @@ int m_get_statusmessage_size(Messenger *m, int friendnumber)
379{ 414{
380 if (friendnumber >= m->numfriends || friendnumber < 0) 415 if (friendnumber >= m->numfriends || friendnumber < 0)
381 return -1; 416 return -1;
417
382 return m->friendlist[friendnumber].statusmessage_length; 418 return m->friendlist[friendnumber].statusmessage_length;
383} 419}
384 420
385/* copy the user status of friendnumber into buf, truncating if needed to maxlen 421/* copy the user status of friendnumber into buf, truncating if needed to maxlen
386 bytes, use m_get_statusmessage_size to find out how much you need to allocate */ 422 bytes, use m_get_statusmessage_size to find out how much you need to allocate */
387int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t * buf, uint32_t maxlen) 423int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t *buf, uint32_t maxlen)
388{ 424{
389 if (friendnumber >= m->numfriends || friendnumber < 0) 425 if (friendnumber >= m->numfriends || friendnumber < 0)
390 return -1; 426 return -1;
427
391 memset(buf, 0, maxlen); 428 memset(buf, 0, maxlen);
392 memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); 429 memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
393 return 0; 430 return 0;
394} 431}
395 432
396int m_copy_self_statusmessage(Messenger *m, uint8_t * buf, uint32_t maxlen) 433int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen)
397{ 434{
398 memset(buf, 0, maxlen); 435 memset(buf, 0, maxlen);
399 memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); 436 memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
@@ -404,10 +441,13 @@ USERSTATUS m_get_userstatus(Messenger *m, int friendnumber)
404{ 441{
405 if (friendnumber >= m->numfriends || friendnumber < 0) 442 if (friendnumber >= m->numfriends || friendnumber < 0)
406 return USERSTATUS_INVALID; 443 return USERSTATUS_INVALID;
444
407 USERSTATUS status = m->friendlist[friendnumber].userstatus; 445 USERSTATUS status = m->friendlist[friendnumber].userstatus;
446
408 if (status >= USERSTATUS_INVALID) { 447 if (status >= USERSTATUS_INVALID) {
409 status = USERSTATUS_NONE; 448 status = USERSTATUS_NONE;
410 } 449 }
450
411 return status; 451 return status;
412} 452}
413 453
@@ -416,7 +456,7 @@ USERSTATUS m_get_self_userstatus(Messenger *m)
416 return m->userstatus; 456 return m->userstatus;
417} 457}
418 458
419static int send_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) 459static int send_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
420{ 460{
421 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length); 461 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length);
422} 462}
@@ -427,10 +467,11 @@ static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
427 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); 467 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat));
428} 468}
429 469
430static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) 470static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
431{ 471{
432 if (friendnumber >= m->numfriends || friendnumber < 0) 472 if (friendnumber >= m->numfriends || friendnumber < 0)
433 return -1; 473 return -1;
474
434 uint8_t *newstatus = calloc(length, 1); 475 uint8_t *newstatus = calloc(length, 1);
435 memcpy(newstatus, status, length); 476 memcpy(newstatus, status, length);
436 free(m->friendlist[friendnumber].statusmessage); 477 free(m->friendlist[friendnumber].statusmessage);
@@ -449,56 +490,61 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
449{ 490{
450 if (yesno != 0 || yesno != 1) 491 if (yesno != 0 || yesno != 1)
451 return; 492 return;
493
452 if (friendnumber >= m->numfriends || friendnumber < 0) 494 if (friendnumber >= m->numfriends || friendnumber < 0)
453 return; 495 return;
496
454 m->friendlist[friendnumber].receives_read_receipts = yesno; 497 m->friendlist[friendnumber].receives_read_receipts = yesno;
455} 498}
456 499
457/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */ 500/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */
458/* set the function that will be executed when a friend request is received. */ 501/* set the function that will be executed when a friend request is received. */
459void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata) 502void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
460{ 503{
461 callback_friendrequest(function, userdata); 504 callback_friendrequest(function, userdata);
462} 505}
463 506
464/* set the function that will be executed when a message from a friend is received. */ 507/* set the function that will be executed when a message from a friend is received. */
465void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 508void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
509 void *userdata)
466{ 510{
467 m->friend_message = function; 511 m->friend_message = function;
468 m->friend_message_userdata = userdata; 512 m->friend_message_userdata = userdata;
469} 513}
470 514
471void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 515void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), void *userdata)
472{ 516{
473 m->friend_action = function; 517 m->friend_action = function;
474 m->friend_action_userdata = userdata; 518 m->friend_action_userdata = userdata;
475} 519}
476 520
477void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 521void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
522 void *userdata)
478{ 523{
479 m->friend_namechange = function; 524 m->friend_namechange = function;
480 m->friend_namechange_userdata = userdata; 525 m->friend_namechange_userdata = userdata;
481} 526}
482 527
483void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 528void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
529 void *userdata)
484{ 530{
485 m->friend_statusmessagechange = function; 531 m->friend_statusmessagechange = function;
486 m->friend_statuschange_userdata = userdata; 532 m->friend_statuschange_userdata = userdata;
487} 533}
488 534
489void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata) 535void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata)
490{ 536{
491 m->friend_userstatuschange = function; 537 m->friend_userstatuschange = function;
492 m->friend_userstatuschange_userdata = userdata; 538 m->friend_userstatuschange_userdata = userdata;
493} 539}
494 540
495void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata) 541void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata)
496{ 542{
497 m->read_receipt = function; 543 m->read_receipt = function;
498 m->read_receipt_userdata = userdata; 544 m->read_receipt_userdata = userdata;
499} 545}
500 546
501void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata) 547void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata)
502{ 548{
503 m->friend_connectionstatuschange = function; 549 m->friend_connectionstatuschange = function;
504 m->friend_connectionstatuschange_userdata = userdata; 550 m->friend_connectionstatuschange_userdata = userdata;
@@ -508,10 +554,13 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
508{ 554{
509 if (!m->friend_connectionstatuschange) 555 if (!m->friend_connectionstatuschange)
510 return; 556 return;
557
511 if (status == NOFRIEND) 558 if (status == NOFRIEND)
512 return; 559 return;
560
513 const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE; 561 const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE;
514 const uint8_t is_connected = status == FRIEND_ONLINE; 562 const uint8_t is_connected = status == FRIEND_ONLINE;
563
515 if (is_connected != was_connected) 564 if (is_connected != was_connected)
516 m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata); 565 m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata);
517} 566}
@@ -526,8 +575,10 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
526{ 575{
527 if (friendnumber < 0 || friendnumber >= m->numfriends) 576 if (friendnumber < 0 || friendnumber >= m->numfriends)
528 return 0; 577 return 0;
578
529 if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE) 579 if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
530 return 0; 580 return 0;
581
531 uint8_t packet[length + 1]; 582 uint8_t packet[length + 1];
532 packet[0] = packet_id; 583 packet[0] = packet_id;
533 memcpy(packet + 1, data, length); 584 memcpy(packet + 1, data, length);
@@ -541,7 +592,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
541#define PORT 33445 592#define PORT 33445
542 593
543/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 594/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
544int LANdiscovery(timer* t, void* arg) 595int LANdiscovery(timer *t, void *arg)
545{ 596{
546 send_LANdiscovery(htons(PORT)); 597 send_LANdiscovery(htons(PORT));
547 timer_start(t, LAN_DISCOVERY_INTERVAL); 598 timer_start(t, LAN_DISCOVERY_INTERVAL);
@@ -549,19 +600,20 @@ int LANdiscovery(timer* t, void* arg)
549} 600}
550 601
551/* run this at startup */ 602/* run this at startup */
552Messenger * initMessenger(void) 603Messenger *initMessenger(void)
553{ 604{
554 Messenger *m = calloc(1, sizeof(Messenger)); 605 Messenger *m = calloc(1, sizeof(Messenger));
555 if( ! m ) 606
607 if ( ! m )
556 return 0; 608 return 0;
557 609
558 new_keys(); 610 new_keys();
559 m_set_statusmessage(m, (uint8_t*)"Online", sizeof("Online")); 611 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
560 initNetCrypto(); 612 initNetCrypto();
561 IP ip; 613 IP ip;
562 ip.i = 0; 614 ip.i = 0;
563 615
564 if(init_networking(ip,PORT) == -1) 616 if (init_networking(ip, PORT) == -1)
565 return 0; 617 return 0;
566 618
567 DHT_init(); 619 DHT_init();
@@ -576,7 +628,8 @@ Messenger * initMessenger(void)
576} 628}
577 629
578/* run this before closing shop */ 630/* run this before closing shop */
579void cleanupMessenger(Messenger *m){ 631void cleanupMessenger(Messenger *m)
632{
580 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger 633 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger
581 * this requires the other modules to expose cleanup functions 634 * this requires the other modules to expose cleanup functions
582 */ 635 */
@@ -591,117 +644,155 @@ void doFriends(Messenger *m)
591 uint32_t i; 644 uint32_t i;
592 int len; 645 int len;
593 uint8_t temp[MAX_DATA_SIZE]; 646 uint8_t temp[MAX_DATA_SIZE];
647
594 for (i = 0; i < m->numfriends; ++i) { 648 for (i = 0; i < m->numfriends; ++i) {
595 if (m->friendlist[i].status == FRIEND_ADDED) { 649 if (m->friendlist[i].status == FRIEND_ADDED) {
596 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size); 650 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
651 m->friendlist[i].info_size);
652
597 if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */ 653 if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
598 set_friend_status(m, i, FRIEND_REQUESTED); 654 set_friend_status(m, i, FRIEND_REQUESTED);
599 else if (fr > 0) 655 else if (fr > 0)
600 set_friend_status(m, i, FRIEND_REQUESTED); 656 set_friend_status(m, i, FRIEND_REQUESTED);
601 } 657 }
602 if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ 658
659 if (m->friendlist[i].status == FRIEND_REQUESTED
660 || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
603 if (m->friendlist[i].status == FRIEND_REQUESTED) { 661 if (m->friendlist[i].status == FRIEND_REQUESTED) {
604 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ 662 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
605 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size); 663 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
664 m->friendlist[i].info_size);
606 m->friendlist[i].friend_request_id = unix_time(); 665 m->friendlist[i].friend_request_id = unix_time();
607 } 666 }
608 } 667 }
668
609 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); 669 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
670
610 switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { 671 switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) {
611 case 0: 672 case 0:
612 if (friendip.ip.i > 1) 673 if (friendip.ip.i > 1)
613 m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); 674 m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip);
614 break; 675
615 case 3: /* Connection is established */ 676 break;
616 set_friend_status(m, i, FRIEND_ONLINE); 677
617 m->friendlist[i].name_sent = 0; 678 case 3: /* Connection is established */
618 m->friendlist[i].userstatus_sent = 0; 679 set_friend_status(m, i, FRIEND_ONLINE);
619 m->friendlist[i].statusmessage_sent = 0; 680 m->friendlist[i].name_sent = 0;
620 break; 681 m->friendlist[i].userstatus_sent = 0;
621 case 4: 682 m->friendlist[i].statusmessage_sent = 0;
622 crypto_kill(m->friendlist[i].crypt_connection_id); 683 break;
623 m->friendlist[i].crypt_connection_id = -1; 684
624 break; 685 case 4:
625 default: 686 crypto_kill(m->friendlist[i].crypt_connection_id);
626 break; 687 m->friendlist[i].crypt_connection_id = -1;
688 break;
689
690 default:
691 break;
627 } 692 }
628 } 693 }
694
629 while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ 695 while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */
630 if (m->friendlist[i].name_sent == 0) { 696 if (m->friendlist[i].name_sent == 0) {
631 if (m_sendname(m, i, m->name, m->name_length)) 697 if (m_sendname(m, i, m->name, m->name_length))
632 m->friendlist[i].name_sent = 1; 698 m->friendlist[i].name_sent = 1;
633 } 699 }
700
634 if (m->friendlist[i].statusmessage_sent == 0) { 701 if (m->friendlist[i].statusmessage_sent == 0) {
635 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) 702 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length))
636 m->friendlist[i].statusmessage_sent = 1; 703 m->friendlist[i].statusmessage_sent = 1;
637 } 704 }
705
638 if (m->friendlist[i].userstatus_sent == 0) { 706 if (m->friendlist[i].userstatus_sent == 0) {
639 if (send_userstatus(m, i, m->userstatus)) 707 if (send_userstatus(m, i, m->userstatus))
640 m->friendlist[i].userstatus_sent = 1; 708 m->friendlist[i].userstatus_sent = 1;
641 } 709 }
710
642 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); 711 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp);
643 uint8_t packet_id = temp[0]; 712 uint8_t packet_id = temp[0];
644 uint8_t* data = temp + 1; 713 uint8_t *data = temp + 1;
645 int data_length = len - 1; 714 int data_length = len - 1;
715
646 if (len > 0) { 716 if (len > 0) {
647 switch (packet_id) { 717 switch (packet_id) {
648 case PACKET_ID_NICKNAME: { 718 case PACKET_ID_NICKNAME: {
649 if (data_length >= MAX_NAME_LENGTH || data_length == 0) 719 if (data_length >= MAX_NAME_LENGTH || data_length == 0)
720 break;
721
722 if (m->friend_namechange)
723 m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata);
724
725 memcpy(m->friendlist[i].name, data, data_length);
726 m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */
650 break; 727 break;
651 if(m->friend_namechange) 728 }
652 m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata); 729
653 memcpy(m->friendlist[i].name, data, data_length); 730 case PACKET_ID_STATUSMESSAGE: {
654 m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */ 731 if (data_length == 0)
655 break; 732 break;
656 } 733
657 case PACKET_ID_STATUSMESSAGE: { 734 uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1);
658 if (data_length == 0) 735 memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
736
737 if (m->friend_statusmessagechange)
738 m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH),
739 m->friend_statuschange_userdata);
740
741 set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
742 free(status);
659 break; 743 break;
660 uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1); 744 }
661 memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 745
662 if (m->friend_statusmessagechange) 746 case PACKET_ID_USERSTATUS: {
663 m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 747 if (data_length != 1)
664 m->friend_statuschange_userdata); 748 break;
665 set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 749
666 free(status); 750 USERSTATUS status = data[0];
667 break; 751
668 } 752 if (m->friend_userstatuschange)
669 case PACKET_ID_USERSTATUS: { 753 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
670 if (data_length != 1) 754
755 set_friend_userstatus(m, i, status);
671 break; 756 break;
672 USERSTATUS status = data[0];
673 if (m->friend_userstatuschange)
674 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
675 set_friend_userstatus(m, i, status);
676 break;
677 }
678 case PACKET_ID_MESSAGE: {
679 uint8_t *message_id = data;
680 uint8_t message_id_length = 4;
681 uint8_t *message = data + message_id_length;
682 uint16_t message_length = data_length - message_id_length;
683 if (m->friendlist[i].receives_read_receipts) {
684 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
685 } 757 }
686 if (m->friend_message) 758
687 (*m->friend_message)(m, i, message, message_length, m->friend_message_userdata); 759 case PACKET_ID_MESSAGE: {
688 break; 760 uint8_t *message_id = data;
689 } 761 uint8_t message_id_length = 4;
690 case PACKET_ID_ACTION: { 762 uint8_t *message = data + message_id_length;
691 if (m->friend_action) 763 uint16_t message_length = data_length - message_id_length;
692 (*m->friend_action)(m, i, data, data_length, m->friend_action_userdata); 764
693 break; 765 if (m->friendlist[i].receives_read_receipts) {
694 } 766 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
695 case PACKET_ID_RECEIPT: { 767 }
696 uint32_t msgid; 768
697 if (data_length < sizeof(msgid)) 769 if (m->friend_message)
770 (*m->friend_message)(m, i, message, message_length, m->friend_message_userdata);
771
698 break; 772 break;
699 memcpy(&msgid, data, sizeof(msgid)); 773 }
700 msgid = ntohl(msgid); 774
701 if (m->read_receipt) 775 case PACKET_ID_ACTION: {
702 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata); 776 if (m->friend_action)
703 break; 777 (*m->friend_action)(m, i, data, data_length, m->friend_action_userdata);
704 } 778
779 break;
780 }
781
782 case PACKET_ID_RECEIPT: {
783 uint32_t msgid;
784
785 if (data_length < sizeof(msgid))
786 break;
787
788 memcpy(&msgid, data, sizeof(msgid));
789 msgid = ntohl(msgid);
790
791 if (m->read_receipt)
792 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
793
794 break;
795 }
705 } 796 }
706 } else { 797 } else {
707 if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ 798 if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
@@ -709,6 +800,7 @@ void doFriends(Messenger *m)
709 m->friendlist[i].crypt_connection_id = -1; 800 m->friendlist[i].crypt_connection_id = -1;
710 set_friend_status(m, i, FRIEND_CONFIRMED); 801 set_friend_status(m, i, FRIEND_CONFIRMED);
711 } 802 }
803
712 break; 804 break;
713 } 805 }
714 } 806 }
@@ -721,8 +813,10 @@ void doInbound(Messenger *m)
721 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 813 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
722 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 814 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
723 int inconnection = crypto_inbound(public_key, secret_nonce, session_key); 815 int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
816
724 if (inconnection != -1) { 817 if (inconnection != -1) {
725 int friend_id = getfriend_id(m, public_key); 818 int friend_id = getfriend_id(m, public_key);
819
726 if (friend_id != -1) { 820 if (friend_id != -1) {
727 crypto_kill(m->friendlist[friend_id].crypt_connection_id); 821 crypto_kill(m->friendlist[friend_id].crypt_connection_id);
728 m->friendlist[friend_id].crypt_connection_id = 822 m->friendlist[friend_id].crypt_connection_id =
@@ -775,12 +869,14 @@ void Messenger_save(Messenger *m, uint8_t *data)
775} 869}
776 870
777/* load the messenger from data of size length. */ 871/* load the messenger from data of size length. */
778int Messenger_load(Messenger *m, uint8_t * data, uint32_t length) 872int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
779{ 873{
780 if (length == ~0) 874 if (length == ~0)
781 return -1; 875 return -1;
876
782 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3) 877 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3)
783 return -1; 878 return -1;
879
784 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; 880 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
785 load_keys(data); 881 load_keys(data);
786 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 882 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@@ -794,23 +890,28 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
794 890
795 if (length < size) 891 if (length < size)
796 return -1; 892 return -1;
893
797 length -= size; 894 length -= size;
895
798 if (DHT_load(data, size) == -1) 896 if (DHT_load(data, size) == -1)
799 return -1; 897 return -1;
898
800 data += size; 899 data += size;
801 memcpy(&size, data, sizeof(size)); 900 memcpy(&size, data, sizeof(size));
802 data += sizeof(size); 901 data += sizeof(size);
902
803 if (length != size || length % sizeof(Friend) != 0) 903 if (length != size || length % sizeof(Friend) != 0)
804 return -1; 904 return -1;
805 905
806 Friend * temp = malloc(size); 906 Friend *temp = malloc(size);
807 memcpy(temp, data, size); 907 memcpy(temp, data, size);
808 908
809 uint16_t num = size / sizeof(Friend); 909 uint16_t num = size / sizeof(Friend);
810 910
811 uint32_t i; 911 uint32_t i;
912
812 for (i = 0; i < num; ++i) { 913 for (i = 0; i < num; ++i) {
813 if(temp[i].status >= 3) { 914 if (temp[i].status >= 3) {
814 int fnum = m_addfriend_norequest(m, temp[i].client_id); 915 int fnum = m_addfriend_norequest(m, temp[i].client_id);
815 setfriendname(m, fnum, temp[i].name); 916 setfriendname(m, fnum, temp[i].name);
816 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ 917 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
@@ -824,6 +925,7 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
824 m_addfriend(m, address, temp[i].info, temp[i].info_size); 925 m_addfriend(m, address, temp[i].info, temp[i].info_size);
825 } 926 }
826 } 927 }
928
827 free(temp); 929 free(temp);
828 return 0; 930 return 0;
829} 931}
diff --git a/core/Messenger.h b/core/Messenger.h
index e12b3fc8..cd9e6e63 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -76,7 +76,8 @@ typedef enum {
76 USERSTATUS_AWAY, 76 USERSTATUS_AWAY,
77 USERSTATUS_BUSY, 77 USERSTATUS_BUSY,
78 USERSTATUS_INVALID 78 USERSTATUS_INVALID
79} USERSTATUS; 79}
80USERSTATUS;
80 81
81typedef struct { 82typedef struct {
82 uint8_t client_id[CLIENT_ID_SIZE]; 83 uint8_t client_id[CLIENT_ID_SIZE];
@@ -111,22 +112,22 @@ typedef struct Messenger {
111 Friend *friendlist; 112 Friend *friendlist;
112 uint32_t numfriends; 113 uint32_t numfriends;
113 114
114 void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void*); 115 void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
115 void* friend_message_userdata; 116 void *friend_message_userdata;
116 void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void*); 117 void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
117 void* friend_action_userdata; 118 void *friend_action_userdata;
118 void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*); 119 void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
119 void* friend_namechange_userdata; 120 void *friend_namechange_userdata;
120 void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*); 121 void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
121 void* friend_statusmessagechange_userdata; 122 void *friend_statusmessagechange_userdata;
122 void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void*); 123 void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void *);
123 void* friend_userstatuschange_userdata; 124 void *friend_userstatuschange_userdata;
124 void (*read_receipt)(struct Messenger *m, int, uint32_t, void*); 125 void (*read_receipt)(struct Messenger *m, int, uint32_t, void *);
125 void* read_receipt_userdata; 126 void *read_receipt_userdata;
126 void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void*); 127 void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void *);
127 void* friend_statuschange_userdata; 128 void *friend_statuschange_userdata;
128 void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void*); 129 void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void *);
129 void* friend_connectionstatuschange_userdata; 130 void *friend_connectionstatuschange_userdata;
130 131
131 132
132} Messenger; 133} Messenger;
@@ -255,29 +256,32 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno);
255 256
256/* set the function that will be executed when a friend request is received. 257/* set the function that will be executed when a friend request is received.
257 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 258 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
258void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata); 259void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
259 260
260/* set the function that will be executed when a message from a friend is received. 261/* set the function that will be executed when a message from a friend is received.
261 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ 262 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
262void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); 263void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
264 void *userdata);
263 265
264/* set the function that will be executed when an action from a friend is received. 266/* set the function that will be executed when an action from a friend is received.
265 function format is: function(int friendnumber, uint8_t * action, uint32_t length) */ 267 function format is: function(int friendnumber, uint8_t * action, uint32_t length) */
266void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); 268void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), void *userdata);
267 269
268/* set the callback for name changes 270/* set the callback for name changes
269 function(int friendnumber, uint8_t *newname, uint16_t length) 271 function(int friendnumber, uint8_t *newname, uint16_t length)
270 you are not responsible for freeing newname */ 272 you are not responsible for freeing newname */
271void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); 273void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
274 void *userdata);
272 275
273/* set the callback for status message changes 276/* set the callback for status message changes
274 function(int friendnumber, uint8_t *newstatus, uint16_t length) 277 function(int friendnumber, uint8_t *newstatus, uint16_t length)
275 you are not responsible for freeing newstatus */ 278 you are not responsible for freeing newstatus */
276void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); 279void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
280 void *userdata);
277 281
278/* set the callback for status type changes 282/* set the callback for status type changes
279 function(int friendnumber, USERSTATUS kind) */ 283 function(int friendnumber, USERSTATUS kind) */
280void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata); 284void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata);
281 285
282/* set the callback for read receipts 286/* set the callback for read receipts
283 function(int friendnumber, uint32_t receipt) 287 function(int friendnumber, uint32_t receipt)
@@ -286,7 +290,7 @@ void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USE
286 has been received on the other side. since core doesn't 290 has been received on the other side. since core doesn't
287 track ids for you, receipt may not correspond to any message 291 track ids for you, receipt may not correspond to any message
288 in that case, you should discard it. */ 292 in that case, you should discard it. */
289void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata); 293void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata);
290 294
291/* set the callback for connection status changes 295/* set the callback for connection status changes
292 function(int friendnumber, uint8_t status) 296 function(int friendnumber, uint8_t status)
@@ -296,12 +300,12 @@ void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, u
296 note that this callback is not called when adding friends, thus the "after 300 note that this callback is not called when adding friends, thus the "after
297 being previously online" part. it's assumed that when adding friends, 301 being previously online" part. it's assumed that when adding friends,
298 their connection status is offline. */ 302 their connection status is offline. */
299void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata); 303void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata);
300 304
301/* run this at startup 305/* run this at startup
302 * returns allocated instance of Messenger on success 306 * returns allocated instance of Messenger on success
303 * returns 0 if there are problems */ 307 * returns 0 if there are problems */
304Messenger * initMessenger(void); 308Messenger *initMessenger(void);
305 309
306/* run this before closing shop 310/* run this before closing shop
307 * free all datastructures */ 311 * free all datastructures */
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 00beaa14..3708f154 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -31,16 +31,17 @@ uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
31 return -1 if failure. 31 return -1 if failure.
32 return 0 if it sent the friend request directly to the friend. 32 return 0 if it sent the friend request directly to the friend.
33 return the number of peers it was routed through if it did not send it directly.*/ 33 return the number of peers it was routed through if it did not send it directly.*/
34int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data, uint32_t length) 34int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
35{ 35{
36 if(length + sizeof(nospam_num) > MAX_DATA_SIZE) 36 if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
37 return -1; 37 return -1;
38 38
39 uint8_t temp[MAX_DATA_SIZE]; 39 uint8_t temp[MAX_DATA_SIZE];
40 memcpy(temp, &nospam_num, sizeof(nospam_num)); 40 memcpy(temp, &nospam_num, sizeof(nospam_num));
41 memcpy(temp + sizeof(nospam_num), data, length); 41 memcpy(temp + sizeof(nospam_num), data, length);
42 uint8_t packet[MAX_DATA_SIZE]; 42 uint8_t packet[MAX_DATA_SIZE];
43 int len = create_request(packet, public_key, temp, length + sizeof(nospam_num), 32); /* 32 is friend request packet id */ 43 int len = create_request(packet, public_key, temp, length + sizeof(nospam_num),
44 32); /* 32 is friend request packet id */
44 45
45 if (len == -1) 46 if (len == -1)
46 return -1; 47 return -1;
@@ -53,6 +54,7 @@ int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data
53 if (ip_port.ip.i != 0) { 54 if (ip_port.ip.i != 0) {
54 if (sendpacket(ip_port, packet, len) != -1) 55 if (sendpacket(ip_port, packet, len) != -1)
55 return 0; 56 return 0;
57
56 return -1; 58 return -1;
57 } 59 }
58 60
@@ -78,11 +80,11 @@ uint32_t get_nospam()
78 return nospam; 80 return nospam;
79} 81}
80 82
81static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void*); 83static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *);
82static uint8_t handle_friendrequest_isset = 0; 84static uint8_t handle_friendrequest_isset = 0;
83static void* handle_friendrequest_userdata; 85static void *handle_friendrequest_userdata;
84/* set the function that will be executed when a friend request is received. */ 86/* set the function that will be executed when a friend request is received. */
85void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata) 87void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
86{ 88{
87 handle_friendrequest = function; 89 handle_friendrequest = function;
88 handle_friendrequest_isset = 1; 90 handle_friendrequest_isset = 1;
@@ -99,7 +101,7 @@ static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]
99static uint16_t received_requests_index; 101static uint16_t received_requests_index;
100 102
101/*Add to list of received friend requests*/ 103/*Add to list of received friend requests*/
102static void addto_receivedlist(uint8_t * client_id) 104static void addto_receivedlist(uint8_t *client_id)
103{ 105{
104 if (received_requests_index >= MAX_RECEIVED_STORED) 106 if (received_requests_index >= MAX_RECEIVED_STORED)
105 received_requests_index = 0; 107 received_requests_index = 0;
@@ -110,7 +112,7 @@ static void addto_receivedlist(uint8_t * client_id)
110 112
111/* Check if a friend request was already received 113/* Check if a friend request was already received
112 return 0 if not, 1 if we did */ 114 return 0 if not, 1 if we did */
113static int request_received(uint8_t * client_id) 115static int request_received(uint8_t *client_id)
114{ 116{
115 uint32_t i; 117 uint32_t i;
116 118
@@ -123,14 +125,17 @@ static int request_received(uint8_t * client_id)
123} 125}
124 126
125 127
126static int friendreq_handlepacket(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) 128static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
127{ 129{
128 if (handle_friendrequest_isset == 0) 130 if (handle_friendrequest_isset == 0)
129 return 1; 131 return 1;
132
130 if (length <= sizeof(nospam)) 133 if (length <= sizeof(nospam))
131 return 1; 134 return 1;
135
132 if (request_received(source_pubkey)) 136 if (request_received(source_pubkey))
133 return 1; 137 return 1;
138
134 if (memcmp(packet, &nospam, sizeof(nospam)) != 0) 139 if (memcmp(packet, &nospam, sizeof(nospam)) != 0)
135 return 1; 140 return 1;
136 141
diff --git a/core/friend_requests.h b/core/friend_requests.h
index 0b75fd60..3ce0df8c 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -33,7 +33,7 @@ extern "C" {
33 33
34/* Try to send a friendrequest to peer with public_key 34/* Try to send a friendrequest to peer with public_key
35 data is the data in the request and length is the length. */ 35 data is the data in the request and length is the length. */
36int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data, uint32_t length); 36int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
37/* 37/*
38 * Set and get the nospam variable used to prevent one type of friend request spam 38 * Set and get the nospam variable used to prevent one type of friend request spam
39 */ 39 */
@@ -42,7 +42,7 @@ uint32_t get_nospam();
42 42
43/* set the function that will be executed when a friend request for us is received. 43/* set the function that will be executed when a friend request for us is received.
44 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 44 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
45void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata); 45void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
46 46
47/* sets up friendreq packet handlers */ 47/* sets up friendreq packet handlers */
48void friendreq_init(void); 48void friendreq_init(void);
diff --git a/core/net_crypto.c b/core/net_crypto.c
index a05208ef..4b7fa043 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -65,14 +65,16 @@ uint8_t crypto_iszero(uint8_t *mem, uint32_t length)
65{ 65{
66 uint8_t check = 0; 66 uint8_t check = 0;
67 uint32_t i; 67 uint32_t i;
68
68 for (i = 0; i < length; ++i) { 69 for (i = 0; i < length; ++i) {
69 check |= mem[i]; 70 check |= mem[i];
70 } 71 }
72
71 return check; // We return zero if mem is made out of zeroes. 73 return check; // We return zero if mem is made out of zeroes.
72} 74}
73 75
74/* Precomputes the shared key from their public_key and our secret_key. 76/* Precomputes the shared key from their public_key and our secret_key.
75 This way we can avoid an expensive elliptic curve scalar multiply for each 77 This way we can avoid an expensive elliptic curve scalar multiply for each
76 encrypt/decrypt operation. 78 encrypt/decrypt operation.
77 enc_key has to be crypto_box_BEFORENMBYTES bytes long. */ 79 enc_key has to be crypto_box_BEFORENMBYTES bytes long. */
78void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key) 80void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key)
@@ -81,7 +83,7 @@ void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_k
81} 83}
82 84
83/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ 85/* Fast encrypt. Depends on enc_key from encrypt_precompute. */
84int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 86int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
85 uint8_t *plain, uint32_t length, uint8_t *encrypted) 87 uint8_t *plain, uint32_t length, uint8_t *encrypted)
86{ 88{
87 if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) 89 if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0)
@@ -94,7 +96,7 @@ int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
94 96
95 crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key); 97 crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key);
96 98
97 if(crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) 99 if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0)
98 return -1; 100 return -1;
99 101
100 /* unpad the encrypted message */ 102 /* unpad the encrypted message */
@@ -118,9 +120,9 @@ int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
118 nonce, enc_key) == -1) 120 nonce, enc_key) == -1)
119 return -1; 121 return -1;
120 122
121 /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero 123 /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero
122 apparently memcmp should not be used so we do this instead:*/ 124 apparently memcmp should not be used so we do this instead:*/
123 if(crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) 125 if (crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0)
124 return -1; 126 return -1;
125 127
126 /* unpad the plain message */ 128 /* unpad the plain message */
@@ -148,9 +150,11 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
148static void increment_nonce(uint8_t *nonce) 150static void increment_nonce(uint8_t *nonce)
149{ 151{
150 uint32_t i; 152 uint32_t i;
153
151 for (i = 0; i < crypto_box_NONCEBYTES; ++i) { 154 for (i = 0; i < crypto_box_NONCEBYTES; ++i) {
152 ++nonce[i]; 155 ++nonce[i];
153 if(nonce[i] != 0) 156
157 if (nonce[i] != 0)
154 break; 158 break;
155 } 159 }
156} 160}
@@ -159,6 +163,7 @@ static void increment_nonce(uint8_t *nonce)
159void random_nonce(uint8_t *nonce) 163void random_nonce(uint8_t *nonce)
160{ 164{
161 uint32_t i, temp; 165 uint32_t i, temp;
166
162 for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) { 167 for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) {
163 temp = random_int(); 168 temp = random_int();
164 memcpy(nonce + 4 * i, &temp, 4); 169 memcpy(nonce + 4 * i, &temp, 4);
@@ -172,21 +177,28 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
172{ 177{
173 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 178 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
174 return 0; 179 return 0;
180
175 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) 181 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
176 return 0; 182 return 0;
183
177 uint8_t temp_data[MAX_DATA_SIZE]; 184 uint8_t temp_data[MAX_DATA_SIZE];
178 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); 185 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
186
179 if (length == 0) 187 if (length == 0)
180 return 0; 188 return 0;
189
181 if (temp_data[0] != 3) 190 if (temp_data[0] != 3)
182 return -1; 191 return -1;
192
183 int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, 193 int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key,
184 crypto_connections[crypt_connection_id].recv_nonce, 194 crypto_connections[crypt_connection_id].recv_nonce,
185 temp_data + 1, length - 1, data); 195 temp_data + 1, length - 1, data);
196
186 if (len != -1) { 197 if (len != -1) {
187 increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); 198 increment_nonce(crypto_connections[crypt_connection_id].recv_nonce);
188 return len; 199 return len;
189 } 200 }
201
190 return -1; 202 return -1;
191} 203}
192 204
@@ -196,19 +208,26 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
196{ 208{
197 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 209 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
198 return 0; 210 return 0;
211
199 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) 212 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
200 return 0; 213 return 0;
214
201 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) 215 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
202 return 0; 216 return 0;
217
203 uint8_t temp_data[MAX_DATA_SIZE]; 218 uint8_t temp_data[MAX_DATA_SIZE];
204 int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, 219 int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key,
205 crypto_connections[crypt_connection_id].sent_nonce, 220 crypto_connections[crypt_connection_id].sent_nonce,
206 data, length, temp_data + 1); 221 data, length, temp_data + 1);
222
207 if (len == -1) 223 if (len == -1)
208 return 0; 224 return 0;
225
209 temp_data[0] = 3; 226 temp_data[0] = 3;
227
210 if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) 228 if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
211 return 0; 229 return 0;
230
212 increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); 231 increment_nonce(crypto_connections[crypt_connection_id].sent_nonce);
213 return 1; 232 return 1;
214} 233}
@@ -223,6 +242,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
223{ 242{
224 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) 243 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING)
225 return -1; 244 return -1;
245
226 uint8_t nonce[crypto_box_NONCEBYTES]; 246 uint8_t nonce[crypto_box_NONCEBYTES];
227 uint8_t temp[MAX_DATA_SIZE]; 247 uint8_t temp[MAX_DATA_SIZE];
228 memcpy(temp + 1, data, length); 248 memcpy(temp + 1, data, length);
@@ -230,8 +250,10 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
230 random_nonce(nonce); 250 random_nonce(nonce);
231 int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1, 251 int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1,
232 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 252 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
253
233 if (len == -1) 254 if (len == -1)
234 return -1; 255 return -1;
256
235 packet[0] = 32; 257 packet[0] = 32;
236 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 258 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
237 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); 259 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES);
@@ -248,16 +270,19 @@ static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_i
248{ 270{
249 271
250 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 272 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
251 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && 273 length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
252 memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 274 memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
253 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); 275 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
254 uint8_t nonce[crypto_box_NONCEBYTES]; 276 uint8_t nonce[crypto_box_NONCEBYTES];
255 uint8_t temp[MAX_DATA_SIZE]; 277 uint8_t temp[MAX_DATA_SIZE];
256 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); 278 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
257 int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, 279 int len1 = decrypt_data(public_key, self_secret_key, nonce,
280 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
258 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); 281 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
259 if(len1 == -1 || len1 == 0) 282
283 if (len1 == -1 || len1 == 0)
260 return -1; 284 return -1;
285
261 request_id[0] = temp[0]; 286 request_id[0] = temp[0];
262 --len1; 287 --len1;
263 memcpy(data, temp + 1, len1); 288 memcpy(data, temp + 1, len1);
@@ -273,27 +298,32 @@ void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb
273 cryptopackethandlers[byte] = cb; 298 cryptopackethandlers[byte] = cb;
274} 299}
275 300
276static int cryptopacket_handle(IP_Port source, uint8_t * packet, uint32_t length) 301static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length)
277{ 302{
278 if (packet[0] == 32) { 303 if (packet[0] == 32) {
279 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || 304 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING ||
280 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 305 length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
281 return 1; 306 return 1;
307
282 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. 308 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us.
283 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 309 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
284 uint8_t data[MAX_DATA_SIZE]; 310 uint8_t data[MAX_DATA_SIZE];
285 uint8_t number; 311 uint8_t number;
286 int len = handle_request(public_key, data, &number, packet, length); 312 int len = handle_request(public_key, data, &number, packet, length);
313
287 if (len == -1 || len == 0) 314 if (len == -1 || len == 0)
288 return 1; 315 return 1;
316
289 if (!cryptopackethandlers[number]) return 1; 317 if (!cryptopackethandlers[number]) return 1;
318
290 cryptopackethandlers[number](source, public_key, data, len); 319 cryptopackethandlers[number](source, public_key, data, len);
291 320
292 } else { /* if request is not for us, try routing it. */ 321 } else { /* if request is not for us, try routing it. */
293 if(route_packet(packet + 1, packet, length) == length) 322 if (route_packet(packet + 1, packet, length) == length)
294 return 0; 323 return 0;
295 } 324 }
296 } 325 }
326
297 return 1; 327 return 1;
298} 328}
299 329
@@ -312,8 +342,10 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t
312 342
313 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 343 int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
314 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 344 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
345
315 if (len == -1) 346 if (len == -1)
316 return 0; 347 return 0;
348
317 temp_data[0] = 2; 349 temp_data[0] = 2;
318 memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); 350 memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
319 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 351 memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
@@ -324,15 +356,18 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t
324 return 1 if successful 356 return 1 if successful
325 return 0 if failure */ 357 return 0 if failure */
326static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, 358static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
327 uint8_t *session_key, uint8_t *data, uint16_t length) 359 uint8_t *session_key, uint8_t *data, uint16_t length)
328{ 360{
329 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); 361 int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
362
330 if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES 363 if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
331 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) { 364 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) {
332 return 0; 365 return 0;
333 } 366 }
367
334 if (data[0] != 2) 368 if (data[0] != 2)
335 return 0; 369 return 0;
370
336 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; 371 uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
337 372
338 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); 373 memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
@@ -355,11 +390,13 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
355static int getcryptconnection_id(uint8_t *public_key) 390static int getcryptconnection_id(uint8_t *public_key)
356{ 391{
357 uint32_t i; 392 uint32_t i;
393
358 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 394 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
359 if (crypto_connections[i].status != CONN_NO_CONNECTION) 395 if (crypto_connections[i].status != CONN_NO_CONNECTION)
360 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) 396 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
361 return i; 397 return i;
362 } 398 }
399
363 return -1; 400 return -1;
364} 401}
365 402
@@ -370,16 +407,21 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
370{ 407{
371 uint32_t i; 408 uint32_t i;
372 int id = getcryptconnection_id(public_key); 409 int id = getcryptconnection_id(public_key);
410
373 if (id != -1) { 411 if (id != -1) {
374 IP_Port c_ip = connection_ip(crypto_connections[id].number); 412 IP_Port c_ip = connection_ip(crypto_connections[id].number);
375 if(c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port) 413
414 if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port)
376 return -1; 415 return -1;
377 } 416 }
417
378 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 418 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
379 if (crypto_connections[i].status == CONN_NO_CONNECTION) { 419 if (crypto_connections[i].status == CONN_NO_CONNECTION) {
380 int id = new_connection(ip_port); 420 int id = new_connection(ip_port);
421
381 if (id == -1) 422 if (id == -1)
382 return -1; 423 return -1;
424
383 crypto_connections[i].number = id; 425 crypto_connections[i].number = id;
384 crypto_connections[i].status = CONN_HANDSHAKE_SENT; 426 crypto_connections[i].status = CONN_HANDSHAKE_SENT;
385 random_nonce(crypto_connections[i].recv_nonce); 427 random_nonce(crypto_connections[i].recv_nonce);
@@ -391,9 +433,11 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
391 increment_nonce(crypto_connections[i].recv_nonce); 433 increment_nonce(crypto_connections[i].recv_nonce);
392 return i; 434 return i;
393 } 435 }
436
394 return -1; /* this should never happen. */ 437 return -1; /* this should never happen. */
395 } 438 }
396 } 439 }
440
397 return -1; 441 return -1;
398} 442}
399 443
@@ -407,6 +451,7 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
407int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) 451int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
408{ 452{
409 uint32_t i; 453 uint32_t i;
454
410 for (i = 0; i < MAX_INCOMING; ++i) { 455 for (i = 0; i < MAX_INCOMING; ++i) {
411 if (incoming_connections[i] != -1) { 456 if (incoming_connections[i] != -1) {
412 if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) { 457 if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) {
@@ -414,9 +459,11 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
414 incoming_connections[i] = -1; 459 incoming_connections[i] = -1;
415 continue; 460 continue;
416 } 461 }
462
417 if (id_packet(incoming_connections[i]) == 2) { 463 if (id_packet(incoming_connections[i]) == 2) {
418 uint8_t temp_data[MAX_DATA_SIZE]; 464 uint8_t temp_data[MAX_DATA_SIZE];
419 uint16_t len = read_packet(incoming_connections[i], temp_data); 465 uint16_t len = read_packet(incoming_connections[i], temp_data);
466
420 if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { 467 if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
421 int connection_id = incoming_connections[i]; 468 int connection_id = incoming_connections[i];
422 incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ 469 incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */
@@ -425,6 +472,7 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
425 } 472 }
426 } 473 }
427 } 474 }
475
428 return -1; 476 return -1;
429} 477}
430 478
@@ -435,13 +483,15 @@ int crypto_kill(int crypt_connection_id)
435{ 483{
436 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 484 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
437 return 1; 485 return 1;
486
438 if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { 487 if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) {
439 crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; 488 crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION;
440 kill_connection(crypto_connections[crypt_connection_id].number); 489 kill_connection(crypto_connections[crypt_connection_id].number);
441 memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection)); 490 memset(&crypto_connections[crypt_connection_id], 0 , sizeof(Crypto_Connection));
442 crypto_connections[crypt_connection_id].number = ~0; 491 crypto_connections[crypt_connection_id].number = ~0;
443 return 0; 492 return 0;
444 } 493 }
494
445 return 1; 495 return 1;
446} 496}
447 497
@@ -451,15 +501,17 @@ int crypto_kill(int crypt_connection_id)
451int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) 501int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
452{ 502{
453 uint32_t i; 503 uint32_t i;
504
454 if (connection_id == -1) 505 if (connection_id == -1)
455 return -1; 506 return -1;
507
456 /* 508 /*
457 if(getcryptconnection_id(public_key) != -1) 509 if(getcryptconnection_id(public_key) != -1)
458 { 510 {
459 return -1; 511 return -1;
460 }*/ 512 }*/
461 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 513 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
462 if(crypto_connections[i].status == CONN_NO_CONNECTION) { 514 if (crypto_connections[i].status == CONN_NO_CONNECTION) {
463 crypto_connections[i].number = connection_id; 515 crypto_connections[i].number = connection_id;
464 crypto_connections[i].status = CONN_NOT_CONFIRMED; 516 crypto_connections[i].status = CONN_NOT_CONFIRMED;
465 random_nonce(crypto_connections[i].recv_nonce); 517 random_nonce(crypto_connections[i].recv_nonce);
@@ -474,17 +526,19 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
474 crypto_connections[i].sessionpublic_key) == 1) { 526 crypto_connections[i].sessionpublic_key) == 1) {
475 increment_nonce(crypto_connections[i].recv_nonce); 527 increment_nonce(crypto_connections[i].recv_nonce);
476 uint32_t zero = 0; 528 uint32_t zero = 0;
477 encrypt_precompute(crypto_connections[i].peersessionpublic_key, 529 encrypt_precompute(crypto_connections[i].peersessionpublic_key,
478 crypto_connections[i].sessionsecret_key, 530 crypto_connections[i].sessionsecret_key,
479 crypto_connections[i].shared_key); 531 crypto_connections[i].shared_key);
480 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ 532 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
481 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); 533 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
482 crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ 534 crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
483 return i; 535 return i;
484 } 536 }
537
485 return -1; /* this should never happen. */ 538 return -1; /* this should never happen. */
486 } 539 }
487 } 540 }
541
488 return -1; 542 return -1;
489} 543}
490 544
@@ -495,6 +549,7 @@ int is_cryptoconnected(int crypt_connection_id)
495{ 549{
496 if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) 550 if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
497 return crypto_connections[crypt_connection_id].status; 551 return crypto_connections[crypt_connection_id].status;
552
498 return CONN_NO_CONNECTION; 553 return CONN_NO_CONNECTION;
499} 554}
500 555
@@ -502,7 +557,7 @@ int is_cryptoconnected(int crypt_connection_id)
502 Only call this function the first time the program starts. */ 557 Only call this function the first time the program starts. */
503void new_keys(void) 558void new_keys(void)
504{ 559{
505 crypto_box_keypair(self_public_key,self_secret_key); 560 crypto_box_keypair(self_public_key, self_secret_key);
506} 561}
507 562
508/* save the public and private keys to the keys array 563/* save the public and private keys to the keys array
@@ -528,12 +583,14 @@ void load_keys(uint8_t *keys)
528static int new_incoming(int id) 583static int new_incoming(int id)
529{ 584{
530 uint32_t i; 585 uint32_t i;
586
531 for (i = 0; i < MAX_INCOMING; ++i) { 587 for (i = 0; i < MAX_INCOMING; ++i) {
532 if (incoming_connections[i] == -1) { 588 if (incoming_connections[i] == -1) {
533 incoming_connections[i] = id; 589 incoming_connections[i] = id;
534 return 0; 590 return 0;
535 } 591 }
536 } 592 }
593
537 return 1; 594 return 1;
538} 595}
539 596
@@ -542,9 +599,11 @@ static int new_incoming(int id)
542static void handle_incomings(void) 599static void handle_incomings(void)
543{ 600{
544 int income; 601 int income;
602
545 while (1) { 603 while (1) {
546 income = incoming_connection(); 604 income = incoming_connection();
547 if(income == -1 || new_incoming(income) ) 605
606 if (income == -1 || new_incoming(income) )
548 break; 607 break;
549 } 608 }
550} 609}
@@ -553,6 +612,7 @@ static void handle_incomings(void)
553static void receive_crypto(void) 612static void receive_crypto(void)
554{ 613{
555 uint32_t i; 614 uint32_t i;
615
556 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 616 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
557 if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { 617 if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) {
558 uint8_t temp_data[MAX_DATA_SIZE]; 618 uint8_t temp_data[MAX_DATA_SIZE];
@@ -560,19 +620,22 @@ static void receive_crypto(void)
560 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 620 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
561 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 621 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
562 uint16_t len; 622 uint16_t len;
623
563 if (id_packet(crypto_connections[i].number) == 1) 624 if (id_packet(crypto_connections[i].number) == 1)
564 /* if the packet is a friend request drop it (because we are already friends) */ 625 /* if the packet is a friend request drop it (because we are already friends) */
565 len = read_packet(crypto_connections[i].number, temp_data); 626 len = read_packet(crypto_connections[i].number, temp_data);
627
566 if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ 628 if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
567 len = read_packet(crypto_connections[i].number, temp_data); 629 len = read_packet(crypto_connections[i].number, temp_data);
630
568 if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { 631 if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
569 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { 632 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
570 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 633 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
571 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 634 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
572 increment_nonce(crypto_connections[i].sent_nonce); 635 increment_nonce(crypto_connections[i].sent_nonce);
573 uint32_t zero = 0; 636 uint32_t zero = 0;
574 encrypt_precompute(crypto_connections[i].peersessionpublic_key, 637 encrypt_precompute(crypto_connections[i].peersessionpublic_key,
575 crypto_connections[i].sessionsecret_key, 638 crypto_connections[i].sessionsecret_key,
576 crypto_connections[i].shared_key); 639 crypto_connections[i].shared_key);
577 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ 640 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
578 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); 641 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
@@ -583,6 +646,7 @@ static void receive_crypto(void)
583 crypto_kill(crypto_connections[i].number); 646 crypto_kill(crypto_connections[i].number);
584 647
585 } 648 }
649
586 if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { 650 if (crypto_connections[i].status == CONN_NOT_CONFIRMED) {
587 if (id_packet(crypto_connections[i].number) == 3) { 651 if (id_packet(crypto_connections[i].number) == 3) {
588 uint8_t temp_data[MAX_DATA_SIZE]; 652 uint8_t temp_data[MAX_DATA_SIZE];
@@ -592,10 +656,11 @@ static void receive_crypto(void)
592 crypto_connections[i].sessionsecret_key, 656 crypto_connections[i].sessionsecret_key,
593 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); 657 crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
594 uint32_t zero = 0; 658 uint32_t zero = 0;
659
595 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { 660 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
596 increment_nonce(crypto_connections[i].recv_nonce); 661 increment_nonce(crypto_connections[i].recv_nonce);
597 encrypt_precompute(crypto_connections[i].peersessionpublic_key, 662 encrypt_precompute(crypto_connections[i].peersessionpublic_key,
598 crypto_connections[i].sessionsecret_key, 663 crypto_connections[i].sessionsecret_key,
599 crypto_connections[i].shared_key); 664 crypto_connections[i].shared_key);
600 crypto_connections[i].status = CONN_ESTABLISHED; 665 crypto_connections[i].status = CONN_ESTABLISHED;
601 666
@@ -603,7 +668,7 @@ static void receive_crypto(void)
603 kill_connection_in(crypto_connections[i].number, 3000000); 668 kill_connection_in(crypto_connections[i].number, 3000000);
604 } else 669 } else
605 crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does 670 crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does
606 } else if(id_packet(crypto_connections[i].number) != -1) 671 } else if (id_packet(crypto_connections[i].number) != -1)
607 /* This should not happen 672 /* This should not happen
608 kill the connection if it does */ 673 kill the connection if it does */
609 crypto_kill(crypto_connections[i].number); 674 crypto_kill(crypto_connections[i].number);
@@ -615,10 +680,11 @@ static void receive_crypto(void)
615 sets all the global connection variables to their default values. */ 680 sets all the global connection variables to their default values. */
616void initNetCrypto(void) 681void initNetCrypto(void)
617{ 682{
618 memset(crypto_connections, 0 ,sizeof(crypto_connections)); 683 memset(crypto_connections, 0 , sizeof(crypto_connections));
619 memset(incoming_connections, -1 ,sizeof(incoming_connections)); 684 memset(incoming_connections, -1 , sizeof(incoming_connections));
620 networking_registerhandler(32, &cryptopacket_handle); 685 networking_registerhandler(32, &cryptopacket_handle);
621 uint32_t i; 686 uint32_t i;
687
622 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) 688 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
623 crypto_connections[i].number = ~0; 689 crypto_connections[i].number = ~0;
624} 690}
@@ -626,6 +692,7 @@ void initNetCrypto(void)
626static void killTimedout(void) 692static void killTimedout(void)
627{ 693{
628 uint32_t i; 694 uint32_t i;
695
629 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 696 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
630 if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4) 697 if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4)
631 crypto_connections[i].status = CONN_TIMED_OUT; 698 crypto_connections[i].status = CONN_TIMED_OUT;
diff --git a/core/net_crypto.h b/core/net_crypto.h
index 570b9373..742d9fdc 100644
--- a/core/net_crypto.h
+++ b/core/net_crypto.h
@@ -38,14 +38,14 @@ extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
38#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 38#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
39 39
40/* returns zero if the buffer contains only zeros */ 40/* returns zero if the buffer contains only zeros */
41uint8_t crypto_iszero(uint8_t* buffer, uint32_t blen); 41uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
42 42
43/* encrypts plain of length length to encrypted of length + 16 using the 43/* encrypts plain of length length to encrypted of length + 16 using the
44 public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce 44 public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
45 return -1 if there was a problem. 45 return -1 if there was a problem.
46 return length of encrypted data if everything was fine. */ 46 return length of encrypted data if everything was fine. */
47int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 47int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
48 uint8_t *plain, uint32_t length, uint8_t *encrypted); 48 uint8_t *plain, uint32_t length, uint8_t *encrypted);
49 49
50 50
51/* decrypts encrypted of length length to plain of length length - 16 using the 51/* decrypts encrypted of length length to plain of length length - 16 using the
@@ -53,15 +53,15 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
53 return -1 if there was a problem(decryption failed) 53 return -1 if there was a problem(decryption failed)
54 return length of plain data if everything was fine. */ 54 return length of plain data if everything was fine. */
55int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 55int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
56 uint8_t *encrypted, uint32_t length, uint8_t *plain); 56 uint8_t *encrypted, uint32_t length, uint8_t *plain);
57 57
58/* Fast encrypt/decrypt operations. Use if this is not a one-time communication. 58/* Fast encrypt/decrypt operations. Use if this is not a one-time communication.
59 encrypt_precompute does the shared-key generation once so it does not have 59 encrypt_precompute does the shared-key generation once so it does not have
60 to be preformed on every encrypt/decrypt. */ 60 to be preformed on every encrypt/decrypt. */
61void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key); 61void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key);
62 62
63/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ 63/* Fast encrypt. Depends on enc_key from encrypt_precompute. */
64int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 64int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
65 uint8_t *plain, uint32_t length, uint8_t *encrypted); 65 uint8_t *plain, uint32_t length, uint8_t *encrypted);
66 66
67/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ 67/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */
@@ -87,10 +87,10 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length);
87 request_id is the id of the request (32 = friend request, 254 = ping request) 87 request_id is the id of the request (32 = friend request, 254 = ping request)
88 returns -1 on failure 88 returns -1 on failure
89 returns the length of the created packet on success */ 89 returns the length of the created packet on success */
90int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); 90int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id);
91 91
92 92
93typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t * source_pubkey, uint8_t *data, uint32_t len); 93typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
94/* Function to call when request beginning with byte is received */ 94/* Function to call when request beginning with byte is received */
95void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); 95void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb);
96 96
@@ -111,12 +111,12 @@ int crypto_kill(int crypt_connection_id);
111 and the session public key for the connection in session_key 111 and the session public key for the connection in session_key
112 to accept it see: accept_crypto_inbound(...) 112 to accept it see: accept_crypto_inbound(...)
113 to refuse it just call kill_connection(...) on the connection id */ 113 to refuse it just call kill_connection(...) on the connection id */
114int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); 114int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
115 115
116/* accept an incoming connection using the parameters provided by crypto_inbound 116/* accept an incoming connection using the parameters provided by crypto_inbound
117 return -1 if not successful 117 return -1 if not successful
118 returns the crypt_connection_id if successful */ 118 returns the crypt_connection_id if successful */
119int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); 119int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
120 120
121/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet 121/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
122 (we have received a handshake but no empty data packet), 3 if the connection is established. 122 (we have received a handshake but no empty data packet), 3 if the connection is established.
@@ -130,11 +130,11 @@ void new_keys(void);
130 130
131/* save the public and private keys to the keys array 131/* save the public and private keys to the keys array
132 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 132 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
133void save_keys(uint8_t * keys); 133void save_keys(uint8_t *keys);
134 134
135/* load the public and private keys from the keys array 135/* load the public and private keys from the keys array
136 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ 136 Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
137void load_keys(uint8_t * keys); 137void load_keys(uint8_t *keys);
138 138
139/* run this to (re)initialize net_crypto 139/* run this to (re)initialize net_crypto
140 sets all the global connection variables to their default values. */ 140 sets all the global connection variables to their default values. */
diff --git a/core/network.c b/core/network.c
index 7e3b344a..1977ce38 100644
--- a/core/network.c
+++ b/core/network.c
@@ -32,14 +32,14 @@ uint64_t current_time(void)
32 FILETIME ft; 32 FILETIME ft;
33 GetSystemTimeAsFileTime(&ft); 33 GetSystemTimeAsFileTime(&ft);
34 time = ft.dwHighDateTime; 34 time = ft.dwHighDateTime;
35 time <<=32; 35 time <<= 32;
36 time |= ft.dwLowDateTime; 36 time |= ft.dwLowDateTime;
37 time -= 116444736000000000UL; 37 time -= 116444736000000000UL;
38 return time/10; 38 return time / 10;
39#else 39#else
40 struct timeval a; 40 struct timeval a;
41 gettimeofday(&a, NULL); 41 gettimeofday(&a, NULL);
42 time = 1000000UL*a.tv_sec + a.tv_usec; 42 time = 1000000UL * a.tv_sec + a.tv_usec;
43 return time; 43 return time;
44#endif 44#endif
45} 45}
@@ -61,17 +61,17 @@ static int sock;
61 61
62/* Basic network functions: 62/* Basic network functions:
63 Function to send packet(data) of length length to ip_port */ 63 Function to send packet(data) of length length to ip_port */
64int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) 64int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length)
65{ 65{
66 ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; 66 ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
67 return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); 67 return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
68} 68}
69 69
70/* Function to receive data, ip and port of sender is put into ip_port 70/* Function to receive data, ip and port of sender is put into ip_port
71 the packet data into data 71 the packet data into data
72 the packet length into length. 72 the packet length into length.
73 dump all empty packets. */ 73 dump all empty packets. */
74static int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) 74static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length)
75{ 75{
76 ADDR addr; 76 ADDR addr;
77#ifdef WIN32 77#ifdef WIN32
@@ -79,8 +79,9 @@ static int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
79#else 79#else
80 uint32_t addrlen = sizeof(addr); 80 uint32_t addrlen = sizeof(addr);
81#endif 81#endif
82 (*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen); 82 (*(int32_t *)length) = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
83 if (*(int32_t*)length <= 0) 83
84 if (*(int32_t *)length <= 0)
84 return -1; /* nothing received or empty packet */ 85 return -1; /* nothing received or empty packet */
85 86
86 ip_port->ip = addr.ip; 87 ip_port->ip = addr.ip;
@@ -100,11 +101,12 @@ void networking_poll()
100 IP_Port ip_port; 101 IP_Port ip_port;
101 uint8_t data[MAX_UDP_PACKET_SIZE]; 102 uint8_t data[MAX_UDP_PACKET_SIZE];
102 uint32_t length; 103 uint32_t length;
103 104
104 while (receivepacket(&ip_port, data, &length) != -1) 105 while (receivepacket(&ip_port, data, &length) != -1) {
105 {
106 if (length < 1) continue; 106 if (length < 1) continue;
107
107 if (!packethandlers[data[0]]) continue; 108 if (!packethandlers[data[0]]) continue;
109
108 packethandlers[data[0]](ip_port, data, length); 110 packethandlers[data[0]](ip_port, data, length);
109 } 111 }
110} 112}
@@ -119,8 +121,10 @@ int init_networking(IP ip, uint16_t port)
119{ 121{
120#ifdef WIN32 122#ifdef WIN32
121 WSADATA wsaData; 123 WSADATA wsaData;
122 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) 124
125 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR)
123 return -1; 126 return -1;
127
124#else 128#else
125 srandom((uint32_t)current_time()); 129 srandom((uint32_t)current_time());
126#endif 130#endif
@@ -131,11 +135,15 @@ int init_networking(IP ip, uint16_t port)
131 135
132 /* Check for socket error */ 136 /* Check for socket error */
133#ifdef WIN32 137#ifdef WIN32
138
134 if (sock == INVALID_SOCKET) /* MSDN recommends this */ 139 if (sock == INVALID_SOCKET) /* MSDN recommends this */
135 return -1; 140 return -1;
141
136#else 142#else
143
137 if (sock < 0) 144 if (sock < 0)
138 return -1; 145 return -1;
146
139#endif 147#endif
140 148
141 /* Functions to increase the size of the send and receive UDP buffers 149 /* Functions to increase the size of the send and receive UDP buffers
@@ -153,7 +161,7 @@ int init_networking(IP ip, uint16_t port)
153 161
154 /* Enable broadcast on socket */ 162 /* Enable broadcast on socket */
155 int broadcast = 1; 163 int broadcast = 1;
156 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)); 164 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
157 165
158 /* Set socket nonblocking */ 166 /* Set socket nonblocking */
159#ifdef WIN32 167#ifdef WIN32
@@ -167,7 +175,7 @@ int init_networking(IP ip, uint16_t port)
167 175
168 /* Bind our socket to port PORT and address 0.0.0.0 */ 176 /* Bind our socket to port PORT and address 0.0.0.0 */
169 ADDR addr = {AF_INET, htons(port), ip}; 177 ADDR addr = {AF_INET, htons(port), ip};
170 bind(sock, (struct sockaddr*)&addr, sizeof(addr)); 178 bind(sock, (struct sockaddr *)&addr, sizeof(addr));
171 179
172 return 0; 180 return 0;
173} 181}
@@ -207,18 +215,18 @@ uint32_t resolve_addr(const char *address)
207 rc = getaddrinfo(address, "echo", &hints, &server); 215 rc = getaddrinfo(address, "echo", &hints, &server);
208 216
209 // Lookup failed. 217 // Lookup failed.
210 if(rc != 0) { 218 if (rc != 0) {
211 return 0; 219 return 0;
212 } 220 }
213 221
214 // IPv4 records only.. 222 // IPv4 records only..
215 if(server->ai_family != AF_INET) { 223 if (server->ai_family != AF_INET) {
216 freeaddrinfo(server); 224 freeaddrinfo(server);
217 return 0; 225 return 0;
218 } 226 }
219
220 227
221 addr = ((struct sockaddr_in*)server->ai_addr)->sin_addr.s_addr; 228
229 addr = ((struct sockaddr_in *)server->ai_addr)->sin_addr.s_addr;
222 230
223 freeaddrinfo(server); 231 freeaddrinfo(server);
224 return addr; 232 return addr;
diff --git a/core/ping.c b/core/ping.c
index ee05d9fa..47d6e163 100644
--- a/core/ping.c
+++ b/core/ping.c
@@ -26,7 +26,7 @@ typedef struct {
26static pinged_t pings[PING_NUM_MAX]; 26static pinged_t pings[PING_NUM_MAX];
27static size_t num_pings; 27static size_t num_pings;
28static size_t pos_pings; 28static size_t pos_pings;
29static clientid_t* self_id = (clientid_t*) &self_public_key; 29static clientid_t *self_id = (clientid_t *) &self_public_key;
30 30
31extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c 31extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
32 32
@@ -48,10 +48,10 @@ static void remove_timeouts() // O(n)
48 size_t new_num = num_pings; 48 size_t new_num = num_pings;
49 49
50 // Loop through buffer, oldest first 50 // Loop through buffer, oldest first
51 for (i=0; i<num_pings; i++) { 51 for (i = 0; i < num_pings; i++) {
52 id = (pos_pings + i) % PING_NUM_MAX; 52 id = (pos_pings + i) % PING_NUM_MAX;
53 53
54 if(is_timeout(pings[id].timestamp)) { 54 if (is_timeout(pings[id].timestamp)) {
55 new_pos++; 55 new_pos++;
56 new_num--; 56 new_num--;
57 } 57 }
@@ -92,12 +92,12 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
92{ 92{
93 if (ipp.ip.i == 0 && ping_id == 0) 93 if (ipp.ip.i == 0 && ping_id == 0)
94 return false; 94 return false;
95 95
96 size_t i, id; 96 size_t i, id;
97 97
98 remove_timeouts(); 98 remove_timeouts();
99 99
100 for (i=0; i<num_pings; i++) { 100 for (i = 0; i < num_pings; i++) {
101 id = (pos_pings + i) % PING_NUM_MAX; 101 id = (pos_pings + i) % PING_NUM_MAX;
102 102
103 // ping_id = 0 means match any id 103 // ping_id = 0 means match any id
@@ -109,7 +109,7 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
109 return false; 109 return false;
110} 110}
111 111
112int send_ping_request(IP_Port ipp, clientid_t* client_id) 112int send_ping_request(IP_Port ipp, clientid_t *client_id)
113{ 113{
114 pingreq_t pk; 114 pingreq_t pk;
115 int rc; 115 int rc;
@@ -123,22 +123,22 @@ int send_ping_request(IP_Port ipp, clientid_t* client_id)
123 123
124 pk.magic = PACKET_PING_REQ; 124 pk.magic = PACKET_PING_REQ;
125 id_cpy(&pk.client_id, self_id); // Our pubkey 125 id_cpy(&pk.client_id, self_id); // Our pubkey
126 random_nonce((uint8_t*) &pk.nonce); // Generate random nonce 126 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
127 127
128 // Encrypt ping_id using recipient privkey 128 // Encrypt ping_id using recipient privkey
129 rc = encrypt_data((uint8_t*) client_id, 129 rc = encrypt_data((uint8_t *) client_id,
130 self_secret_key, 130 self_secret_key,
131 (uint8_t*) &pk.nonce, 131 (uint8_t *) &pk.nonce,
132 (uint8_t*) &ping_id, sizeof(ping_id), 132 (uint8_t *) &ping_id, sizeof(ping_id),
133 (uint8_t*) &pk.ping_id); 133 (uint8_t *) &pk.ping_id);
134 134
135 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 135 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
136 return 1; 136 return 1;
137 137
138 return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); 138 return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk));
139} 139}
140 140
141int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) 141int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
142{ 142{
143 pingres_t pk; 143 pingres_t pk;
144 int rc; 144 int rc;
@@ -148,24 +148,24 @@ int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id)
148 148
149 pk.magic = PACKET_PING_RES; 149 pk.magic = PACKET_PING_RES;
150 id_cpy(&pk.client_id, self_id); // Our pubkey 150 id_cpy(&pk.client_id, self_id); // Our pubkey
151 random_nonce((uint8_t*) &pk.nonce); // Generate random nonce 151 random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
152 152
153 // Encrypt ping_id using recipient privkey 153 // Encrypt ping_id using recipient privkey
154 rc = encrypt_data((uint8_t*) client_id, 154 rc = encrypt_data((uint8_t *) client_id,
155 self_secret_key, 155 self_secret_key,
156 (uint8_t*) &pk.nonce, 156 (uint8_t *) &pk.nonce,
157 (uint8_t*) &ping_id, sizeof(ping_id), 157 (uint8_t *) &ping_id, sizeof(ping_id),
158 (uint8_t*) &pk.ping_id); 158 (uint8_t *) &pk.ping_id);
159 159
160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
161 return 1; 161 return 1;
162 162
163 return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); 163 return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk));
164} 164}
165 165
166int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length) 166int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length)
167{ 167{
168 pingreq_t* p = (pingreq_t*) packet; 168 pingreq_t *p = (pingreq_t *) packet;
169 int rc; 169 int rc;
170 uint64_t ping_id; 170 uint64_t ping_id;
171 171
@@ -173,26 +173,26 @@ int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length)
173 return 1; 173 return 1;
174 174
175 // Decrypt ping_id 175 // Decrypt ping_id
176 rc = decrypt_data((uint8_t*) &p->client_id, 176 rc = decrypt_data((uint8_t *) &p->client_id,
177 self_secret_key, 177 self_secret_key,
178 (uint8_t*) &p->nonce, 178 (uint8_t *) &p->nonce,
179 (uint8_t*) &p->ping_id, 179 (uint8_t *) &p->ping_id,
180 sizeof(ping_id) + ENCRYPTION_PADDING, 180 sizeof(ping_id) + ENCRYPTION_PADDING,
181 (uint8_t*) &ping_id); 181 (uint8_t *) &ping_id);
182 182
183 if (rc != sizeof(ping_id)) 183 if (rc != sizeof(ping_id))
184 return 1; 184 return 1;
185 185
186 // Send response 186 // Send response
187 send_ping_response(source, &p->client_id, ping_id); 187 send_ping_response(source, &p->client_id, ping_id);
188 add_toping((uint8_t*) &p->client_id, source); 188 add_toping((uint8_t *) &p->client_id, source);
189 189
190 return 0; 190 return 0;
191} 191}
192 192
193int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length) 193int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length)
194{ 194{
195 pingres_t* p = (pingres_t*) packet; 195 pingres_t *p = (pingres_t *) packet;
196 int rc; 196 int rc;
197 uint64_t ping_id; 197 uint64_t ping_id;
198 198
@@ -200,21 +200,21 @@ int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length)
200 return 1; 200 return 1;
201 201
202 // Decrypt ping_id 202 // Decrypt ping_id
203 rc = decrypt_data((uint8_t*) &p->client_id, 203 rc = decrypt_data((uint8_t *) &p->client_id,
204 self_secret_key, 204 self_secret_key,
205 (uint8_t*) &p->nonce, 205 (uint8_t *) &p->nonce,
206 (uint8_t*) &p->ping_id, 206 (uint8_t *) &p->ping_id,
207 sizeof(ping_id) + ENCRYPTION_PADDING, 207 sizeof(ping_id) + ENCRYPTION_PADDING,
208 (uint8_t*) &ping_id); 208 (uint8_t *) &ping_id);
209 209
210 if (rc != sizeof(ping_id)) 210 if (rc != sizeof(ping_id))
211 return 1; 211 return 1;
212 212
213 // Make sure ping_id is correct 213 // Make sure ping_id is correct
214 if(!is_pinging(source, ping_id)) 214 if (!is_pinging(source, ping_id))
215 return 1; 215 return 1;
216 216
217 // Associate source ip with client_id 217 // Associate source ip with client_id
218 addto_lists(source, (uint8_t*) &p->client_id); 218 addto_lists(source, (uint8_t *) &p->client_id);
219 return 0; 219 return 0;
220} 220}
diff --git a/core/ping.h b/core/ping.h
index 1ccfabac..0c44874b 100644
--- a/core/ping.h
+++ b/core/ping.h
@@ -10,7 +10,7 @@
10void init_ping(); 10void init_ping();
11uint64_t add_ping(IP_Port ipp); 11uint64_t add_ping(IP_Port ipp);
12bool is_pinging(IP_Port ipp, uint64_t ping_id); 12bool is_pinging(IP_Port ipp, uint64_t ping_id);
13int send_ping_request(IP_Port ipp, clientid_t* client_id); 13int send_ping_request(IP_Port ipp, clientid_t *client_id);
14int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id); 14int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id);
15int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length); 15int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length);
16int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length); 16int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length);
diff --git a/core/timer.c b/core/timer.c
index 06e25693..29190921 100644
--- a/core/timer.c
+++ b/core/timer.c
@@ -4,7 +4,7 @@
4#include "timer.h" 4#include "timer.h"
5#include "network.h" 5#include "network.h"
6 6
7/* 7/*
8A nested linked list increases efficiency of insertions. 8A nested linked list increases efficiency of insertions.
9Depending on the number of timers we have, we might need to have nested linked lists 9Depending on the number of timers we have, we might need to have nested linked lists
10in order to improve insertion efficiency. 10in order to improve insertion efficiency.
@@ -46,35 +46,37 @@ enum timer_state {
46 STATE_CALLBACK 46 STATE_CALLBACK
47}; 47};
48 48
49struct timer 49struct timer {
50{
51 enum timer_state state; 50 enum timer_state state;
52 timer* _prev; 51 timer *_prev;
53 timer* _next; 52 timer *_next;
54 timer_callback cb; 53 timer_callback cb;
55 void* userdata; 54 void *userdata;
56 uint64_t deadline; 55 uint64_t deadline;
57}; 56};
58 57
59static timer* timer_main_queue; 58static timer *timer_main_queue;
60static timer* timer_us_queue; /* hi-speed queue */ 59static timer *timer_us_queue; /* hi-speed queue */
61 60
62inline static void timer_dequeue(timer* t, timer** queue) 61inline static void timer_dequeue(timer *t, timer **queue)
63{ 62{
64 if (t->state == STATE_INACTIVE) return; /* not in a queue */ 63 if (t->state == STATE_INACTIVE) return; /* not in a queue */
65 64
66 if (t->_prev) { 65 if (t->_prev) {
67 t->_prev->_next = t->_next; 66 t->_prev->_next = t->_next;
68 } else { 67 } else {
69 *queue = t->_next; 68 *queue = t->_next;
70 } 69 }
70
71 if (t->_next) t->_next->_prev = t->_prev; 71 if (t->_next) t->_next->_prev = t->_prev;
72
72 t->state = STATE_INACTIVE; 73 t->state = STATE_INACTIVE;
73} 74}
74 75
75static void timer_enqueue(timer* t, timer** queue, timer* prev) 76static void timer_enqueue(timer *t, timer **queue, timer *prev)
76{ 77{
77 t->state = STATE_ACTIVE; 78 t->state = STATE_ACTIVE;
79
78 while (true) { 80 while (true) {
79 if (!*queue) { 81 if (!*queue) {
80 t->_next = 0; 82 t->_next = 0;
@@ -104,22 +106,24 @@ void timer_init()
104} 106}
105 107
106/* Do not depend on fields being zeroed */ 108/* Do not depend on fields being zeroed */
107static timer* timer_pool; /* timer_pool is SINGLY LINKED!! */ 109static timer *timer_pool; /* timer_pool is SINGLY LINKED!! */
108 110
109timer* new_timer(void) 111timer *new_timer(void)
110{ 112{
111 timer* ret; 113 timer *ret;
114
112 if (timer_pool) { 115 if (timer_pool) {
113 ret = timer_pool; 116 ret = timer_pool;
114 timer_pool = timer_pool->_next; 117 timer_pool = timer_pool->_next;
115 } else { 118 } else {
116 ret = calloc(1, sizeof(struct timer)); 119 ret = calloc(1, sizeof(struct timer));
117 } 120 }
121
118 ret->state = STATE_INACTIVE; 122 ret->state = STATE_INACTIVE;
119 return ret; 123 return ret;
120} 124}
121 125
122void delete_timer(timer* t) 126void delete_timer(timer *t)
123{ 127{
124 timer_dequeue(t, &timer_main_queue); 128 timer_dequeue(t, &timer_main_queue);
125 t->_next = timer_pool; 129 t->_next = timer_pool;
@@ -127,93 +131,99 @@ void delete_timer(timer* t)
127 timer_pool = t; 131 timer_pool = t;
128} 132}
129 133
130void timer_setup(timer* t, timer_callback cb, void* userarg) 134void timer_setup(timer *t, timer_callback cb, void *userarg)
131{ 135{
132 t->cb = cb; 136 t->cb = cb;
133 t->userdata = userarg; 137 t->userdata = userarg;
134} 138}
135 139
136void* timer_get_userdata(timer* t) 140void *timer_get_userdata(timer *t)
137{ 141{
138 return t->userdata; 142 return t->userdata;
139} 143}
140 144
141static void timer_delay_us(timer* t, int us) 145static void timer_delay_us(timer *t, int us)
142{ 146{
143 t->deadline += us; 147 t->deadline += us;
144 timer** queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue; 148 timer **queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue;
145 timer_dequeue(t, &timer_main_queue); 149 timer_dequeue(t, &timer_main_queue);
146 timer_enqueue(t, queue, t->_prev); 150 timer_enqueue(t, queue, t->_prev);
147} 151}
148 152
149/* Starts the timer so that it's called in sec seconds in the future. 153/* Starts the timer so that it's called in sec seconds in the future.
150 * A non-positive value of sec results in the callback being called immediately. 154 * A non-positive value of sec results in the callback being called immediately.
151 * This function may be called again after a timer has been started to adjust 155 * This function may be called again after a timer has been started to adjust
152 * the expiry time. */ 156 * the expiry time. */
153void timer_start(timer* t, int sec) 157void timer_start(timer *t, int sec)
154{ 158{
155 uint64_t newdeadline = current_time() + sec * US_PER_SECOND; 159 uint64_t newdeadline = current_time() + sec * US_PER_SECOND;
156 if (timer_is_active(t)){ 160
161 if (timer_is_active(t)) {
157 if (t->deadline < newdeadline) { 162 if (t->deadline < newdeadline) {
158 timer_delay_us(t, newdeadline - t->deadline); 163 timer_delay_us(t, newdeadline - t->deadline);
159 return; 164 return;
160 } 165 }
166
161 timer_dequeue(t, &timer_main_queue); 167 timer_dequeue(t, &timer_main_queue);
162 } 168 }
169
163 t->deadline = newdeadline; 170 t->deadline = newdeadline;
164 timer_enqueue(t, &timer_main_queue, 0); 171 timer_enqueue(t, &timer_main_queue, 0);
165} 172}
166 173
167/* Stops the timer. Returns -1 if the timer was not active. */ 174/* Stops the timer. Returns -1 if the timer was not active. */
168int timer_stop(timer* t) 175int timer_stop(timer *t)
169{ 176{
170 int ret = timer_is_active(t) ? -1 : 0; 177 int ret = timer_is_active(t) ? -1 : 0;
171 timer_dequeue(t, &timer_main_queue); 178 timer_dequeue(t, &timer_main_queue);
172 return ret; 179 return ret;
173} 180}
174 181
175/* Adds additionalsec seconds to the timer. 182/* Adds additionalsec seconds to the timer.
176 * Returns -1 and does nothing if the timer was not active. */ 183 * Returns -1 and does nothing if the timer was not active. */
177int timer_delay(timer* t, int additonalsec) 184int timer_delay(timer *t, int additonalsec)
178{ 185{
179 if (!timer_is_active(t)) return -1; 186 if (!timer_is_active(t)) return -1;
187
180 timer_delay_us(t, additonalsec * US_PER_SECOND); 188 timer_delay_us(t, additonalsec * US_PER_SECOND);
181 return 0; 189 return 0;
182} 190}
183 191
184static uint64_t timer_diff(timer* t, uint64_t time) 192static uint64_t timer_diff(timer *t, uint64_t time)
185{ 193{
186 if (t->deadline <= time) return 0; 194 if (t->deadline <= time) return 0;
195
187 return time - t->deadline; 196 return time - t->deadline;
188} 197}
189 198
190/* Returns the time remaining on a timer in seconds. 199/* Returns the time remaining on a timer in seconds.
191 * Returns -1 if the timer is not active. 200 * Returns -1 if the timer is not active.
192 * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */ 201 * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */
193int timer_time_remaining(timer* t) 202int timer_time_remaining(timer *t)
194{ 203{
195 if (!timer_is_active(t)) return -1; 204 if (!timer_is_active(t)) return -1;
205
196 return timer_diff(t, current_time()) / US_PER_SECOND; 206 return timer_diff(t, current_time()) / US_PER_SECOND;
197} 207}
198 208
199bool timer_is_active(timer* t) 209bool timer_is_active(timer *t)
200{ 210{
201 return t->state != STATE_INACTIVE; 211 return t->state != STATE_INACTIVE;
202} 212}
203 213
204/* Single-use timer. 214/* Single-use timer.
205 * Creates a new timer, preforms setup and starts it. */ 215 * Creates a new timer, preforms setup and starts it. */
206void timer_single(timer_callback cb, void* userarg, int sec) 216void timer_single(timer_callback cb, void *userarg, int sec)
207{ 217{
208 timer* t = new_timer(); 218 timer *t = new_timer();
209 timer_setup(t, cb, userarg); 219 timer_setup(t, cb, userarg);
210 timer_start(t, sec); 220 timer_start(t, sec);
211} 221}
212 222
213/* Single-use microsecond timer. */ 223/* Single-use microsecond timer. */
214void timer_us(timer_callback cb, void* userarg, int us) 224void timer_us(timer_callback cb, void *userarg, int us)
215{ 225{
216 timer* t = new_timer(); 226 timer *t = new_timer();
217 timer_setup(t, cb, userarg); 227 timer_setup(t, cb, userarg);
218 t->deadline = current_time() + us; 228 t->deadline = current_time() + us;
219 t->state = STATE_ACTIVE; 229 t->state = STATE_ACTIVE;
@@ -228,26 +238,30 @@ void timer_poll(void)
228 /* Handle millisecond timers */ 238 /* Handle millisecond timers */
229 while (timer_us_queue) { 239 while (timer_us_queue) {
230 if (timer_diff(timer_us_queue, time) != 0) break; 240 if (timer_diff(timer_us_queue, time) != 0) break;
231 timer* t = timer_us_queue; 241
242 timer *t = timer_us_queue;
232 timer_dequeue(t, &timer_us_queue); 243 timer_dequeue(t, &timer_us_queue);
233 t->cb(0, t->userdata); 244 t->cb(0, t->userdata);
234 delete_timer(t); 245 delete_timer(t);
235 } 246 }
236 247
237 if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) { 248 if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) {
238 /* time moving backwards is just a sanity check */ 249 /* time moving backwards is just a sanity check */
239 prevtime = time; 250 prevtime = time;
240 251
241 while (timer_main_queue) { 252 while (timer_main_queue) {
242 if (timer_diff(timer_main_queue, time) != 0) break; 253 if (timer_diff(timer_main_queue, time) != 0) break;
243 timer* t = timer_main_queue; 254
255 timer *t = timer_main_queue;
244 t->state = STATE_CALLBACK; 256 t->state = STATE_CALLBACK;
245 int rv = t->cb(t, t->userdata); 257 int rv = t->cb(t, t->userdata);
258
246 if (rv != 0) { 259 if (rv != 0) {
247 timer_dequeue(t, &timer_main_queue); 260 timer_dequeue(t, &timer_main_queue);
248 delete_timer(t); 261 delete_timer(t);
249 continue; 262 continue;
250 } 263 }
264
251 if (t->state != STATE_ACTIVE) { 265 if (t->state != STATE_ACTIVE) {
252 timer_dequeue(t, &timer_main_queue); 266 timer_dequeue(t, &timer_main_queue);
253 } 267 }
@@ -257,19 +271,20 @@ void timer_poll(void)
257 271
258/*** Internal Testing ***/ 272/*** Internal Testing ***/
259 273
260/* I do not want to expose internals to the public, 274/* I do not want to expose internals to the public,
261 * which is why internals testing is done this way. */ 275 * which is why internals testing is done this way. */
262void timer_internal_tests(bool (*assert)(bool, char*)) 276void timer_internal_tests(bool (*assert)(bool, char *))
263{ 277{
264 278
265} 279}
266 280
267void timer_debug_print() 281void timer_debug_print()
268{ 282{
269 timer* t = timer_main_queue; 283 timer *t = timer_main_queue;
270 printf("Queue:\n"); 284 printf("Queue:\n");
285
271 while (t) { 286 while (t) {
272 printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline/US_PER_SECOND, (char*)t->userdata); 287 printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline / US_PER_SECOND, (char *)t->userdata);
273 t = t->_next; 288 t = t->_next;
274 } 289 }
275} 290}
diff --git a/core/timer.h b/core/timer.h
index 8844a1dd..15491326 100644
--- a/core/timer.h
+++ b/core/timer.h
@@ -44,7 +44,7 @@ typedef struct timer timer;
44 * You may call any of the timer functions within the callback: 44 * You may call any of the timer functions within the callback:
45 * For example, you may call timer_start to restart the timer from 45 * For example, you may call timer_start to restart the timer from
46 * within a callback. */ 46 * within a callback. */
47typedef int (*timer_callback)(timer* t, void* userarg); 47typedef int (*timer_callback)(timer *t, void *userarg);
48 48
49/* Initisalise timer subsystem */ 49/* Initisalise timer subsystem */
50void timer_init(void); 50void timer_init(void);
@@ -53,52 +53,52 @@ void timer_init(void);
53void timer_poll(void); 53void timer_poll(void);
54 54
55/* Creates a new timer. Does not enqueue/start it. */ 55/* Creates a new timer. Does not enqueue/start it. */
56timer* new_timer(void); 56timer *new_timer(void);
57 57
58/* Destroys a timer instance. */ 58/* Destroys a timer instance. */
59void delete_timer(timer* t); 59void delete_timer(timer *t);
60 60
61/* Sets up the timer callback. */ 61/* Sets up the timer callback. */
62void timer_setup(timer* t, timer_callback cb, void* userarg); 62void timer_setup(timer *t, timer_callback cb, void *userarg);
63 63
64/* Accessor Function. */ 64/* Accessor Function. */
65void* timer_get_userdata(timer* t); 65void *timer_get_userdata(timer *t);
66 66
67/* Starts the timer so that it's called in sec seconds in the future from now. 67/* Starts the timer so that it's called in sec seconds in the future from now.
68 * A non-positive value of sec results in the callback being called immediately. 68 * A non-positive value of sec results in the callback being called immediately.
69 * This function may be called again after a timer has been started to adjust 69 * This function may be called again after a timer has been started to adjust
70 * the expiry time. */ 70 * the expiry time. */
71void timer_start(timer* t, int sec); 71void timer_start(timer *t, int sec);
72 72
73/* Stops the timer. Returns -1 if the timer was not active. */ 73/* Stops the timer. Returns -1 if the timer was not active. */
74int timer_stop(timer* t); 74int timer_stop(timer *t);
75 75
76/* Adds additionalsec seconds to the timer. 76/* Adds additionalsec seconds to the timer.
77 * Returns -1 and does nothing if the timer was not active. */ 77 * Returns -1 and does nothing if the timer was not active. */
78int timer_delay(timer* t, int additonalsec); 78int timer_delay(timer *t, int additonalsec);
79 79
80/* Returns the time remaining on a timer in seconds. 80/* Returns the time remaining on a timer in seconds.
81 * Returns -1 if the timer is not active. 81 * Returns -1 if the timer is not active.
82 * Returns 0 if the timer has expired and the callback hasn't been called yet. */ 82 * Returns 0 if the timer has expired and the callback hasn't been called yet. */
83int timer_time_remaining(timer* t); 83int timer_time_remaining(timer *t);
84 84
85/* Determines if timer is active. Returns TRUE if it is active */ 85/* Determines if timer is active. Returns TRUE if it is active */
86bool timer_is_active(timer* t); 86bool timer_is_active(timer *t);
87 87
88/* Single-use timer. 88/* Single-use timer.
89 * Creates a new timer, preforms setup and starts it. 89 * Creates a new timer, preforms setup and starts it.
90 * Callback must return a non-zero value to prevent memory leak. */ 90 * Callback must return a non-zero value to prevent memory leak. */
91void timer_single(timer_callback cb, void* userarg, int sec); 91void timer_single(timer_callback cb, void *userarg, int sec);
92 92
93/* Single-use microsecond timer. 93/* Single-use microsecond timer.
94 * Creates a new timer, preforms setup and starts it. 94 * Creates a new timer, preforms setup and starts it.
95 * Please do not use this when accuracy is not absolutely required. 95 * Please do not use this when accuracy is not absolutely required.
96 * Use when one needs to time a period < 1 s. 96 * Use when one needs to time a period < 1 s.
97 * Use the more coarse timers above for periods > 5 s. 97 * Use the more coarse timers above for periods > 5 s.
98 * WARNING: the callback will be called with NULL as the first argument */ 98 * WARNING: the callback will be called with NULL as the first argument */
99void timer_us(timer_callback cb, void* userarg, int us); 99void timer_us(timer_callback cb, void *userarg, int us);
100 100
101/* Internal Testing */ 101/* Internal Testing */
102void timer_internal_tests(bool(*)(bool, char*)); 102void timer_internal_tests(bool( *)(bool, char *));
103 103
104#endif 104#endif
diff --git a/core/util.c b/core/util.c
index d201bcb4..6f346db1 100644
--- a/core/util.c
+++ b/core/util.c
@@ -34,12 +34,12 @@ bool ipp_eq(IP_Port a, IP_Port b)
34 return (a.ip.i == b.ip.i) && (a.port == b.port); 34 return (a.ip.i == b.ip.i) && (a.port == b.port);
35} 35}
36 36
37bool id_eq(clientid_t* dest, clientid_t* src) 37bool id_eq(clientid_t *dest, clientid_t *src)
38{ 38{
39 return memcmp(dest, src, sizeof(clientid_t)) == 0; 39 return memcmp(dest, src, sizeof(clientid_t)) == 0;
40} 40}
41 41
42void id_cpy(clientid_t* dest, clientid_t* src) 42void id_cpy(clientid_t *dest, clientid_t *src)
43{ 43{
44 memcpy(dest, src, sizeof(clientid_t)); 44 memcpy(dest, src, sizeof(clientid_t));
45} 45}
diff --git a/core/util.h b/core/util.h
index b85fbd39..5209c2ca 100644
--- a/core/util.h
+++ b/core/util.h
@@ -8,5 +8,5 @@
8uint64_t now(); 8uint64_t now();
9uint64_t random_64b(); 9uint64_t random_64b();
10bool ipp_eq(IP_Port a, IP_Port b); 10bool ipp_eq(IP_Port a, IP_Port b);
11bool id_eq(clientid_t* dest, clientid_t* src); 11bool id_eq(clientid_t *dest, clientid_t *src);
12void id_cpy(clientid_t* dest, clientid_t* src); 12void id_cpy(clientid_t *dest, clientid_t *src);