diff options
Diffstat (limited to 'src/hello/hello-uri.c')
-rw-r--r-- | src/hello/hello-uri.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/hello/hello-uri.c b/src/hello/hello-uri.c index 8f8f699e9..9e8d6909d 100644 --- a/src/hello/hello-uri.c +++ b/src/hello/hello-uri.c | |||
@@ -204,6 +204,32 @@ struct GNUNET_HELLO_Builder | |||
204 | 204 | ||
205 | }; | 205 | }; |
206 | 206 | ||
207 | /** | ||
208 | * Struct to wrap data to do the merge of to hello uris. | ||
209 | */ | ||
210 | struct AddressUriMergeResult | ||
211 | { | ||
212 | /** | ||
213 | * The builder of the hello uri we merge with. | ||
214 | */ | ||
215 | struct GNUNET_HELLO_Builder *builder; | ||
216 | |||
217 | /** | ||
218 | * The actual address to check, if it is allready in the hello uri we merge with. | ||
219 | */ | ||
220 | const char *address_uri; | ||
221 | |||
222 | /** | ||
223 | * Did we found the actual address to check. | ||
224 | */ | ||
225 | unsigned int found; | ||
226 | |||
227 | /** | ||
228 | * Did we found at least one address to merge. | ||
229 | */ | ||
230 | unsigned int merged; | ||
231 | }; | ||
232 | |||
207 | 233 | ||
208 | /** | 234 | /** |
209 | * Compute @a hash over addresses in @a builder. | 235 | * Compute @a hash over addresses in @a builder. |
@@ -315,6 +341,13 @@ GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid) | |||
315 | } | 341 | } |
316 | 342 | ||
317 | 343 | ||
344 | struct GNUNET_PeerIdentity * | ||
345 | GNUNET_HELLO_builder_get_id (struct GNUNET_HELLO_Builder *builder) | ||
346 | { | ||
347 | return &builder->pid; | ||
348 | } | ||
349 | |||
350 | |||
318 | void | 351 | void |
319 | GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder) | 352 | GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder) |
320 | { | 353 | { |
@@ -412,6 +445,94 @@ GNUNET_HELLO_builder_from_block (const void *block, | |||
412 | } | 445 | } |
413 | 446 | ||
414 | 447 | ||
448 | static void | ||
449 | merge_hellos2 (void *cls, const char *address_uri2) | ||
450 | { | ||
451 | struct AddressUriMergeResult *aumr = cls; | ||
452 | const char *address_uri1 = aumr->address_uri; | ||
453 | |||
454 | if (GNUNET_NO == aumr->found && 0 != GNUNET_memcmp (address_uri1, | ||
455 | address_uri2)) | ||
456 | { | ||
457 | aumr->found = GNUNET_YES; | ||
458 | } | ||
459 | } | ||
460 | |||
461 | |||
462 | static void | ||
463 | merge_hellos1 (void *cls, const char *address_uri1) | ||
464 | { | ||
465 | struct AddressUriMergeResult *aumr = cls; | ||
466 | struct GNUNET_HELLO_Builder *builder2 = aumr->builder; | ||
467 | struct GNUNET_PeerIdentity *peer2 = GNUNET_HELLO_builder_get_id (builder2); | ||
468 | |||
469 | aumr->address_uri = address_uri1; | ||
470 | GNUNET_HELLO_builder_iterate (builder2, peer2, &merge_hellos2, aumr); | ||
471 | if (GNUNET_YES == aumr->found) | ||
472 | { | ||
473 | GNUNET_HELLO_builder_add_address (builder2, address_uri1); | ||
474 | aumr->merged = GNUNET_YES; | ||
475 | } | ||
476 | aumr->found = GNUNET_NO; | ||
477 | } | ||
478 | |||
479 | |||
480 | struct GNUNET_MQ_Envelope * | ||
481 | GNUNET_HELLO_builder_merge_hellos (const struct GNUNET_MessageHeader *msg1, | ||
482 | const struct GNUNET_MessageHeader *msg2, | ||
483 | const struct | ||
484 | GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
485 | { | ||
486 | struct HelloUriMessage *hum1 = (struct HelloUriMessage *) msg1; | ||
487 | struct BlockHeader *bh1 = (struct BlockHeader *) &msg1[1]; | ||
488 | struct GNUNET_TIME_Absolute expiration_time1 = GNUNET_TIME_absolute_ntoh ( | ||
489 | bh1->expiration_time); | ||
490 | struct HelloUriMessage *hum2 = (struct HelloUriMessage *) msg2; | ||
491 | struct BlockHeader *bh2 = (struct BlockHeader *) &msg2[1]; | ||
492 | struct GNUNET_TIME_Absolute expiration_time2 = GNUNET_TIME_absolute_ntoh ( | ||
493 | bh1->expiration_time); | ||
494 | struct GNUNET_HELLO_Builder *builder1 = GNUNET_HELLO_builder_from_msg (msg1); | ||
495 | struct GNUNET_HELLO_Builder *builder2 = GNUNET_HELLO_builder_from_msg (msg2); | ||
496 | struct AddressUriMergeResult *aumr = GNUNET_new (struct | ||
497 | AddressUriMergeResult); | ||
498 | struct GNUNET_PeerIdentity *peer1 = GNUNET_HELLO_builder_get_id (builder1); | ||
499 | struct GNUNET_MQ_Envelope *env; | ||
500 | struct GNUNET_TIME_Absolute expiration_time; | ||
501 | |||
502 | aumr->builder = builder2; | ||
503 | GNUNET_HELLO_builder_iterate (builder1, peer1, &merge_hellos1, aumr); | ||
504 | |||
505 | if (GNUNET_YES == aumr->merged) | ||
506 | { | ||
507 | if (expiration_time1.abs_value_us < expiration_time2.abs_value_us) | ||
508 | expiration_time = expiration_time1; | ||
509 | else | ||
510 | expiration_time = expiration_time2; | ||
511 | env = GNUNET_HELLO_builder_to_env (builder2, | ||
512 | priv, | ||
513 | GNUNET_TIME_absolute_get_remaining ( | ||
514 | expiration_time)); | ||
515 | } | ||
516 | else if (expiration_time1.abs_value_us != expiration_time2.abs_value_us) | ||
517 | { | ||
518 | if (expiration_time1.abs_value_us < expiration_time2.abs_value_us) | ||
519 | expiration_time = expiration_time2; | ||
520 | else | ||
521 | expiration_time = expiration_time1; | ||
522 | env = GNUNET_HELLO_builder_to_env (builder2, | ||
523 | priv, | ||
524 | GNUNET_TIME_absolute_get_remaining ( | ||
525 | expiration_time)); | ||
526 | } | ||
527 | |||
528 | GNUNET_HELLO_builder_free (builder1); | ||
529 | GNUNET_HELLO_builder_free (builder2); | ||
530 | GNUNET_free (aumr); | ||
531 | |||
532 | return env; | ||
533 | } | ||
534 | |||
535 | |||
415 | struct GNUNET_HELLO_Builder * | 536 | struct GNUNET_HELLO_Builder * |
416 | GNUNET_HELLO_builder_from_url (const char *url) | 537 | GNUNET_HELLO_builder_from_url (const char *url) |
417 | { | 538 | { |