9 #define RENDCACHE_PRIVATE
63 STATIC size_t rend_cache_total_allocation = 0;
84 return sizeof(*e) + e->
len +
sizeof(*e->
parsed);
89 rend_cache_get_total_allocation(
void)
91 return rend_cache_total_allocation;
98 static int have_underflowed = 0;
100 if (rend_cache_total_allocation >= n) {
101 rend_cache_total_allocation -= n;
103 rend_cache_total_allocation = 0;
104 if (! have_underflowed) {
105 have_underflowed = 1;
106 log_warn(
LD_BUG,
"Underflow in rend_cache_decrement_allocation");
115 static int have_overflowed = 0;
116 if (rend_cache_total_allocation <= SIZE_MAX - n) {
117 rend_cache_total_allocation += n;
119 rend_cache_total_allocation = SIZE_MAX;
120 if (! have_overflowed) {
122 log_warn(
LD_BUG,
"Overflow in rend_cache_increment_allocation");
138 rend_cache_failure_intro_entry_free_void(
void *entry)
149 entry->failure_type = failure;
150 entry->created_ts = time(NULL);
163 digestmap_free(entry->intro_failures,
164 rend_cache_failure_intro_entry_free_void);
183 entry->intro_failures = digestmap_new();
204 rend_cache_failure_entry_free(entry);
218 rend_service_descriptor_free(e->
parsed);
234 const uint8_t *intro_identity)
254 rend_cache_total_allocation = 0;
273 if (ip_ent->created_ts < cutoff) {
274 rend_cache_failure_intro_entry_free(ip_ent);
279 if (digestmap_isempty(ent->intro_failures)) {
280 rend_cache_failure_entry_free(ent);
283 } STRMAP_FOREACH_END;
296 strmap_t *cache = NULL;
298 if (cache_type == REND_CACHE_TYPE_CLIENT) {
300 }
else if (cache_type == REND_CACHE_TYPE_SERVICE) {
305 for (iter = strmap_iter_init(cache); !strmap_iter_done(iter); ) {
306 strmap_iter_get(iter, &key, &val);
309 iter = strmap_iter_next_rmv(cache, iter);
310 rend_cache_entry_free(ent);
312 iter = strmap_iter_next(cache, iter);
323 log_info(
LD_REND,
"Purging HS v2 descriptor cache");
335 log_info(
LD_REND,
"Purging HS v2 failure cache");
364 intro_elem = digestmap_get(elem->intro_failures, (
char *) identity);
365 if (intro_elem == NULL) {
369 *intro_entry = intro_elem;
383 ent_dup->created_ts = entry->created_ts;
392 rend_intro_point_failure_t failure)
400 if (fail_entry == NULL) {
406 old_entry = digestmap_set(fail_entry->intro_failures,
407 (
char *) identity, entry);
409 rend_cache_failure_intro_entry_free(old_entry);
419 const char *service_id)
426 new_entry = tor_malloc(
sizeof(*new_entry));
427 new_entry->intro_failures = digestmap_new();
434 const uint8_t *identity =
435 (uint8_t *) intro->extend_info->identity_digest;
446 digestmap_set(new_entry->intro_failures, (
char *) identity, ent_dup);
448 rend_intro_point_free(intro);
451 } SMARTLIST_FOREACH_END(intro);
455 if (cur_entry != NULL) {
456 rend_cache_failure_entry_free(cur_entry);
467 const uint8_t *identity,
468 const char *service_id)
478 entry->failure_type = failure;
489 digestmap_iter_t *iter;
490 size_t bytes_removed = 0;
493 !digestmap_iter_done(iter); ) {
497 digestmap_iter_get(iter, &key, &val);
502 log_info(
LD_REND,
"Removing descriptor with ID '%s' from cache",
503 safe_str_client(key_base32));
506 rend_cache_entry_free(ent);
512 return bytes_removed;
528 static const int default_version = 2;
547 log_warn(
LD_REND,
"Cache lookup of a v0 renddesc is deprecated.");
552 tor_snprintf(key,
sizeof(key),
"%d%s", default_version, query);
619 "Rejecting v2 rendezvous descriptor request -- descriptor ID "
620 "has wrong length or illegal characters: %s",
655 int number_parsed = 0, number_stored = 0;
656 const char *current_desc = desc;
657 const char *next_desc;
659 time_t now = time(NULL);
663 &intro_size, &encoded_size,
664 &next_desc, current_desc, 1) >= 0) {
673 log_info(
LD_REND,
"Service descriptor with desc ID %s is too old.",
674 safe_str(desc_id_base32));
679 log_info(
LD_REND,
"Service descriptor with desc ID %s is too far in the "
681 safe_str(desc_id_base32));
687 log_info(
LD_REND,
"We already have a newer service descriptor with the "
688 "same desc ID %s and version.",
689 safe_str(desc_id_base32));
693 if (e && !strcmp(desc, e->
desc)) {
694 log_info(
LD_REND,
"We already have this service descriptor with desc "
695 "ID %s.", safe_str(desc_id_base32));
709 rend_service_descriptor_free(e->
parsed);
713 e->
desc = tor_strndup(current_desc, encoded_size);
714 e->
len = encoded_size;
716 log_info(
LD_REND,
"Successfully stored service descriptor with desc ID "
718 safe_str(desc_id_base32), (
int)encoded_size);
727 rend_service_descriptor_free(parsed);
730 current_desc = next_desc;
733 strcmpstart(current_desc,
"rendezvous-service-descriptor "))
736 if (!number_parsed) {
737 log_info(
LD_REND,
"Could not parse any descriptor.");
740 log_info(
LD_REND,
"Parsed %d and added %d descriptor%s.",
741 number_parsed, number_stored, number_stored != 1 ?
"s" :
"");
759 char *intro_content = NULL;
762 const char *next_desc;
771 &intro_size, &encoded_size,
772 &next_desc, desc, 0) < 0) {
773 log_warn(
LD_REND,
"Could not parse descriptor.");
778 log_warn(
LD_REND,
"Couldn't compute service ID.");
787 log_info(
LD_REND,
"We already have a newer service descriptor for "
788 "service ID %s.", safe_str_client(service_id));
798 rend_service_descriptor_free(e->
parsed);
802 e->
desc = tor_malloc_zero(encoded_size + 1);
803 strlcpy(e->
desc, desc, encoded_size + 1);
804 e->
len = encoded_size;
806 log_debug(
LD_REND,
"Successfully stored rend desc '%s', len %d.",
807 safe_str_client(service_id), (
int)encoded_size);
814 rend_service_descriptor_free(parsed);
837 const char *desc_id_base32,
858 char *intro_content = NULL;
861 const char *next_desc;
862 time_t now = time(NULL);
873 memset(want_desc_id, 0,
sizeof(want_desc_id));
878 desc_id_base32, strlen(desc_id_base32)) !=
879 sizeof(want_desc_id)) {
880 log_warn(
LD_BUG,
"Couldn't decode base32 %s for descriptor id.",
886 &intro_size, &encoded_size,
887 &next_desc, desc, 0) < 0) {
888 log_warn(
LD_REND,
"Could not parse descriptor.");
893 log_warn(
LD_REND,
"Couldn't compute service ID.");
898 log_warn(
LD_REND,
"Received service descriptor for service ID %s; "
899 "expected descriptor for service ID %s.",
904 log_warn(
LD_REND,
"Received service descriptor for %s with incorrect "
905 "descriptor ID.", service_id);
910 if (intro_content && intro_size > 0) {
912 if (rend_data->
auth_type != REND_NO_AUTH &&
915 char *ipos_decrypted = NULL;
916 size_t ipos_decrypted_size;
918 &ipos_decrypted_size,
922 log_warn(
LD_REND,
"Failed to decrypt introduction points. We are "
923 "probably unable to parse the encoded introduction points.");
926 log_info(
LD_REND,
"Successfully decrypted introduction points.");
928 intro_content = ipos_decrypted;
929 intro_size = ipos_decrypted_size;
934 if (n_intro_points <= 0) {
935 log_warn(
LD_REND,
"Failed to parse introduction points. Either the "
936 "service has published a corrupt descriptor or you have "
937 "provided invalid authorization data.");
939 }
else if (n_intro_points > MAX_INTRO_POINTS) {
940 log_warn(
LD_REND,
"Found too many introduction points on a hidden "
941 "service descriptor for %s. This is probably a (misguided) "
942 "attempt to improve reliability, but it could also be an "
943 "attempt to do a guard enumeration attack. Rejecting.",
944 safe_str_client(service_id));
949 log_info(
LD_REND,
"Descriptor does not contain any introduction points.");
956 log_warn(
LD_REND,
"Service descriptor with service ID %s is too old.",
957 safe_str_client(service_id));
962 log_warn(
LD_REND,
"Service descriptor with service ID %s is too far in "
963 "the future.", safe_str_client(service_id));
969 if (e && !strcmp(desc, e->
desc)) {
970 log_info(
LD_REND,
"We already have this service descriptor %s.",
971 safe_str_client(service_id));
980 log_info(
LD_REND,
"We already have a new enough service descriptor for "
981 "service ID %s with the same desc ID and version.",
982 safe_str_client(service_id));
991 log_info(
LD_REND,
"Service descriptor with service ID %s has no "
992 "usable intro points. Discarding it.",
993 safe_str_client(service_id));
1004 rend_service_descriptor_free(e->
parsed);
1008 e->
desc = tor_malloc_zero(encoded_size + 1);
1009 strlcpy(e->
desc, desc, encoded_size + 1);
1010 e->
len = encoded_size;
1012 log_debug(
LD_REND,
"Successfully stored rend desc '%s', len %d.",
1013 safe_str_client(service_id), (
int)encoded_size);
1026 rend_service_descriptor_free(parsed);