diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-03 20:12:09 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-03 20:12:09 +0000 |
commit | 5baf12a487a19225962d15e28ba52f10d1d1f7d4 (patch) | |
tree | 59b511a23d38b57ef880e7171a46df6e90562893 /src/hello/hello.c | |
parent | f7f85255bce69204e68b5fca21afae8ea4d6d352 (diff) | |
download | gnunet-5baf12a487a19225962d15e28ba52f10d1d1f7d4.tar.gz gnunet-5baf12a487a19225962d15e28ba52f10d1d1f7d4.zip |
improving comments and coding style for libgnunethello library
Diffstat (limited to 'src/hello/hello.c')
-rw-r--r-- | src/hello/hello.c | 334 |
1 files changed, 209 insertions, 125 deletions
diff --git a/src/hello/hello.c b/src/hello/hello.c index c8c71945d..1013fd5a3 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009 Christian Grothoff (and other contributing authors) | 3 | Copyright (C) 2009, 2015 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -108,7 +108,6 @@ struct GNUNET_HELLO_ParseUriContext | |||
108 | */ | 108 | */ |
109 | unsigned int counter_added; | 109 | unsigned int counter_added; |
110 | 110 | ||
111 | |||
112 | /** | 111 | /** |
113 | * Function for finding transport plugins by name. | 112 | * Function for finding transport plugins by name. |
114 | */ | 113 | */ |
@@ -120,13 +119,13 @@ struct GNUNET_HELLO_ParseUriContext | |||
120 | * Return HELLO type | 119 | * Return HELLO type |
121 | * | 120 | * |
122 | * @param h HELLO Message to test | 121 | * @param h HELLO Message to test |
123 | * @return #GNUNET_YES or #GNUNET_NO | 122 | * @return #GNUNET_YES for friend-only or #GNUNET_NO otherwise |
124 | */ | 123 | */ |
125 | int | 124 | int |
126 | GNUNET_HELLO_is_friend_only (const struct GNUNET_HELLO_Message *h) | 125 | GNUNET_HELLO_is_friend_only (const struct GNUNET_HELLO_Message *h) |
127 | { | 126 | { |
128 | if (GNUNET_YES == ntohl(h->friend_only)) | 127 | if (GNUNET_YES == ntohl(h->friend_only)) |
129 | return GNUNET_YES; | 128 | return GNUNET_YES; |
130 | return GNUNET_NO; | 129 | return GNUNET_NO; |
131 | } | 130 | } |
132 | 131 | ||
@@ -173,9 +172,9 @@ GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address, | |||
173 | * Get the size of an address entry in a HELLO message. | 172 | * Get the size of an address entry in a HELLO message. |
174 | * | 173 | * |
175 | * @param buf pointer to the start of the address entry | 174 | * @param buf pointer to the start of the address entry |
176 | * @param max maximum size of the entry (end of buf) | 175 | * @param max maximum size of the entry (end of @a buf) |
177 | * @param ralen set to the address length | 176 | * @param ralen set to the address length |
178 | * @return size of the entry, or 0 if max is not large enough | 177 | * @return size of the entry, or 0 if @a max is not large enough |
179 | */ | 178 | */ |
180 | static size_t | 179 | static size_t |
181 | get_hello_address_size (const char *buf, | 180 | get_hello_address_size (const char *buf, |
@@ -228,10 +227,17 @@ get_hello_address_size (const char *buf, | |||
228 | * expiration time and an iterator that spews the | 227 | * expiration time and an iterator that spews the |
229 | * transport addresses. | 228 | * transport addresses. |
230 | * | 229 | * |
230 | * If friend only is set to #GNUNET_YES we create a FRIEND_HELLO which | ||
231 | * will not be gossiped to other peers. | ||
232 | * | ||
233 | * @param public_key public key to include in the HELLO | ||
234 | * @param addrgen callback to invoke to get addresses | ||
235 | * @param addrgen_cls closure for @a addrgen | ||
236 | * @param friend_only should the returned HELLO be only visible to friends? | ||
231 | * @return the hello message | 237 | * @return the hello message |
232 | */ | 238 | */ |
233 | struct GNUNET_HELLO_Message * | 239 | struct GNUNET_HELLO_Message * |
234 | GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey, | 240 | GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, |
235 | GNUNET_HELLO_GenerateAddressListCallback addrgen, | 241 | GNUNET_HELLO_GenerateAddressListCallback addrgen, |
236 | void *addrgen_cls, | 242 | void *addrgen_cls, |
237 | int friend_only) | 243 | int friend_only) |
@@ -243,14 +249,16 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey, | |||
243 | size_t ret; | 249 | size_t ret; |
244 | struct GNUNET_HELLO_Message *hello; | 250 | struct GNUNET_HELLO_Message *hello; |
245 | 251 | ||
246 | GNUNET_assert (NULL != publicKey); | 252 | GNUNET_assert (NULL != public_key); |
247 | GNUNET_assert ((GNUNET_YES == friend_only) || (GNUNET_NO == friend_only)); | 253 | GNUNET_assert ( (GNUNET_YES == friend_only) || |
248 | 254 | (GNUNET_NO == friend_only) ); | |
249 | max = sizeof (buffer); | 255 | max = sizeof (buffer); |
250 | used = 0; | 256 | used = 0; |
251 | if (addrgen != NULL) | 257 | if (NULL != addrgen) |
252 | { | 258 | { |
253 | while (GNUNET_SYSERR != (ret = addrgen (addrgen_cls, max, &buffer[used]))) | 259 | while (GNUNET_SYSERR != (ret = addrgen (addrgen_cls, |
260 | max, | ||
261 | &buffer[used]))) | ||
254 | { | 262 | { |
255 | max -= ret; | 263 | max -= ret; |
256 | used += ret; | 264 | used += ret; |
@@ -260,10 +268,10 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey, | |||
260 | hello->header.type = htons (GNUNET_MESSAGE_TYPE_HELLO); | 268 | hello->header.type = htons (GNUNET_MESSAGE_TYPE_HELLO); |
261 | hello->header.size = htons (sizeof (struct GNUNET_HELLO_Message) + used); | 269 | hello->header.size = htons (sizeof (struct GNUNET_HELLO_Message) + used); |
262 | hello->friend_only = htonl (friend_only); | 270 | hello->friend_only = htonl (friend_only); |
263 | 271 | hello->publicKey = *public_key; | |
264 | memcpy (&hello->publicKey, publicKey, | 272 | memcpy (&hello[1], |
265 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | 273 | buffer, |
266 | memcpy (&hello[1], buffer, used); | 274 | used); |
267 | return hello; | 275 | return hello; |
268 | } | 276 | } |
269 | 277 | ||
@@ -304,22 +312,27 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg, | |||
304 | if (return_modified) | 312 | if (return_modified) |
305 | { | 313 | { |
306 | ret = GNUNET_malloc (msize); | 314 | ret = GNUNET_malloc (msize); |
307 | memcpy (ret, msg, msize); | 315 | memcpy (ret, |
316 | msg, | ||
317 | msize); | ||
308 | } | 318 | } |
309 | inptr = (const char *) &msg[1]; | 319 | inptr = (const char *) &msg[1]; |
310 | insize = msize - sizeof (struct GNUNET_HELLO_Message); | 320 | insize = msize - sizeof (struct GNUNET_HELLO_Message); |
311 | wpos = 0; | 321 | wpos = 0; |
312 | woff = (ret != NULL) ? (char *) &ret[1] : NULL; | 322 | woff = (NULL != ret) ? (char *) &ret[1] : NULL; |
313 | address.peer.public_key = msg->publicKey; | 323 | address.peer.public_key = msg->publicKey; |
314 | while (insize > 0) | 324 | while (insize > 0) |
315 | { | 325 | { |
316 | esize = get_hello_address_size (inptr, insize, &alen); | 326 | esize = get_hello_address_size (inptr, |
327 | insize, | ||
328 | &alen); | ||
317 | if (0 == esize) | 329 | if (0 == esize) |
318 | { | 330 | { |
319 | GNUNET_break (0); | 331 | GNUNET_break (0); |
320 | GNUNET_free_non_null (ret); | 332 | GNUNET_free_non_null (ret); |
321 | return NULL; | 333 | return NULL; |
322 | } | 334 | } |
335 | /* need memcpy() due to possibility of misalignment */ | ||
323 | memcpy (&expire, | 336 | memcpy (&expire, |
324 | &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)], | 337 | &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)], |
325 | sizeof (struct GNUNET_TIME_AbsoluteNBO)); | 338 | sizeof (struct GNUNET_TIME_AbsoluteNBO)); |
@@ -327,23 +340,25 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg, | |||
327 | address.address_length = alen; | 340 | address.address_length = alen; |
328 | address.transport_name = inptr; | 341 | address.transport_name = inptr; |
329 | address.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE; | 342 | address.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE; |
330 | iret = it (it_cls, &address, GNUNET_TIME_absolute_ntoh (expire)); | 343 | iret = it (it_cls, |
331 | if (iret == GNUNET_SYSERR) | 344 | &address, |
332 | { | 345 | GNUNET_TIME_absolute_ntoh (expire)); |
333 | if (ret != NULL) | 346 | if (GNUNET_SYSERR == iret) |
334 | ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos); | 347 | break; |
335 | return ret; | 348 | if ( (GNUNET_OK == iret) && |
336 | } | 349 | (NULL != ret) ) |
337 | if ((iret == GNUNET_OK) && (ret != NULL)) | ||
338 | { | 350 | { |
339 | memcpy (woff, inptr, esize); | 351 | /* copy address over */ |
352 | memcpy (woff, | ||
353 | inptr, | ||
354 | esize); | ||
340 | woff += esize; | 355 | woff += esize; |
341 | wpos += esize; | 356 | wpos += esize; |
342 | } | 357 | } |
343 | insize -= esize; | 358 | insize -= esize; |
344 | inptr += esize; | 359 | inptr += esize; |
345 | } | 360 | } |
346 | if (ret != NULL) | 361 | if (NULL != ret) |
347 | ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos); | 362 | ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos); |
348 | return ret; | 363 | return ret; |
349 | } | 364 | } |
@@ -386,53 +401,56 @@ get_match_exp (void *cls, | |||
386 | { | 401 | { |
387 | struct ExpireContext *ec = cls; | 402 | struct ExpireContext *ec = cls; |
388 | 403 | ||
389 | if (0 == GNUNET_HELLO_address_cmp (address, ec->address)) | 404 | if (0 != GNUNET_HELLO_address_cmp (address, |
390 | { | 405 | ec->address)) |
391 | ec->found = GNUNET_YES; | 406 | return GNUNET_OK; |
392 | ec->expiration = expiration; | 407 | ec->found = GNUNET_YES; |
393 | return GNUNET_SYSERR; /* done here */ | 408 | ec->expiration = expiration; |
394 | } | 409 | return GNUNET_SYSERR; /* done here */ |
395 | return GNUNET_OK; | ||
396 | } | 410 | } |
397 | 411 | ||
398 | 412 | ||
399 | /** | 413 | /** |
400 | * | 414 | * Context for a #GNUNET_HELLO_Merge operation. |
401 | */ | 415 | */ |
402 | struct MergeContext | 416 | struct MergeContext |
403 | { | 417 | { |
404 | /** | 418 | /** |
405 | * | 419 | * First HELLO we are merging. |
406 | */ | 420 | */ |
407 | const struct GNUNET_HELLO_Message *h1; | 421 | const struct GNUNET_HELLO_Message *h1; |
408 | 422 | ||
409 | /** | 423 | /** |
410 | * | 424 | * Second HELLO we are merging. |
411 | */ | 425 | */ |
412 | const struct GNUNET_HELLO_Message *h2; | 426 | const struct GNUNET_HELLO_Message *h2; |
413 | 427 | ||
414 | /** | 428 | /** |
415 | * | 429 | * Either @e h1 or @e h2, used when copying |
430 | * to compare against (so we only copy the | ||
431 | * most recent entry). | ||
416 | */ | 432 | */ |
417 | const struct GNUNET_HELLO_Message *other; | 433 | const struct GNUNET_HELLO_Message *other; |
418 | 434 | ||
419 | /** | 435 | /** |
420 | * | 436 | * Buffer where we copy to. |
421 | */ | 437 | */ |
422 | char *buf; | 438 | char *buf; |
423 | 439 | ||
424 | /** | 440 | /** |
425 | * | 441 | * Number of bytes allocated in @e buf |
426 | */ | 442 | */ |
427 | size_t max; | 443 | size_t max; |
428 | 444 | ||
429 | /** | 445 | /** |
430 | * | 446 | * Current (write) offset in @e buf. |
431 | */ | 447 | */ |
432 | size_t ret; | 448 | size_t ret; |
433 | 449 | ||
434 | /** | 450 | /** |
435 | * | 451 | * Should we copy addresses with an identical value |
452 | * and expiration time in @e other, or do we only | ||
453 | * copy addresses with strictly later expiration times? | ||
436 | */ | 454 | */ |
437 | int take_equal; | 455 | int take_equal; |
438 | 456 | ||
@@ -440,12 +458,14 @@ struct MergeContext | |||
440 | 458 | ||
441 | 459 | ||
442 | /** | 460 | /** |
461 | * Append the address @a address to the buffer from | ||
462 | * the merge context IF it is more recent than equivalent | ||
463 | * addresses in `other`. | ||
443 | * | 464 | * |
444 | * | 465 | * @param cls the `struct MergeContext` |
445 | * @param cls | 466 | * @param address the HELLO address we might copy |
446 | * @param address | 467 | * @param expiration expiration time for @a address |
447 | * @param expiration | 468 | * @return always #GNUNET_OK |
448 | * @return | ||
449 | */ | 469 | */ |
450 | static int | 470 | static int |
451 | copy_latest (void *cls, | 471 | copy_latest (void *cls, |
@@ -457,14 +477,21 @@ copy_latest (void *cls, | |||
457 | 477 | ||
458 | ec.address = address; | 478 | ec.address = address; |
459 | ec.found = GNUNET_NO; | 479 | ec.found = GNUNET_NO; |
460 | GNUNET_HELLO_iterate_addresses (mc->other, GNUNET_NO, &get_match_exp, &ec); | 480 | /* check if address exists in other */ |
461 | if ((ec.found == GNUNET_NO) || | 481 | GNUNET_HELLO_iterate_addresses (mc->other, |
462 | (ec.expiration.abs_value_us < expiration.abs_value_us) || | 482 | GNUNET_NO, |
463 | ((ec.expiration.abs_value_us == expiration.abs_value_us) && | 483 | &get_match_exp, |
464 | (mc->take_equal == GNUNET_YES))) | 484 | &ec); |
485 | if ( (GNUNET_NO == ec.found) || | ||
486 | (ec.expiration.abs_value_us < expiration.abs_value_us) || | ||
487 | ( (ec.expiration.abs_value_us == expiration.abs_value_us) && | ||
488 | (GNUNET_YES == mc->take_equal) ) ) | ||
465 | { | 489 | { |
490 | /* copy address to buffer */ | ||
466 | mc->ret += | 491 | mc->ret += |
467 | GNUNET_HELLO_add_address (address, expiration, &mc->buf[mc->ret], | 492 | GNUNET_HELLO_add_address (address, |
493 | expiration, | ||
494 | &mc->buf[mc->ret], | ||
468 | mc->max - mc->ret); | 495 | mc->max - mc->ret); |
469 | } | 496 | } |
470 | return GNUNET_OK; | 497 | return GNUNET_OK; |
@@ -472,7 +499,14 @@ copy_latest (void *cls, | |||
472 | 499 | ||
473 | 500 | ||
474 | /** | 501 | /** |
502 | * Function called to build the HELLO during | ||
503 | * #GNUNET_HELLO_merge() by merging addresses from | ||
504 | * two original HELLOs. | ||
475 | * | 505 | * |
506 | * @param cls the `struct MergeContext` | ||
507 | * @param max number of bytes we can write at most in @a buf | ||
508 | * @param buf where to copy the addresses | ||
509 | * @return #GNUNET_SYSERR to end iteration, otherwise number of bytes written to @a buf | ||
476 | */ | 510 | */ |
477 | static ssize_t | 511 | static ssize_t |
478 | merge_addr (void *cls, | 512 | merge_addr (void *cls, |
@@ -481,17 +515,26 @@ merge_addr (void *cls, | |||
481 | { | 515 | { |
482 | struct MergeContext *mc = cls; | 516 | struct MergeContext *mc = cls; |
483 | 517 | ||
484 | if (mc->h1 == NULL) | 518 | if (NULL == mc->h1) |
485 | return GNUNET_SYSERR; /* Stop iteration */ | 519 | return GNUNET_SYSERR; /* Stop iteration */ |
486 | mc->ret = 0; | 520 | mc->ret = 0; |
487 | mc->max = max; | 521 | mc->max = max; |
488 | mc->buf = buf; | 522 | mc->buf = buf; |
489 | mc->take_equal = GNUNET_NO; | 523 | mc->take_equal = GNUNET_NO; |
490 | mc->other = mc->h2; | 524 | mc->other = mc->h2; |
491 | GNUNET_HELLO_iterate_addresses (mc->h1, GNUNET_NO, ©_latest, mc); | 525 | /* copy addresses from h1, if strictly larger expiration than h2 */ |
526 | GNUNET_HELLO_iterate_addresses (mc->h1, | ||
527 | GNUNET_NO, | ||
528 | ©_latest, | ||
529 | mc); | ||
492 | mc->take_equal = GNUNET_YES; | 530 | mc->take_equal = GNUNET_YES; |
493 | mc->other = mc->h1; | 531 | mc->other = mc->h1; |
494 | GNUNET_HELLO_iterate_addresses (mc->h2, GNUNET_NO, ©_latest, mc); | 532 | /* copy addresses from h2, if larger or equal expiration than h1 */ |
533 | GNUNET_HELLO_iterate_addresses (mc->h2, | ||
534 | GNUNET_NO, | ||
535 | ©_latest, | ||
536 | mc); | ||
537 | /* set marker to stop iteration */ | ||
495 | mc->h1 = NULL; | 538 | mc->h1 = NULL; |
496 | return mc->ret; | 539 | return mc->ret; |
497 | } | 540 | } |
@@ -504,7 +547,7 @@ merge_addr (void *cls, | |||
504 | * | 547 | * |
505 | * @param h1 first HELLO message | 548 | * @param h1 first HELLO message |
506 | * @param h2 the second HELLO message | 549 | * @param h2 the second HELLO message |
507 | * @return the combined hello message | 550 | * @return the combined HELLO message |
508 | */ | 551 | */ |
509 | struct GNUNET_HELLO_Message * | 552 | struct GNUNET_HELLO_Message * |
510 | GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1, | 553 | GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1, |
@@ -526,17 +569,18 @@ GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1, | |||
526 | 569 | ||
527 | 570 | ||
528 | /** | 571 | /** |
529 | * | 572 | * Context used in #GNUNET_HELLO_iterate_new_addresses() to |
573 | * figure out which addresses are in fact 'new'. | ||
530 | */ | 574 | */ |
531 | struct DeltaContext | 575 | struct DeltaContext |
532 | { | 576 | { |
533 | /** | 577 | /** |
534 | * | 578 | * We should ignore addresses that expire before this time. |
535 | */ | 579 | */ |
536 | struct GNUNET_TIME_Absolute expiration_limit; | 580 | struct GNUNET_TIME_Absolute expiration_limit; |
537 | 581 | ||
538 | /** | 582 | /** |
539 | * | 583 | * Function to call on addresses that are indeed new. |
540 | */ | 584 | */ |
541 | GNUNET_HELLO_AddressIterator it; | 585 | GNUNET_HELLO_AddressIterator it; |
542 | 586 | ||
@@ -546,14 +590,24 @@ struct DeltaContext | |||
546 | void *it_cls; | 590 | void *it_cls; |
547 | 591 | ||
548 | /** | 592 | /** |
549 | * | 593 | * HELLO with known addresses, addresses in this HELLO |
594 | * we must always ignore. | ||
550 | */ | 595 | */ |
551 | const struct GNUNET_HELLO_Message *old_hello; | 596 | const struct GNUNET_HELLO_Message *old_hello; |
552 | }; | 597 | }; |
553 | 598 | ||
554 | 599 | ||
555 | /** | 600 | /** |
601 | * Check if the given address is 'new', and if so, call | ||
602 | * the iterator. Compares the existing address against | ||
603 | * addresses in the context's `old_hello` and calls the | ||
604 | * iterator on those that are new (and not expired). | ||
556 | * | 605 | * |
606 | * @param cls the `struct DeltaContext` | ||
607 | * @param address an address to check whether it is new | ||
608 | * @param expiration expiration time for @a address | ||
609 | * @return #GNUNET_YES if the address is ignored, otherwise | ||
610 | * whatever the iterator returned. | ||
557 | */ | 611 | */ |
558 | static int | 612 | static int |
559 | delta_match (void *cls, | 613 | delta_match (void *cls, |
@@ -570,22 +624,26 @@ delta_match (void *cls, | |||
570 | GNUNET_NO, | 624 | GNUNET_NO, |
571 | &get_match_exp, | 625 | &get_match_exp, |
572 | &ec); | 626 | &ec); |
573 | if ((ec.found == GNUNET_YES) && | 627 | if ( (GNUNET_YES == ec.found) && |
574 | ((ec.expiration.abs_value_us > expiration.abs_value_us) || | 628 | ( (ec.expiration.abs_value_us > expiration.abs_value_us) || |
575 | (ec.expiration.abs_value_us >= dc->expiration_limit.abs_value_us))) | 629 | (ec.expiration.abs_value_us >= dc->expiration_limit.abs_value_us))) |
576 | return GNUNET_YES; /* skip */ | 630 | return GNUNET_YES; /* skip: found and boring */ |
577 | ret = dc->it (dc->it_cls, address, expiration); | 631 | ret = dc->it (dc->it_cls, |
632 | address, | ||
633 | expiration); | ||
578 | return ret; | 634 | return ret; |
579 | } | 635 | } |
580 | 636 | ||
581 | 637 | ||
582 | /** | 638 | /** |
583 | * Iterate over addresses in "new_hello" that | 639 | * Iterate over addresses in @a new_hello that are NOT already present |
584 | * are NOT already present in "old_hello". | 640 | * in @a old_hello. Note that if the address is present in @a old_hello |
641 | * but the expiration time in @a new_hello is more recent, the iterator | ||
642 | * is also called. | ||
585 | * | 643 | * |
586 | * @param new_hello a HELLO message | 644 | * @param new_hello a HELLO message |
587 | * @param old_hello a HELLO message | 645 | * @param old_hello a HELLO message |
588 | * @param expiration_limit ignore addresses in old_hello | 646 | * @param expiration_limit ignore addresses in @a old_hello |
589 | * that expired before the given time stamp | 647 | * that expired before the given time stamp |
590 | * @param it iterator to call on each address | 648 | * @param it iterator to call on each address |
591 | * @param it_cls closure for @a it | 649 | * @param it_cls closure for @a it |
@@ -603,7 +661,11 @@ GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message *new_hello | |||
603 | dc.it = it; | 661 | dc.it = it; |
604 | dc.it_cls = it_cls; | 662 | dc.it_cls = it_cls; |
605 | dc.old_hello = old_hello; | 663 | dc.old_hello = old_hello; |
606 | GNUNET_HELLO_iterate_addresses (new_hello, GNUNET_NO, &delta_match, &dc); | 664 | GNUNET_assert (NULL == |
665 | GNUNET_HELLO_iterate_addresses (new_hello, | ||
666 | GNUNET_NO, | ||
667 | &delta_match, | ||
668 | &dc)); | ||
607 | } | 669 | } |
608 | 670 | ||
609 | 671 | ||
@@ -625,27 +687,6 @@ GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello) | |||
625 | 687 | ||
626 | 688 | ||
627 | /** | 689 | /** |
628 | * Get the public key from a HELLO message. | ||
629 | * | ||
630 | * @param hello the hello message | ||
631 | * @param publicKey where to copy the public key information, can be NULL | ||
632 | * @return #GNUNET_SYSERR if the HELLO was malformed | ||
633 | */ | ||
634 | int | ||
635 | GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello, | ||
636 | struct GNUNET_CRYPTO_EddsaPublicKey *publicKey) | ||
637 | { | ||
638 | uint16_t ret = ntohs (hello->header.size); | ||
639 | |||
640 | if ((ret < sizeof (struct GNUNET_HELLO_Message)) || | ||
641 | (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO)) | ||
642 | return GNUNET_SYSERR; | ||
643 | *publicKey = hello->publicKey; | ||
644 | return GNUNET_OK; | ||
645 | } | ||
646 | |||
647 | |||
648 | /** | ||
649 | * Get the peer identity from a HELLO message. | 690 | * Get the peer identity from a HELLO message. |
650 | * | 691 | * |
651 | * @param hello the hello message | 692 | * @param hello the hello message |
@@ -688,37 +729,41 @@ GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello) | |||
688 | 729 | ||
689 | 730 | ||
690 | /** | 731 | /** |
691 | * | 732 | * Context used for comparing HELLOs in #GNUNET_HELLO_equals(). |
692 | */ | 733 | */ |
693 | struct EqualsContext | 734 | struct EqualsContext |
694 | { | 735 | { |
695 | /** | 736 | /** |
696 | * | 737 | * Addresses that expired before this date are ignored for |
738 | * the comparisson. | ||
697 | */ | 739 | */ |
698 | struct GNUNET_TIME_Absolute expiration_limit; | 740 | struct GNUNET_TIME_Absolute expiration_limit; |
699 | 741 | ||
700 | /** | 742 | /** |
701 | * | 743 | * Earliest expiration time for which we found a match |
744 | * with a difference in expiration times. | ||
745 | * At this time, the two HELLOs may start to diverge. | ||
702 | */ | 746 | */ |
703 | struct GNUNET_TIME_Absolute result; | 747 | struct GNUNET_TIME_Absolute result; |
704 | 748 | ||
705 | /** | 749 | /** |
706 | * | 750 | * HELLO message to compare against. (First set to the second |
751 | * HELLO, then set to the first HELLO.) | ||
707 | */ | 752 | */ |
708 | const struct GNUNET_HELLO_Message *h2; | 753 | const struct GNUNET_HELLO_Message *ref; |
709 | 754 | ||
710 | /** | 755 | /** |
711 | * | 756 | * Address we are currently looking for. |
712 | */ | 757 | */ |
713 | const struct GNUNET_HELLO_Address *address; | 758 | const struct GNUNET_HELLO_Address *address; |
714 | 759 | ||
715 | /** | 760 | /** |
716 | * | 761 | * Expiration time of @e address. |
717 | */ | 762 | */ |
718 | struct GNUNET_TIME_Absolute expiration; | 763 | struct GNUNET_TIME_Absolute expiration; |
719 | 764 | ||
720 | /** | 765 | /** |
721 | * | 766 | * Did we find the address we were looking for? |
722 | */ | 767 | */ |
723 | int found; | 768 | int found; |
724 | 769 | ||
@@ -726,7 +771,16 @@ struct EqualsContext | |||
726 | 771 | ||
727 | 772 | ||
728 | /** | 773 | /** |
774 | * Check if the given address matches the address we are currently | ||
775 | * looking for. If so, sets `found` to #GNUNET_YES and, if the | ||
776 | * expiration times for the two addresses differ, updates `result` to | ||
777 | * the minimum of our @a expiration and the existing value | ||
729 | * | 778 | * |
779 | * @param cls the `struct EqualsContext` | ||
780 | * @param address address from the reference HELLO | ||
781 | * @param expiration expiration time for @a address | ||
782 | * @return #GNUNET_YES if the address is expired or does not match | ||
783 | * #GNUNET_SYSERR if the address does match. | ||
730 | */ | 784 | */ |
731 | static int | 785 | static int |
732 | find_other_matching (void *cls, | 786 | find_other_matching (void *cls, |
@@ -741,7 +795,8 @@ find_other_matching (void *cls, | |||
741 | { | 795 | { |
742 | ec->found = GNUNET_YES; | 796 | ec->found = GNUNET_YES; |
743 | if (expiration.abs_value_us < ec->expiration.abs_value_us) | 797 | if (expiration.abs_value_us < ec->expiration.abs_value_us) |
744 | ec->result = GNUNET_TIME_absolute_min (expiration, ec->result); | 798 | ec->result = GNUNET_TIME_absolute_min (expiration, |
799 | ec->result); | ||
745 | return GNUNET_SYSERR; | 800 | return GNUNET_SYSERR; |
746 | } | 801 | } |
747 | return GNUNET_YES; | 802 | return GNUNET_YES; |
@@ -749,7 +804,16 @@ find_other_matching (void *cls, | |||
749 | 804 | ||
750 | 805 | ||
751 | /** | 806 | /** |
807 | * Helper function for #GNUNET_HELLO_equals(). Checks | ||
808 | * if the given @a address exists also in the other HELLO; | ||
809 | * if not, the result time is set to zero and the iteration | ||
810 | * is aborted. | ||
752 | * | 811 | * |
812 | * @param cls the `struct EqualsContext` | ||
813 | * @param address address to locate | ||
814 | * @param expiration expiration time of the current address | ||
815 | * @return #GNUNET_OK if the address exists or is expired, | ||
816 | * #GNUNET_SYSERR if it was not found | ||
753 | */ | 817 | */ |
754 | static int | 818 | static int |
755 | find_matching (void *cls, | 819 | find_matching (void *cls, |
@@ -759,13 +823,17 @@ find_matching (void *cls, | |||
759 | struct EqualsContext *ec = cls; | 823 | struct EqualsContext *ec = cls; |
760 | 824 | ||
761 | if (expiration.abs_value_us < ec->expiration_limit.abs_value_us) | 825 | if (expiration.abs_value_us < ec->expiration_limit.abs_value_us) |
762 | return GNUNET_YES; | 826 | return GNUNET_OK; /* expired, we don't care */ |
763 | ec->address = address; | 827 | ec->address = address; |
764 | ec->expiration = expiration; | 828 | ec->expiration = expiration; |
765 | ec->found = GNUNET_NO; | 829 | ec->found = GNUNET_NO; |
766 | GNUNET_HELLO_iterate_addresses (ec->h2, GNUNET_NO, &find_other_matching, ec); | 830 | GNUNET_HELLO_iterate_addresses (ec->ref, |
767 | if (ec->found == GNUNET_NO) | 831 | GNUNET_NO, |
832 | &find_other_matching, | ||
833 | ec); | ||
834 | if (GNUNET_NO == ec->found) | ||
768 | { | 835 | { |
836 | /* not found, we differ *now* */ | ||
769 | ec->result = GNUNET_TIME_UNIT_ZERO_ABS; | 837 | ec->result = GNUNET_TIME_UNIT_ZERO_ABS; |
770 | return GNUNET_SYSERR; | 838 | return GNUNET_SYSERR; |
771 | } | 839 | } |
@@ -776,7 +844,7 @@ find_matching (void *cls, | |||
776 | /** | 844 | /** |
777 | * Test if two HELLO messages contain the same addresses. | 845 | * Test if two HELLO messages contain the same addresses. |
778 | * If they only differ in expiration time, the lowest | 846 | * If they only differ in expiration time, the lowest |
779 | * expiration time larger than 'now' where they differ | 847 | * expiration time larger than @a now where they differ |
780 | * is returned. | 848 | * is returned. |
781 | * | 849 | * |
782 | * @param h1 first HELLO message | 850 | * @param h1 first HELLO message |
@@ -784,9 +852,9 @@ find_matching (void *cls, | |||
784 | * @param now time to use for deciding which addresses have | 852 | * @param now time to use for deciding which addresses have |
785 | * expired and should not be considered at all | 853 | * expired and should not be considered at all |
786 | * @return absolute time forever if the two HELLOs are | 854 | * @return absolute time forever if the two HELLOs are |
787 | * totally identical; smallest timestamp >= now if | 855 | * totally identical; smallest timestamp >= @a now if |
788 | * they only differ in timestamps; | 856 | * they only differ in timestamps; |
789 | * zero if the some addresses with expirations >= now | 857 | * zero if the some addresses with expirations >= @a now |
790 | * do not match at all | 858 | * do not match at all |
791 | */ | 859 | */ |
792 | struct GNUNET_TIME_Absolute | 860 | struct GNUNET_TIME_Absolute |
@@ -797,22 +865,22 @@ GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1, | |||
797 | struct EqualsContext ec; | 865 | struct EqualsContext ec; |
798 | 866 | ||
799 | if (h1->header.type != h2->header.type) | 867 | if (h1->header.type != h2->header.type) |
800 | return GNUNET_TIME_UNIT_ZERO_ABS; | 868 | return GNUNET_TIME_UNIT_ZERO_ABS; |
801 | |||
802 | if (0 != | 869 | if (0 != |
803 | memcmp (&h1->publicKey, &h2->publicKey, | 870 | memcmp (&h1->publicKey, |
871 | &h2->publicKey, | ||
804 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) | 872 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) |
805 | return GNUNET_TIME_UNIT_ZERO_ABS; | 873 | return GNUNET_TIME_UNIT_ZERO_ABS; |
806 | ec.expiration_limit = now; | 874 | ec.expiration_limit = now; |
807 | ec.result = GNUNET_TIME_UNIT_FOREVER_ABS; | 875 | ec.result = GNUNET_TIME_UNIT_FOREVER_ABS; |
808 | ec.h2 = h2; | 876 | ec.ref = h2; |
809 | GNUNET_HELLO_iterate_addresses (h1, | 877 | GNUNET_HELLO_iterate_addresses (h1, |
810 | GNUNET_NO, | 878 | GNUNET_NO, |
811 | &find_matching, | 879 | &find_matching, |
812 | &ec); | 880 | &ec); |
813 | if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us) | 881 | if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us) |
814 | return ec.result; | 882 | return ec.result; |
815 | ec.h2 = h1; | 883 | ec.ref = h1; |
816 | GNUNET_HELLO_iterate_addresses (h2, | 884 | GNUNET_HELLO_iterate_addresses (h2, |
817 | GNUNET_NO, | 885 | GNUNET_NO, |
818 | &find_matching, | 886 | &find_matching, |
@@ -822,7 +890,13 @@ GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1, | |||
822 | 890 | ||
823 | 891 | ||
824 | /** | 892 | /** |
893 | * Iterator to find the time when the last address will expire. | ||
894 | * Updates the maximum value stored in @a cls. | ||
825 | * | 895 | * |
896 | * @param cls where to store the max, a `struct GNUNET_TIME_Absolute` | ||
897 | * @param address an address (ignored) | ||
898 | * @param expiration expiration time for @a address | ||
899 | * @return #GNUNET_OK (always) | ||
826 | */ | 900 | */ |
827 | static int | 901 | static int |
828 | find_max_expire (void *cls, | 902 | find_max_expire (void *cls, |
@@ -847,7 +921,7 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg) | |||
847 | { | 921 | { |
848 | struct GNUNET_TIME_Absolute ret; | 922 | struct GNUNET_TIME_Absolute ret; |
849 | 923 | ||
850 | ret.abs_value_us = 0; | 924 | ret = GNUNET_TIME_UNIT_ZERO_ABS; |
851 | GNUNET_HELLO_iterate_addresses (msg, | 925 | GNUNET_HELLO_iterate_addresses (msg, |
852 | GNUNET_NO, | 926 | GNUNET_NO, |
853 | &find_max_expire, | 927 | &find_max_expire, |
@@ -954,7 +1028,10 @@ add_address_to_uri (void *cls, | |||
954 | "%s%c%s%c%s%c%s", | 1028 | "%s%c%s%c%s%c%s", |
955 | ctx->uri, | 1029 | ctx->uri, |
956 | GNUNET_HELLO_URI_SEP, | 1030 | GNUNET_HELLO_URI_SEP, |
957 | strftime (tbuf, sizeof (tbuf), "%Y%m%d%H%M%S", t) ? tbuf : "0", | 1031 | strftime (tbuf, |
1032 | sizeof (tbuf), | ||
1033 | "%Y%m%d%H%M%S", | ||
1034 | t) ? tbuf : "0", | ||
958 | GNUNET_HELLO_URI_SEP, | 1035 | GNUNET_HELLO_URI_SEP, |
959 | address->transport_name, | 1036 | address->transport_name, |
960 | GNUNET_HELLO_URI_SEP, | 1037 | GNUNET_HELLO_URI_SEP, |
@@ -1006,7 +1083,9 @@ GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello, | |||
1006 | * @return number of bytes added to buffer, #GNUNET_SYSERR on error | 1083 | * @return number of bytes added to buffer, #GNUNET_SYSERR on error |
1007 | */ | 1084 | */ |
1008 | static ssize_t | 1085 | static ssize_t |
1009 | add_address_to_hello (void *cls, size_t max, void *buffer) | 1086 | add_address_to_hello (void *cls, |
1087 | size_t max, | ||
1088 | void *buffer) | ||
1010 | { | 1089 | { |
1011 | struct GNUNET_HELLO_ParseUriContext *ctx = cls; | 1090 | struct GNUNET_HELLO_ParseUriContext *ctx = cls; |
1012 | const char *tname; | 1091 | const char *tname; |
@@ -1033,7 +1112,8 @@ add_address_to_hello (void *cls, size_t max, void *buffer) | |||
1033 | } | 1112 | } |
1034 | ctx->pos++; | 1113 | ctx->pos++; |
1035 | 1114 | ||
1036 | if ('0' == ctx->pos[0] && GNUNET_HELLO_URI_SEP == ctx->pos[1]) | 1115 | if ( ('0' == ctx->pos[0]) && |
1116 | (GNUNET_HELLO_URI_SEP == ctx->pos[1]) ) | ||
1037 | { | 1117 | { |
1038 | expire = GNUNET_TIME_UNIT_FOREVER_ABS; | 1118 | expire = GNUNET_TIME_UNIT_FOREVER_ABS; |
1039 | tname = ctx->pos + 1; | 1119 | tname = ctx->pos + 1; |
@@ -1162,18 +1242,18 @@ GNUNET_HELLO_parse_uri (const char *uri, | |||
1162 | GNUNET_HELLO_URI_PREFIX, | 1242 | GNUNET_HELLO_URI_PREFIX, |
1163 | strlen (GNUNET_HELLO_URI_PREFIX))) | 1243 | strlen (GNUNET_HELLO_URI_PREFIX))) |
1164 | { | 1244 | { |
1165 | pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)]; | 1245 | pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)]; |
1166 | friend_only = GNUNET_NO; | 1246 | friend_only = GNUNET_NO; |
1167 | } | 1247 | } |
1168 | else if (0 == strncmp (uri, | 1248 | else if (0 == strncmp (uri, |
1169 | GNUNET_FRIEND_HELLO_URI_PREFIX, | 1249 | GNUNET_FRIEND_HELLO_URI_PREFIX, |
1170 | strlen (GNUNET_FRIEND_HELLO_URI_PREFIX))) | 1250 | strlen (GNUNET_FRIEND_HELLO_URI_PREFIX))) |
1171 | { | 1251 | { |
1172 | pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)]; | 1252 | pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)]; |
1173 | friend_only = GNUNET_YES; | 1253 | friend_only = GNUNET_YES; |
1174 | } | 1254 | } |
1175 | else | 1255 | else |
1176 | return GNUNET_SYSERR; | 1256 | return GNUNET_SYSERR; |
1177 | exc = strchr (pks, GNUNET_HELLO_URI_SEP); | 1257 | exc = strchr (pks, GNUNET_HELLO_URI_SEP); |
1178 | 1258 | ||
1179 | if (GNUNET_OK != | 1259 | if (GNUNET_OK != |
@@ -1188,11 +1268,15 @@ GNUNET_HELLO_parse_uri (const char *uri, | |||
1188 | ctx.counter_total = 0; | 1268 | ctx.counter_total = 0; |
1189 | ctx.counter_added = 0; | 1269 | ctx.counter_added = 0; |
1190 | ctx.plugins_find = plugins_find; | 1270 | ctx.plugins_find = plugins_find; |
1191 | *hello = GNUNET_HELLO_create (pubkey, &add_address_to_hello, &ctx, friend_only); | 1271 | *hello = GNUNET_HELLO_create (pubkey, |
1272 | &add_address_to_hello, | ||
1273 | &ctx, | ||
1274 | friend_only); | ||
1192 | 1275 | ||
1193 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1276 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1194 | _("HELLO URI contained %u addresses, added %u addresses\n"), | 1277 | "HELLO URI contained %u addresses, added %u addresses\n", |
1195 | ctx.counter_total, ctx.counter_added); | 1278 | ctx.counter_total, |
1279 | ctx.counter_added); | ||
1196 | 1280 | ||
1197 | return ctx.ret; | 1281 | return ctx.ret; |
1198 | } | 1282 | } |