14 #define CONSDIFFMGR_PRIVATE
38 #define LABEL_DOCTYPE "document-type"
41 #define LABEL_VALID_AFTER "consensus-valid-after"
44 #define LABEL_FRESH_UNTIL "consensus-fresh-until"
47 #define LABEL_VALID_UNTIL "consensus-valid-until"
50 #define LABEL_SIGNATORIES "consensus-signatories"
52 #define LABEL_SHA3_DIGEST "sha3-digest"
54 #define LABEL_SHA3_DIGEST_UNCOMPRESSED "sha3-digest-uncompressed"
56 #define LABEL_SHA3_DIGEST_AS_SIGNED "sha3-digest-as-signed"
58 #define LABEL_FLAVOR "consensus-flavor"
60 #define LABEL_FROM_SHA3_DIGEST "from-sha3-digest"
62 #define LABEL_TARGET_SHA3_DIGEST "target-sha3-digest"
64 #define LABEL_FROM_VALID_AFTER "from-valid-after"
66 #define LABEL_COMPRESSION_TYPE "compression"
69 #define DOCTYPE_CONSENSUS "consensus"
70 #define DOCTYPE_CONSENSUS_DIFF "consensus-diff"
92 CDM_DIFF_IN_PROGRESS=2,
145 #define RETAIN_CONSENSUS_COMPRESSED_WITH_METHOD ZLIB_METHOD
149 static consensus_cache_entry_handle_t *
174 consensus_cache_entry_handle_t *entry;
185 # define CACHE_MAX_NUM 64
187 # define CACHE_MAX_NUM 128
202 size_t consensus_len,
220 return (
unsigned) siphash24g(tmp,
sizeof(tmp));
227 diff1->flavor == diff2->flavor &&
228 diff1->compress_method == diff2->compress_method;
235 #define cdm_diff_free(diff) \
236 FREE_AND_NULL(cdm_diff_t, cdm_diff_free_, (diff))
244 consensus_cache_entry_handle_free(diff->entry);
252 const uint8_t *from_sha3,
253 const uint8_t *target_sha3,
261 ent->compress_method = method;
275 const uint8_t *from_sha3,
276 const uint8_t *target_sha3)
284 search.flavor = flav;
285 search.compress_method = method;
287 ent = HT_FIND(cdm_diff_ht, &cdm_diff_ht, &search);
289 tor_assert_nonfatal(ent->cdm_diff_status != CDM_DIFF_PRESENT);
293 ent =
cdm_diff_new(flav, from_sha3, target_sha3, method);
294 ent->cdm_diff_status = CDM_DIFF_IN_PROGRESS;
295 HT_INSERT(cdm_diff_ht, &cdm_diff_ht, ent);
308 const uint8_t *from_sha3,
309 const uint8_t *to_sha3,
312 consensus_cache_entry_handle_t *handle)
314 if (handle == NULL) {
315 tor_assert_nonfatal(status != CDM_DIFF_PRESENT);
320 search.flavor = flav;
321 search.compress_method = method,
323 ent = HT_FIND(cdm_diff_ht, &cdm_diff_ht, &search);
326 ent->cdm_diff_status = CDM_DIFF_IN_PROGRESS;
327 HT_INSERT(cdm_diff_ht, &cdm_diff_ht, ent);
335 tor_assert_nonfatal(ent->cdm_diff_status == CDM_DIFF_IN_PROGRESS);
337 ent->cdm_diff_status = status;
338 consensus_cache_entry_handle_free(ent->entry);
352 const uint8_t *unless_target_sha3_matches)
355 for (diff = HT_START(cdm_diff_ht, &cdm_diff_ht); diff; diff = next) {
358 if ((*diff)->cdm_diff_status == CDM_DIFF_PRESENT &&
359 flav == (*diff)->flavor) {
361 if (BUG((*diff)->entry == NULL) ||
362 consensus_cache_entry_handle_get((*diff)->entry) == NULL) {
364 next = HT_NEXT_RMV(cdm_diff_ht, &cdm_diff_ht, diff);
369 if (unless_target_sha3_matches &&
370 fast_memneq(unless_target_sha3_matches, (*diff)->target_sha3,
373 next = HT_NEXT_RMV(cdm_diff_ht, &cdm_diff_ht, diff);
378 next = HT_NEXT(cdm_diff_ht, &cdm_diff_ht, diff);
388 unsigned n_entries = consdiff_cfg.cache_max_num * 2;
394 log_err(
LD_FS,
"Error: Couldn't open storage for consensus diffs.");
395 tor_assert_unreached();
433 (
const char *)body, bodylen, DIGEST_SHA3_256);
435 (
const char *)sha3_digest,
sizeof(sha3_digest));
471 char formatted_time[ISO_TIME_LEN+1];
481 LABEL_VALID_AFTER, formatted_time);
486 if (smartlist_len(matches)) {
487 result = smartlist_get(matches, 0);
489 smartlist_free(matches);
500 const int32_t DEFAULT_MAX_AGE_TO_CACHE = 8192;
501 const int32_t MIN_MAX_AGE_TO_CACHE = 0;
502 const int32_t MAX_MAX_AGE_TO_CACHE = 8192;
503 const char MAX_AGE_TO_CACHE_NAME[] =
"max-consensus-age-to-cache-for-diff";
509 if (v >= MAX_MAX_AGE_TO_CACHE * 3600)
510 return MAX_MAX_AGE_TO_CACHE;
517 MAX_AGE_TO_CACHE_NAME,
518 DEFAULT_MAX_AGE_TO_CACHE,
519 MIN_MAX_AGE_TO_CACHE,
520 MAX_MAX_AGE_TO_CACHE);
523 #ifdef TOR_UNIT_TESTS
527 consdiffmgr_add_consensus_nulterm(
const char *consensus,
530 size_t len = strlen(consensus);
533 char *ctmp = tor_memdup(consensus, len);
550 size_t consensus_len,
553 if (BUG(consensus == NULL) || BUG(as_parsed == NULL))
555 if (BUG(as_parsed->
type != NS_TYPE_CONSENSUS))
562 log_info(
LD_DIRSERV,
"We don't care about this consensus document; it's "
571 log_info(
LD_DIRSERV,
"We already have a copy of that consensus");
602 if (smartlist_len(lst)) {
603 return smartlist_get(lst, smartlist_len(lst) - 1);
639 return CONSDIFF_NOT_FOUND;
643 return CONSDIFF_NOT_FOUND;
644 *entry_out = consensus_cache_entry_handle_get(handle);
646 return CONSDIFF_AVAILABLE;
648 return CONSDIFF_NOT_FOUND;
663 const uint8_t *digest,
667 if (BUG(digest_type != DIGEST_SHA3_256) ||
669 return CONSDIFF_NOT_FOUND;
674 memset(&search, 0,
sizeof(search));
675 search.flavor = flavor;
676 search.compress_method = method;
678 ent = HT_FIND(cdm_diff_ht, &cdm_diff_ht, &search);
681 ent->cdm_diff_status == CDM_DIFF_ERROR) {
682 return CONSDIFF_NOT_FOUND;
683 }
else if (ent->cdm_diff_status == CDM_DIFF_IN_PROGRESS) {
684 return CONSDIFF_IN_PROGRESS;
685 }
else if (BUG(ent->cdm_diff_status != CDM_DIFF_PRESENT)) {
686 return CONSDIFF_IN_PROGRESS;
689 if (BUG(ent->entry == NULL)) {
690 return CONSDIFF_NOT_FOUND;
692 *entry_out = consensus_cache_entry_handle_get(ent->entry);
693 return (*entry_out) ? CONSDIFF_AVAILABLE : CONSDIFF_NOT_FOUND;
699 base16_encode(hex,
sizeof(hex), (
const char *)digest, digestlen);
704 LABEL_FROM_SHA3_DIGEST, hex);
710 (*entry_out) ? CONSDIFF_AVAILABLE : CONSDIFF_NOT_FOUND;
711 smartlist_free(matches);
729 log_debug(
LD_DIRSERV,
"Looking for consdiffmgr entries to remove");
737 const char *lv_valid_after =
739 if (! lv_valid_after) {
740 log_debug(
LD_DIRSERV,
"Ignoring entry because it had no %s label",
744 time_t valid_after = 0;
746 log_debug(
LD_DIRSERV,
"Ignoring entry because its %s value (%s) was "
747 "unparseable", LABEL_VALID_AFTER,
escaped(lv_valid_after));
750 if (valid_after < valid_after_cutoff) {
751 log_debug(
LD_DIRSERV,
"Deleting entry because its %s value (%s) was "
752 "too old", LABEL_VALID_AFTER, lv_valid_after);
756 } SMARTLIST_FOREACH_END(ent);
768 if (most_recent == NULL)
770 const char *most_recent_sha3 =
772 LABEL_SHA3_DIGEST_UNCOMPRESSED);
773 if (BUG(most_recent_sha3 == NULL))
781 const char *this_diff_target_sha3 =
783 if (!this_diff_target_sha3)
785 if (strcmp(this_diff_target_sha3, most_recent_sha3)) {
789 } SMARTLIST_FOREACH_END(diff);
804 if (most_recent == NULL)
806 const char *most_recent_sha3_uncompressed =
808 LABEL_SHA3_DIGEST_UNCOMPRESSED);
812 if (BUG(most_recent_sha3_uncompressed == NULL))
815 const char *lv_sha3_uncompressed =
817 if (BUG(! lv_sha3_uncompressed))
819 if (!strcmp(lv_sha3_uncompressed, most_recent_sha3_uncompressed))
821 const char *lv_methodname =
823 if (! lv_methodname || strcmp(lv_methodname, retain_methodname)) {
827 } SMARTLIST_FOREACH_END(ent);
830 smartlist_free(objects);
831 smartlist_free(consensuses);
832 smartlist_free(diffs);
847 memcpy(&consdiff_cfg, cfg,
sizeof(consdiff_cfg));
883 }
else if (r == -2) {
911 } SMARTLIST_FOREACH_END(obj);
912 smartlist_free(objects);
925 strmap_t *have_diff_from = NULL;
938 LABEL_FLAVOR, flavname);
943 log_info(
LD_DIRSERV,
"No 'most recent' %s consensus found; "
944 "not making diffs", flavname);
950 const char *most_recent_valid_after =
952 if (BUG(most_recent_valid_after == NULL))
956 LABEL_SHA3_DIGEST_UNCOMPRESSED) < 0))
963 LABEL_VALID_AFTER, most_recent_valid_after);
966 have_diff_from = strmap_new();
969 LABEL_FROM_VALID_AFTER);
972 strmap_set(have_diff_from, va, diff);
973 } SMARTLIST_FOREACH_END(diff);
982 if (strmap_get(have_diff_from, va) != NULL)
989 } SMARTLIST_FOREACH_END(ent);
992 "The most recent %s consensus is valid-after %s. We have diffs to "
993 "this consensus for %d/%d older %s consensuses. Generating diffs "
996 most_recent_valid_after,
997 smartlist_len(matches) - smartlist_len(compute_diffs_from),
998 smartlist_len(matches),
1000 smartlist_len(compute_diffs_from));
1008 if (BUG(c == most_recent))
1013 LABEL_SHA3_DIGEST_AS_SIGNED)<0) {
1019 this_sha3, most_recent_sha3)) {
1024 } SMARTLIST_FOREACH_END(c);
1027 smartlist_free(matches);
1028 smartlist_free(diffs);
1029 smartlist_free(compute_diffs_from);
1030 strmap_free(have_diff_from, NULL);
1045 LABEL_FLAVOR, flavname);
1050 const char *most_recent_sha3 =
1052 LABEL_SHA3_DIGEST_UNCOMPRESSED);
1053 if (BUG(most_recent_sha3 == NULL))
1061 const char *lv_compression =
1070 } SMARTLIST_FOREACH_END(ent);
1072 smartlist_free(matches);
1085 const char *lv_flavor =
1092 const char *lv_compression =
1095 if (lv_compression) {
1097 if (method == UNKNOWN_METHOD) {
1112 consensus_cache_entry_handle_new(diff));
1113 } SMARTLIST_FOREACH_END(diff);
1114 smartlist_free(diffs);
1172 const char *va1, *fva1, *va2, *fva2;
1213 if (n_to_remove <= 0) {
1226 if (++n_marked >= n_to_remove)
1228 } SMARTLIST_FOREACH_END(ent);
1229 smartlist_free(objects);
1240 if (BUG(n_marked < n_to_remove))
1259 } SMARTLIST_FOREACH_END(ent);
1260 smartlist_free(objects);
1270 for (diff = HT_START(cdm_diff_ht, &cdm_diff_ht); diff; diff = next) {
1272 next = HT_NEXT_RMV(cdm_diff_ht, &cdm_diff_ht, diff);
1273 cdm_diff_free(
this);
1317 const uint8_t *input,
size_t len,
1322 for (i = 0; i < n_methods; ++i) {
1327 if (0 ==
tor_compress(&result, &sz, (
const char*)input, len, method)) {
1328 results_out[i].
body = (uint8_t*)result;
1332 results_out[i].body,
1333 results_out[i].bodylen);
1335 LABEL_COMPRESSION_TYPE,
1358 const char *description)
1364 for (i = 0; i < n; ++i) {
1366 uint8_t *body_out = results[i].
body;
1367 size_t bodylen_out = results[i].
bodylen;
1370 if (body_out && bodylen_out && labels) {
1372 log_info(
LD_DIRSERV,
"Adding %s, compressed with %s",
1373 description, methodname);
1381 static ratelim_t cant_store_ratelim = RATELIM_INIT(5*60);
1383 "Unable to store object %s compressed with %s.",
1384 description, methodname);
1388 status = CDM_DIFF_PRESENT;
1389 handles_out[i] = consensus_cache_entry_handle_new(ent);
1429 const uint8_t *body;
1437 const char *lv_compression =
1445 if (method == NO_METHOD) {
1446 *out = (
const char *)body;
1450 rv =
tor_uncompress(owned_out, outlen, (
const char *)body, bodylen,
1466 const uint8_t *diff_from, *diff_to;
1467 size_t len_from, len_to;
1473 return WQ_RPL_REPLY;
1476 return WQ_RPL_REPLY;
1478 const char *lv_to_valid_after =
1480 const char *lv_to_fresh_until =
1482 const char *lv_to_valid_until =
1484 const char *lv_to_signatories =
1486 const char *lv_from_valid_after =
1488 const char *lv_from_digest =
1490 LABEL_SHA3_DIGEST_AS_SIGNED);
1491 const char *lv_from_flavor =
1493 const char *lv_to_flavor =
1495 const char *lv_to_digest =
1497 LABEL_SHA3_DIGEST_UNCOMPRESSED);
1499 if (! lv_from_digest) {
1504 return WQ_RPL_REPLY;
1508 if (BUG(!lv_to_valid_after) ||
1509 BUG(!lv_from_valid_after) ||
1510 BUG(!lv_from_flavor) ||
1511 BUG(!lv_to_flavor)) {
1512 return WQ_RPL_REPLY;
1515 if (BUG(strcmp(lv_from_flavor, lv_to_flavor))) {
1516 return WQ_RPL_REPLY;
1519 char *consensus_diff;
1521 const char *diff_from_nt = NULL, *diff_to_nt = NULL;
1522 char *owned1 = NULL, *owned2 = NULL;
1523 size_t diff_from_nt_len, diff_to_nt_len;
1527 return WQ_RPL_REPLY;
1532 return WQ_RPL_REPLY;
1547 if (!consensus_diff) {
1549 return WQ_RPL_REPLY;
1554 size_t difflen = strlen(consensus_diff);
1555 job->
out[0].
body = (uint8_t *) consensus_diff;
1559 if (lv_to_valid_until)
1561 if (lv_to_fresh_until)
1563 if (lv_to_signatories)
1566 LABEL_SHA3_DIGEST_UNCOMPRESSED,
1570 lv_from_valid_after);
1579 DOCTYPE_CONSENSUS_DIFF);
1590 (
const uint8_t*)consensus_diff, difflen, common_labels);
1592 config_free_lines(common_labels);
1593 return WQ_RPL_REPLY;
1596 #define consensus_diff_worker_job_free(job) \
1597 FREE_AND_NULL(consensus_diff_worker_job_t, \
1598 consensus_diff_worker_job_free_, (job))
1610 config_free_lines(job->
out[u].labels);
1631 const char *lv_from_digest =
1633 LABEL_SHA3_DIGEST_AS_SIGNED);
1634 const char *lv_to_digest =
1636 LABEL_SHA3_DIGEST_UNCOMPRESSED);
1637 const char *lv_flavor =
1639 if (BUG(lv_from_digest == NULL))
1640 lv_from_digest =
"???";
1641 if (BUG(lv_to_digest == NULL))
1642 lv_to_digest =
"???";
1649 LABEL_SHA3_DIGEST_AS_SIGNED) < 0))
1652 LABEL_SHA3_DIGEST_UNCOMPRESSED) < 0))
1654 if (BUG(lv_flavor == NULL)) {
1661 memset(handles, 0,
sizeof(handles));
1663 char description[128];
1665 "consensus diff from %s to %s",
1666 lv_from_digest, lv_to_digest);
1674 if (status != CDM_DIFF_PRESENT) {
1677 "Worker was unable to compute consensus diff "
1678 "from %s to %s", lv_from_digest, lv_to_digest);
1680 status = CDM_DIFF_ERROR;
1687 consensus_cache_entry_handle_t *h = handles[u];
1688 int this_status = status;
1690 this_status = CDM_DIFF_ERROR;
1692 tor_assert_nonfatal(h != NULL || this_status == CDM_DIFF_ERROR);
1695 consensus_cache_entry_handle_free(handles[u]);
1699 consensus_diff_worker_job_free(job);
1720 const uint8_t *body;
1724 if (r1 < 0 || r2 < 0)
1737 consensus_diff_worker_job_free(job);
1746 size_t consensus_len;
1752 #define consensus_compress_worker_job_free(job) \
1753 FREE_AND_NULL(consensus_compress_worker_job_t, \
1754 consensus_compress_worker_job_free_, (job))
1765 config_free_lines(job->labels_in);
1768 config_free_lines(job->out[u].labels);
1783 const char *consensus = job->consensus;
1784 size_t bodylen = job->consensus_len;
1790 (
const uint8_t *)consensus, bodylen);
1792 const char *start, *end;
1794 &start, &end) < 0) {
1796 end = consensus+bodylen;
1799 (
const uint8_t *)start,
1808 (
const uint8_t*)consensus, bodylen, labels);
1809 config_free_lines(labels);
1810 return WQ_RPL_REPLY;
1823 consensus_cache_entry_handle_t *handles[
1825 memset(handles, 0,
sizeof(handles));
1838 if (handles[u] == NULL)
1844 consensus_compress_worker_job_free(job);
1858 size_t consensus_len,
1865 job->consensus = tor_memdup_nulterm(consensus, consensus_len);
1866 job->consensus_len = strlen(job->consensus);
1867 job->flavor = as_parsed->
flavor;
1869 char va_str[ISO_TIME_LEN+1];
1870 char vu_str[ISO_TIME_LEN+1];
1871 char fu_str[ISO_TIME_LEN+1];
1882 if (smartlist_len(vi->sigs) == 0)
1887 } SMARTLIST_FOREACH_END(vi);
1892 smartlist_free(hexvoters);
1902 consensus_compress_worker_job_free(job);
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
mainloop_event_t * mainloop_event_postloop_new(void(*cb)(mainloop_event_t *, void *), void *userdata)
void mainloop_event_activate(mainloop_event_t *event)
Header for compat_libevent.c.
compress_method_t compression_method_get_by_name(const char *name)
const char * compression_method_get_name(compress_method_t method)
int tor_compress(char **out, size_t *out_len, const char *in, size_t in_len, compress_method_t method)
int tor_uncompress(char **out, size_t *out_len, const char *in, size_t in_len, compress_method_t method, int complete_only, int protocol_warn_level)
const or_options_t * get_options(void)
Header file for config.c.
void config_line_prepend(config_line_t **lst, const char *key, const char *val)
config_line_t * config_lines_dup(const config_line_t *inp)
void config_line_append(config_line_t **lst, const char *key, const char *val)
void consensus_cache_entry_incref(consensus_cache_entry_t *ent)
consensus_cache_entry_t * consensus_cache_add(consensus_cache_t *cache, const config_line_t *labels, const uint8_t *data, size_t datalen)
void consensus_cache_find_all(smartlist_t *out, consensus_cache_t *cache, const char *key, const char *value)
void consensus_cache_delete_pending(consensus_cache_t *cache, int force)
void consensus_cache_entry_mark_for_aggressive_release(consensus_cache_entry_t *ent)
int consensus_cache_get_n_filenames_available(consensus_cache_t *cache)
const char * consensus_cache_entry_get_value(const consensus_cache_entry_t *ent, const char *key)
int consensus_cache_may_overallocate(consensus_cache_t *cache)
int consensus_cache_register_with_sandbox(consensus_cache_t *cache, struct sandbox_cfg_elem_t **cfg)
void consensus_cache_filter_list(smartlist_t *lst, const char *key, const char *value)
void consensus_cache_entry_mark_for_removal(consensus_cache_entry_t *ent)
void consensus_cache_entry_decref(consensus_cache_entry_t *ent)
int consensus_cache_entry_get_body(const consensus_cache_entry_t *ent, const uint8_t **body_out, size_t *sz_out)
consensus_cache_t * consensus_cache_open(const char *subdir, int max_entries)
char * consensus_diff_generate(const char *cons1, size_t cons1len, const char *cons2, size_t cons2len)
int consensus_cache_entry_get_valid_until(const consensus_cache_entry_t *ent, time_t *out)
static void consdiffmgr_consensus_load(void)
static cdm_diff_t * cdm_diff_new(consensus_flavor_t flav, const uint8_t *from_sha3, const uint8_t *target_sha3, compress_method_t method)
static cdm_diff_status_t store_multiple(consensus_cache_entry_handle_t **handles_out, int n, const compress_method_t *methods, const compressed_result_t *results, const char *description)
#define RETAIN_CONSENSUS_COMPRESSED_WITH_METHOD
int consensus_cache_entry_get_fresh_until(const consensus_cache_entry_t *ent, time_t *out)
consdiff_status_t consdiffmgr_find_diff_from(consensus_cache_entry_t **entry_out, consensus_flavor_t flavor, int digest_type, const uint8_t *digest, size_t digestlen, compress_method_t method)
void consdiffmgr_enable_background_compression(void)
void consdiffmgr_configure(const consdiff_cfg_t *cfg)
static HT_HEAD(cdm_diff_ht, cdm_diff_t)
int consdiffmgr_validate(void)
static void cdm_cache_init(void)
static void consdiffmgr_diffs_load(void)
static void cdm_diff_ht_set_status(consensus_flavor_t flav, const uint8_t *from_sha3, const uint8_t *to_sha3, compress_method_t method, int status, consensus_cache_entry_handle_t *handle)
STATIC consensus_cache_t * cdm_cache_get(void)
static int consensus_compression_method_pos(compress_method_t method)
static void consdiffmgr_rescan_cb(mainloop_event_t *ev, void *arg)
STATIC int cdm_entry_get_sha3_value(uint8_t *digest_out, consensus_cache_entry_t *ent, const char *label)
static const compress_method_t compress_consensus_with[]
static const compress_method_t compress_diffs_with[]
static void cdm_diff_ht_purge(consensus_flavor_t flav, const uint8_t *unless_target_sha3_matches)
static workqueue_reply_t consensus_compress_worker_threadfn(void *state_, void *work_)
static int cdm_cache_dirty
int consdiffmgr_cleanup(void)
static void consdiffmgr_rescan_flavor_(consensus_flavor_t flavor)
STATIC int uncompress_or_set_ptr(const char **out, size_t *outlen, char **owned_out, consensus_cache_entry_t *ent)
STATIC unsigned n_consensus_compression_methods(void)
static consensus_cache_t * cons_diff_cache
static int cdm_diff_eq(const cdm_diff_t *diff1, const cdm_diff_t *diff2)
static void consdiffmgr_set_cache_flags(void)
int consensus_cache_entry_get_voter_id_digests(const consensus_cache_entry_t *ent, smartlist_t *out)
static int compare_by_valid_after_(const void **a, const void **b)
static unsigned cdm_diff_hash(const cdm_diff_t *diff)
static int background_compression
static int compare_by_staleness_(const void **a, const void **b)
consdiff_status_t consdiffmgr_find_consensus(struct consensus_cache_entry_t **entry_out, consensus_flavor_t flavor, compress_method_t method)
static consensus_cache_entry_t * sort_and_find_most_recent(smartlist_t *lst)
static void consensus_compress_worker_job_free_(consensus_compress_worker_job_t *job)
int consdiffmgr_add_consensus(const char *consensus, size_t consensus_len, const networkstatus_t *as_parsed)
static int consdiffmgr_ensure_space_for_files(int n)
STATIC consensus_cache_entry_t * cdm_cache_lookup_consensus(consensus_flavor_t flavor, time_t valid_after)
static mainloop_event_t * consdiffmgr_rescan_ev
STATIC unsigned n_diff_compression_methods(void)
static int cdm_cache_loaded
int consensus_cache_entry_get_valid_after(const consensus_cache_entry_t *ent, time_t *out)
void consdiffmgr_rescan(void)
static int consensus_queue_compression_work(const char *consensus, size_t consensus_len, const networkstatus_t *as_parsed)
static void consensus_diff_worker_job_free_(consensus_diff_worker_job_t *job)
void consdiffmgr_free_all(void)
static void mark_cdm_cache_dirty(void)
static void consensus_diff_worker_replyfn(void *work_)
static int compress_multiple(compressed_result_t *results_out, int n_methods, const compress_method_t *methods, const uint8_t *input, size_t len, const config_line_t *labels_in)
static int cdm_diff_ht_check_and_note_pending(consensus_flavor_t flav, const uint8_t *from_sha3, const uint8_t *target_sha3)
static int32_t get_max_age_to_cache(void)
static int consensus_diff_queue_diff_work(consensus_cache_entry_t *diff_from, consensus_cache_entry_t *diff_to)
static workqueue_reply_t consensus_diff_worker_threadfn(void *state_, void *work_)
int consdiffmgr_register_with_sandbox(struct sandbox_cfg_elem_t **cfg)
static consensus_cache_entry_handle_t * latest_consensus[N_CONSENSUS_FLAVORS][ARRAY_LENGTH(compress_consensus_with)]
static void cdm_diff_free_(cdm_diff_t *diff)
static void consensus_compress_worker_replyfn(void *work_)
static void cdm_labels_prepend_sha3(config_line_t **labels, const char *label, const uint8_t *body, size_t bodylen)
Header for consdiffmgr.c.
workqueue_entry_t * cpuworker_queue_work(workqueue_priority_t priority, workqueue_reply_t(*fn)(void *, void *), void(*reply_fn)(void *), void *arg)
Header file for cpuworker.c.
#define HEX_DIGEST256_LEN
int crypto_digest256(char *digest, const char *m, size_t len, digest_algorithm_t algorithm)
#define fast_memeq(a, b, c)
#define fast_memneq(a, b, c)
const char * escaped(const char *s)
HT_PROTOTYPE(hs_circuitmap_ht, circuit_t, hs_circuitmap_node, hs_circuit_hash_token, hs_circuits_have_same_token)
#define log_fn_ratelim(ratelim, severity, domain, args,...)
void tor_free_(void *mem)
int networkstatus_parse_flavor_name(const char *flavname)
const char * networkstatus_get_flavor_name(consensus_flavor_t flav)
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
Networkstatus consensus/vote structure.
Single consensus voter structure.
Header file for ns_parse.c.
int router_get_networkstatus_v3_signed_boundaries(const char *s, size_t len, const char **start_out, const char **end_out)
Master header file for Tor-specific functionality.
#define N_CONSENSUS_FLAVORS
int tor_snprintf(char *str, size_t size, const char *format,...)
void smartlist_reverse(smartlist_t *sl)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
smartlist_t * smartlist_new(void)
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_clear(smartlist_t *sl)
void smartlist_del(smartlist_t *sl, int idx)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
compressed_result_t out[ARRAY_LENGTH(compress_diffs_with)]
consensus_cache_entry_t * diff_from
consensus_cache_entry_t * diff_to
consensus_flavor_t flavor
networkstatus_type_t type
int MaxConsensusAgeForDiffs
void format_iso_time_nospace(char *buf, time_t t)
int parse_iso_time_nospace(const char *cp, time_t *t)
int strcmp_opt(const char *s1, const char *s2)