diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-08-06 20:27:22 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-08-06 20:27:22 +0000 |
commit | 4700ee225497a1dbfbda029f0cee5321a40654da (patch) | |
tree | ed74fa3d45a4ba4dbf4f1860ec80a6e224eaab43 /src/transport/gnunet-service-transport_validation.c | |
parent | 79fdb70dea5c857406c26c77cce34f959a0adff7 (diff) | |
download | gnunet-4700ee225497a1dbfbda029f0cee5321a40654da.tar.gz gnunet-4700ee225497a1dbfbda029f0cee5321a40654da.zip |
handle PONGs
Diffstat (limited to 'src/transport/gnunet-service-transport_validation.c')
-rw-r--r-- | src/transport/gnunet-service-transport_validation.c | 300 |
1 files changed, 243 insertions, 57 deletions
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index d0331c192..4f0848c87 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c | |||
@@ -33,16 +33,6 @@ | |||
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * How long until a HELLO verification attempt should time out? | ||
37 | * Must be rather small, otherwise a partially successful HELLO | ||
38 | * validation (some addresses working) might not be available | ||
39 | * before a client's request for a connection fails for good. | ||
40 | * Besides, if a single request to an address takes a long time, | ||
41 | * then the peer is unlikely worthwhile anyway. | ||
42 | */ | ||
43 | #define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) | ||
44 | |||
45 | /** | ||
46 | * How long is a PONG signature valid? We'll recycle a signature until | 36 | * How long is a PONG signature valid? We'll recycle a signature until |
47 | * 1/4 of this time is remaining. PONGs should expire so that if our | 37 | * 1/4 of this time is remaining. PONGs should expire so that if our |
48 | * external addresses change an adversary cannot replay them indefinitely. | 38 | * external addresses change an adversary cannot replay them indefinitely. |
@@ -66,25 +56,19 @@ | |||
66 | #define HELLO_REVALIDATION_START_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1) | 56 | #define HELLO_REVALIDATION_START_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1) |
67 | 57 | ||
68 | /** | 58 | /** |
69 | * How long before we try to check an address again (if it turned out to | ||
70 | * be invalid the first time)? | ||
71 | */ | ||
72 | #define MAX_REVALIDATION_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1) | ||
73 | |||
74 | /** | ||
75 | * Size of the validation map hashmap. | 59 | * Size of the validation map hashmap. |
76 | */ | 60 | */ |
77 | #define VALIDATION_MAP_SIZE 256 | 61 | #define VALIDATION_MAP_SIZE 256 |
78 | 62 | ||
79 | /** | 63 | /** |
80 | * Priority to use for PINGs and PONGs | 64 | * Priority to use for PINGs |
81 | */ | 65 | */ |
82 | #define PING_PRIORITY 1 | 66 | #define PING_PRIORITY 2 |
83 | 67 | ||
84 | /** | 68 | /** |
85 | * Priority to use for PINGs and PONGs | 69 | * Priority to use for PONGs |
86 | */ | 70 | */ |
87 | #define PONG_PRIORITY 1 | 71 | #define PONG_PRIORITY 4 |
88 | 72 | ||
89 | 73 | ||
90 | /** | 74 | /** |
@@ -191,6 +175,11 @@ struct ValidationEntry | |||
191 | const void *addr; | 175 | const void *addr; |
192 | 176 | ||
193 | /** | 177 | /** |
178 | * Public key of the peer. | ||
179 | */ | ||
180 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; | ||
181 | |||
182 | /** | ||
194 | * The identity of the peer. | 183 | * The identity of the peer. |
195 | */ | 184 | */ |
196 | struct GNUNET_PeerIdentity pid; | 185 | struct GNUNET_PeerIdentity pid; |
@@ -349,7 +338,6 @@ GST_validation_stop () | |||
349 | } | 338 | } |
350 | 339 | ||
351 | 340 | ||
352 | #if 0 | ||
353 | /** | 341 | /** |
354 | * Address validation cleanup task (record no longer needed). | 342 | * Address validation cleanup task (record no longer needed). |
355 | * | 343 | * |
@@ -374,7 +362,6 @@ timeout_hello_validation (void *cls, | |||
374 | GNUNET_free (va->transport_name); | 362 | GNUNET_free (va->transport_name); |
375 | GNUNET_free (va); | 363 | GNUNET_free (va); |
376 | } | 364 | } |
377 | #endif | ||
378 | 365 | ||
379 | 366 | ||
380 | /** | 367 | /** |
@@ -437,6 +424,7 @@ validation_entry_match (void *cls, | |||
437 | * the given address and transport. If none exists, create one (but | 424 | * the given address and transport. If none exists, create one (but |
438 | * without starting any validation). | 425 | * without starting any validation). |
439 | * | 426 | * |
427 | * @param public_key public key of the peer, NULL for unknown | ||
440 | * @param neighbour which peer we care about | 428 | * @param neighbour which peer we care about |
441 | * @param tname name of the transport plugin | 429 | * @param tname name of the transport plugin |
442 | * @param session session to look for, NULL for 'any'; otherwise | 430 | * @param session session to look for, NULL for 'any'; otherwise |
@@ -444,10 +432,12 @@ validation_entry_match (void *cls, | |||
444 | * if 'addr' matches | 432 | * if 'addr' matches |
445 | * @param addr binary address | 433 | * @param addr binary address |
446 | * @param addrlen length of addr | 434 | * @param addrlen length of addr |
447 | * @return validation entry matching the given specifications | 435 | * @return validation entry matching the given specifications, NULL |
436 | * if we don't have an existing entry and no public key was given | ||
448 | */ | 437 | */ |
449 | static struct ValidationEntry * | 438 | static struct ValidationEntry * |
450 | find_validation_entry (struct GNUNET_PeerIdentity *neighbour, | 439 | find_validation_entry (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key, |
440 | const struct GNUNET_PeerIdentity *neighbour, | ||
451 | const char *tname, | 441 | const char *tname, |
452 | const char *addr, | 442 | const char *addr, |
453 | size_t addrlen) | 443 | size_t addrlen) |
@@ -465,12 +455,15 @@ find_validation_entry (struct GNUNET_PeerIdentity *neighbour, | |||
465 | &vemc); | 455 | &vemc); |
466 | if (NULL != (ve = vemc.ve)) | 456 | if (NULL != (ve = vemc.ve)) |
467 | return ve; | 457 | return ve; |
458 | if (public_key == NULL) | ||
459 | return NULL; | ||
468 | ve = GNUNET_malloc (sizeof (struct ValidationEntry) + addrlen); | 460 | ve = GNUNET_malloc (sizeof (struct ValidationEntry) + addrlen); |
469 | ve->transport_name = GNUNET_strdup (tname); | 461 | ve->transport_name = GNUNET_strdup (tname); |
470 | ve->addr = (void*) &ve[1]; | 462 | ve->addr = (void*) &ve[1]; |
463 | ve->public_key = *public_key; | ||
471 | ve->pid = *neighbour; | 464 | ve->pid = *neighbour; |
472 | ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | 465 | ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, |
473 | UINT32_MAX); | 466 | UINT32_MAX); |
474 | memcpy (&ve[1], addr, addrlen); | 467 | memcpy (&ve[1], addr, addrlen); |
475 | ve->addrlen = addrlen; | 468 | ve->addrlen = addrlen; |
476 | GNUNET_CONTAINER_multihashmap_put (validation_map, | 469 | GNUNET_CONTAINER_multihashmap_put (validation_map, |
@@ -515,7 +508,7 @@ multicast_pong (void *cls, | |||
515 | (const char*) pong, | 508 | (const char*) pong, |
516 | ntohs (pong->header.size), | 509 | ntohs (pong->header.size), |
517 | PONG_PRIORITY, | 510 | PONG_PRIORITY, |
518 | HELLO_VERIFICATION_TIMEOUT, | 511 | HELLO_REVALIDATION_START_TIME, |
519 | NULL, | 512 | NULL, |
520 | plugin_address, | 513 | plugin_address, |
521 | plugin_address_len, | 514 | plugin_address_len, |
@@ -594,7 +587,9 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, | |||
594 | alen = ntohs (hdr->size) - sizeof (struct TransportPingMessage); | 587 | alen = ntohs (hdr->size) - sizeof (struct TransportPingMessage); |
595 | if (alen == 0) | 588 | if (alen == 0) |
596 | { | 589 | { |
597 | /* peer wants to confirm that we have an outbound connection to him */ | 590 | /* peer wants to confirm that we have an outbound connection to him; |
591 | we handle this case here even though it has nothing to do with | ||
592 | address validation (!) */ | ||
598 | if (sender_address == NULL) | 593 | if (sender_address == NULL) |
599 | { | 594 | { |
600 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 595 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
@@ -663,7 +658,8 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, | |||
663 | } | 658 | } |
664 | else | 659 | else |
665 | { | 660 | { |
666 | /* peer wants to confirm that this is one of our addresses */ | 661 | /* peer wants to confirm that this is one of our addresses, this is what is |
662 | used for address validation */ | ||
667 | addrend = memchr (addr, '\0', alen); | 663 | addrend = memchr (addr, '\0', alen); |
668 | if (NULL == addrend) | 664 | if (NULL == addrend) |
669 | { | 665 | { |
@@ -756,7 +752,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, | |||
756 | (const char*) pong, | 752 | (const char*) pong, |
757 | ntohs (pong->header.size), | 753 | ntohs (pong->header.size), |
758 | PONG_PRIORITY, | 754 | PONG_PRIORITY, |
759 | HELLO_VERIFICATION_TIMEOUT, | 755 | HELLO_REVALIDATION_START_TIME, |
760 | session, | 756 | session, |
761 | sender_address, | 757 | sender_address, |
762 | sender_address_len, | 758 | sender_address_len, |
@@ -790,31 +786,27 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, | |||
790 | 786 | ||
791 | 787 | ||
792 | /** | 788 | /** |
793 | * We've received a PONG. Check if it matches a pending PING and | 789 | * Context for the 'validate_address' function |
794 | * mark the respective address as confirmed. | ||
795 | * | ||
796 | * @param sender peer sending the PONG | ||
797 | * @param hdr the PONG | ||
798 | * @param plugin_name name of plugin that received the PONG | ||
799 | * @param sender_address address of the sender as known to the plugin, NULL | ||
800 | * if we did not initiate the connection | ||
801 | * @param sender_address_len number of bytes in sender_address | ||
802 | */ | 790 | */ |
803 | void | 791 | struct ValidateAddressContext |
804 | GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, | ||
805 | const struct GNUNET_MessageHeader *hdr, | ||
806 | const char *plugin_name, | ||
807 | const void *sender_address, | ||
808 | size_t sender_address_len) | ||
809 | { | 792 | { |
810 | } | 793 | /** |
794 | * Hash of the public key of the peer whose address is being validated. | ||
795 | */ | ||
796 | struct GNUNET_PeerIdentity pid; | ||
797 | |||
798 | /** | ||
799 | * Public key of the peer whose address is being validated. | ||
800 | */ | ||
801 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; | ||
802 | }; | ||
811 | 803 | ||
812 | 804 | ||
813 | /** | 805 | /** |
814 | * Iterator callback to go over all addresses and try to validate them | 806 | * Iterator callback to go over all addresses and try to validate them |
815 | * (unless blocked or already validated). | 807 | * (unless blocked or already validated). |
816 | * | 808 | * |
817 | * @param cls pointer to the 'struct PeerIdentity' of the peer | 809 | * @param cls pointer to a 'struct ValidateAddressContext' |
818 | * @param tname name of the transport | 810 | * @param tname name of the transport |
819 | * @param expiration expiration time | 811 | * @param expiration expiration time |
820 | * @param addr the address | 812 | * @param addr the address |
@@ -828,7 +820,8 @@ validate_address (void *cls, | |||
828 | const void *addr, | 820 | const void *addr, |
829 | uint16_t addrlen) | 821 | uint16_t addrlen) |
830 | { | 822 | { |
831 | struct GNUNET_PeerIdentity *pid = cls; | 823 | const struct ValidateAddressContext *vac = cls; |
824 | const struct GNUNET_PeerIdentity *pid = &vac->pid; | ||
832 | struct ValidationEntry *ve; | 825 | struct ValidationEntry *ve; |
833 | struct TransportPingMessage ping; | 826 | struct TransportPingMessage ping; |
834 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | 827 | struct GNUNET_TRANSPORT_PluginFunctions *papi; |
@@ -838,13 +831,18 @@ validate_address (void *cls, | |||
838 | 831 | ||
839 | if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) | 832 | if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) |
840 | return GNUNET_OK; /* expired */ | 833 | return GNUNET_OK; /* expired */ |
841 | ve = find_validation_entry (pid, tname, addr, addrlen); | 834 | ve = find_validation_entry (&vac->public_key, pid, tname, addr, addrlen); |
842 | if (GNUNET_TIME_absolute_get_remaining (ve->validation_block).rel_value > 0) | 835 | if (GNUNET_TIME_absolute_get_remaining (ve->validation_block).rel_value > 0) |
843 | return GNUNET_OK; /* blocked */ | 836 | return GNUNET_OK; /* blocked */ |
844 | if (GNUNET_TIME_absolute_get_remaining (ve->valid_until).rel_value > 0) | 837 | if ( (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) && |
845 | return GNUNET_OK; /* valid */ | 838 | (GNUNET_TIME_absolute_get_remaining (ve->valid_until).rel_value > 0) ) |
846 | ve->validation_block = GNUNET_TIME_relative_to_absolute (MAX_REVALIDATION_FREQUENCY); | 839 | return GNUNET_OK; /* revalidation task already scheduled & still valid */ |
847 | 840 | ve->validation_block = GNUNET_TIME_relative_to_absolute (HELLO_REVALIDATION_START_TIME); | |
841 | if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) | ||
842 | GNUNET_SCHEDULER_cancel (ve->timeout_task); | ||
843 | ve->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_REVALIDATION_START_TIME, | ||
844 | &timeout_hello_validation, | ||
845 | ve); | ||
848 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 846 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
849 | "Transmitting plain PING to `%s'\n", | 847 | "Transmitting plain PING to `%s'\n", |
850 | GNUNET_i2s (pid)); | 848 | GNUNET_i2s (pid)); |
@@ -874,7 +872,7 @@ validate_address (void *cls, | |||
874 | message_buf, | 872 | message_buf, |
875 | tsize, | 873 | tsize, |
876 | PING_PRIORITY, | 874 | PING_PRIORITY, |
877 | HELLO_VERIFICATION_TIMEOUT, | 875 | HELLO_REVALIDATION_START_TIME, |
878 | NULL /* no session */, | 876 | NULL /* no session */, |
879 | ve->addr, | 877 | ve->addr, |
880 | ve->addrlen, | 878 | ve->addrlen, |
@@ -894,6 +892,192 @@ validate_address (void *cls, | |||
894 | 892 | ||
895 | 893 | ||
896 | /** | 894 | /** |
895 | * Do address validation again to keep address valid. | ||
896 | * | ||
897 | * @param cls the 'struct ValidationEntry' | ||
898 | * @param tc scheduler context (unused) | ||
899 | */ | ||
900 | static void | ||
901 | revalidate_address (void *cls, | ||
902 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
903 | { | ||
904 | struct ValidationEntry *ve = cls; | ||
905 | struct GNUNET_TIME_Relative delay; | ||
906 | struct ValidateAddressContext vac; | ||
907 | |||
908 | ve->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
909 | delay = GNUNET_TIME_absolute_get_remaining (ve->validation_block); | ||
910 | if (delay.rel_value > 0) | ||
911 | { | ||
912 | /* should wait a bit longer */ | ||
913 | ve->timeout_task = GNUNET_SCHEDULER_add_delayed (delay, | ||
914 | &revalidate_address, | ||
915 | ve); | ||
916 | return; | ||
917 | } | ||
918 | GNUNET_STATISTICS_update (GST_stats, | ||
919 | gettext_noop ("# address revalidations started"), | ||
920 | 1, | ||
921 | GNUNET_NO); | ||
922 | vac.pid = ve->pid; | ||
923 | vac.public_key = ve->public_key; | ||
924 | validate_address (&vac, | ||
925 | ve->transport_name, | ||
926 | ve->valid_until, | ||
927 | ve->addr, | ||
928 | (uint16_t) ve->addrlen); | ||
929 | } | ||
930 | |||
931 | |||
932 | /** | ||
933 | * Add the validated peer address to the HELLO. | ||
934 | * | ||
935 | * @param cls the 'struct ValidationEntry' with the validated address | ||
936 | * @param max space in buf | ||
937 | * @param buf where to add the address | ||
938 | */ | ||
939 | static size_t | ||
940 | add_valid_peer_address (void *cls, | ||
941 | size_t max, | ||
942 | void *buf) | ||
943 | { | ||
944 | struct ValidationEntry *ve = cls; | ||
945 | |||
946 | return GNUNET_HELLO_add_address (ve->transport_name, | ||
947 | ve->valid_until, | ||
948 | ve->addr, | ||
949 | ve->addrlen, | ||
950 | buf, | ||
951 | max); | ||
952 | } | ||
953 | |||
954 | |||
955 | /** | ||
956 | * We've received a PONG. Check if it matches a pending PING and | ||
957 | * mark the respective address as confirmed. | ||
958 | * | ||
959 | * @param sender peer sending the PONG | ||
960 | * @param hdr the PONG | ||
961 | * @param plugin_name name of plugin that received the PONG | ||
962 | * @param sender_address address of the sender as known to the plugin, NULL | ||
963 | * if we did not initiate the connection | ||
964 | * @param sender_address_len number of bytes in sender_address | ||
965 | */ | ||
966 | void | ||
967 | GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, | ||
968 | const struct GNUNET_MessageHeader *hdr, | ||
969 | const char *plugin_name, | ||
970 | const void *sender_address, | ||
971 | size_t sender_address_len) | ||
972 | { | ||
973 | const struct TransportPongMessage *pong; | ||
974 | struct ValidationEntry *ve; | ||
975 | const char *addr; | ||
976 | const char *addrend; | ||
977 | size_t alen; | ||
978 | size_t slen; | ||
979 | uint32_t rdelay; | ||
980 | struct GNUNET_TIME_Relative delay; | ||
981 | struct GNUNET_HELLO_Message *hello; | ||
982 | |||
983 | if (ntohs (hdr->size) < sizeof (struct TransportPongMessage)) | ||
984 | { | ||
985 | GNUNET_break_op (0); | ||
986 | return; | ||
987 | } | ||
988 | GNUNET_STATISTICS_update (GST_stats, | ||
989 | gettext_noop ("# PONG messages received"), | ||
990 | 1, | ||
991 | GNUNET_NO); | ||
992 | pong = (const struct TransportPongMessage *) hdr; | ||
993 | if (0 != memcmp (&pong->pid, | ||
994 | sender, | ||
995 | sizeof (struct GNUNET_PeerIdentity))) | ||
996 | { | ||
997 | /* PONG is validating inbound session, not an address, not the case | ||
998 | used for address validation, ignore here! */ | ||
999 | return; | ||
1000 | } | ||
1001 | #if DEBUG_TRANSPORT | ||
1002 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | ||
1003 | "Processing `%s' from `%s'\n", | ||
1004 | "PONG", | ||
1005 | (sender_address != NULL) | ||
1006 | ? GST_plugin_a2s (plugin_name, | ||
1007 | sender_address, | ||
1008 | sender_address_len) | ||
1009 | : "<inbound>"); | ||
1010 | #endif | ||
1011 | addr = (const char*) &pong[1]; | ||
1012 | alen = ntohs (hdr->size) - sizeof (struct TransportPongMessage); | ||
1013 | addrend = memchr (addr, '\0', alen); | ||
1014 | if (NULL == addrend) | ||
1015 | { | ||
1016 | GNUNET_break_op (0); | ||
1017 | return; | ||
1018 | } | ||
1019 | addrend++; | ||
1020 | slen = strlen(addr); | ||
1021 | alen -= slen; | ||
1022 | ve = find_validation_entry (NULL, | ||
1023 | sender, | ||
1024 | addr, | ||
1025 | addrend, | ||
1026 | alen); | ||
1027 | if (NULL == ve) | ||
1028 | { | ||
1029 | GNUNET_STATISTICS_update (GST_stats, | ||
1030 | gettext_noop ("# PONGs dropped, no matching pending validation"), | ||
1031 | 1, | ||
1032 | GNUNET_NO); | ||
1033 | return; | ||
1034 | } | ||
1035 | /* now check that PONG is well-formed */ | ||
1036 | if (GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0) | ||
1037 | { | ||
1038 | GNUNET_STATISTICS_update (GST_stats, | ||
1039 | gettext_noop ("# PONGs dropped, signature expired"), | ||
1040 | 1, | ||
1041 | GNUNET_NO); | ||
1042 | return; | ||
1043 | } | ||
1044 | if (GNUNET_OK != | ||
1045 | GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, | ||
1046 | &pong->purpose, | ||
1047 | &pong->signature, | ||
1048 | &ve->public_key)) | ||
1049 | { | ||
1050 | GNUNET_break_op (0); | ||
1051 | return; | ||
1052 | } | ||
1053 | |||
1054 | /* validity achieved, remember it! */ | ||
1055 | ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); | ||
1056 | |||
1057 | /* build HELLO to store in PEERINFO */ | ||
1058 | hello = GNUNET_HELLO_create (&ve->public_key, | ||
1059 | &add_valid_peer_address, | ||
1060 | ve); | ||
1061 | GNUNET_PEERINFO_add_peer (GST_peerinfo, | ||
1062 | hello); | ||
1063 | GNUNET_free (hello); | ||
1064 | |||
1065 | if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) | ||
1066 | GNUNET_SCHEDULER_cancel (ve->timeout_task); | ||
1067 | |||
1068 | /* randomly delay by up to 1h to avoid synchronous validations */ | ||
1069 | rdelay = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1070 | 60 * 60); | ||
1071 | delay = GNUNET_TIME_relative_add (HELLO_REVALIDATION_START_TIME, | ||
1072 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | ||
1073 | rdelay)); | ||
1074 | ve->timeout_task = GNUNET_SCHEDULER_add_delayed (delay, | ||
1075 | &revalidate_address, | ||
1076 | ve); | ||
1077 | } | ||
1078 | |||
1079 | |||
1080 | /** | ||
897 | * We've received a HELLO, check which addresses are new and trigger | 1081 | * We've received a HELLO, check which addresses are new and trigger |
898 | * validation. | 1082 | * validation. |
899 | * | 1083 | * |
@@ -903,10 +1087,12 @@ void | |||
903 | GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) | 1087 | GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) |
904 | { | 1088 | { |
905 | const struct GNUNET_HELLO_Message* hm = (const struct GNUNET_HELLO_Message*) hello; | 1089 | const struct GNUNET_HELLO_Message* hm = (const struct GNUNET_HELLO_Message*) hello; |
906 | struct GNUNET_PeerIdentity pid; | 1090 | struct ValidateAddressContext vac; |
907 | 1091 | ||
908 | if (GNUNET_OK != | 1092 | if ( (GNUNET_OK != |
909 | GNUNET_HELLO_get_id (hm, &pid)) | 1093 | GNUNET_HELLO_get_id (hm, &vac.pid)) || |
1094 | (GNUNET_OK != | ||
1095 | GNUNET_HELLO_get_key (hm, &vac.public_key)) ) | ||
910 | { | 1096 | { |
911 | /* malformed HELLO */ | 1097 | /* malformed HELLO */ |
912 | GNUNET_break (0); | 1098 | GNUNET_break (0); |
@@ -916,7 +1102,7 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) | |||
916 | GNUNET_HELLO_iterate_addresses (hm, | 1102 | GNUNET_HELLO_iterate_addresses (hm, |
917 | GNUNET_NO, | 1103 | GNUNET_NO, |
918 | &validate_address, | 1104 | &validate_address, |
919 | &pid)); | 1105 | &vac)); |
920 | } | 1106 | } |
921 | 1107 | ||
922 | 1108 | ||