Macros | Enumerations | Functions | Variables
dirserv.c File Reference
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "feature/dircache/conscache.h"
#include "feature/dircache/consdiffmgr.h"
#include "feature/dircommon/directory.h"
#include "feature/dircache/dirserv.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/routerlist.h"
#include "feature/relay/router.h"
#include "feature/relay/routermode.h"
#include "feature/stats/predict_ports.h"
#include "feature/dircache/cached_dir_st.h"
#include "feature/dircommon/dir_connection_st.h"
#include "feature/nodelist/extrainfo_st.h"
#include "feature/nodelist/microdesc_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist_st.h"
#include "lib/compress/compress.h"

Go to the source code of this file.


#define DIRSERV_BUFFER_MIN   16384


enum  spooled_resource_flush_status_t { SRFS_ERR = -1, SRFS_MORE = 0, SRFS_DONE }


static void clear_cached_dir (cached_dir_t *d)
static const signed_descriptor_tget_signed_descriptor_by_fp (const uint8_t *fp, int extrainfo)
static int spooled_resource_lookup_body (const spooled_resource_t *spooled, int conn_is_encrypted, const uint8_t **body_out, size_t *size_out, time_t *published_out)
static cached_dir_tspooled_resource_lookup_cached_dir (const spooled_resource_t *spooled, time_t *published_out)
static cached_dir_tlookup_cached_dir_by_fp (const uint8_t *fp)
int directory_fetches_from_authorities (const or_options_t *options)
int directory_fetches_dir_info_early (const or_options_t *options)
int directory_fetches_dir_info_later (const or_options_t *options)
int directory_caches_unknown_auth_certs (const or_options_t *options)
int directory_caches_dir_info (const or_options_t *options)
int directory_permits_begindir_requests (const or_options_t *options)
int directory_too_idle_to_fetch_descriptors (const or_options_t *options, time_t now)
void cached_dir_decref (cached_dir_t *d)
cached_dir_tnew_cached_dir (char *s, time_t published)
static void free_cached_dir_ (void *_d)
void dirserv_set_cached_consensus_networkstatus (const char *networkstatus, size_t networkstatus_len, const char *flavor_name, const common_digests_t *digests, const uint8_t *sha3_as_signed, time_t published)
cached_dir_tdirserv_get_consensus (const char *flavor_name)
int dirserv_get_routerdesc_spool (smartlist_t *spool_out, const char *key, dir_spool_source_t source, int conn_is_encrypted, const char **msg_out)
int dirserv_get_routerdescs (smartlist_t *descs_out, const char *key, const char **msg)
spooled_resource_tspooled_resource_new (dir_spool_source_t source, const uint8_t *digest, size_t digestlen)
spooled_resource_tspooled_resource_new_from_cache_entry (consensus_cache_entry_t *entry)
void spooled_resource_free_ (spooled_resource_t *spooled)
static double estimate_compression_ratio (dir_spool_source_t source)
static size_t spooled_resource_estimate_size (const spooled_resource_t *spooled, dir_connection_t *conn, int compressed, time_t *published_out)
static spooled_resource_flush_status_t spooled_resource_flush_some (spooled_resource_t *spooled, dir_connection_t *conn)
void dirserv_spool_remove_missing_and_guess_size (dir_connection_t *conn, time_t cutoff, int compression, size_t *size_out, int *n_expired_out)
static int dirserv_spool_sort_comparison_ (const void **a_, const void **b_)
void dirserv_spool_sort (dir_connection_t *conn)
int connection_dirserv_flushed_some (dir_connection_t *conn)
void dir_conn_clear_spool (dir_connection_t *conn)
void dirserv_free_all (void)


static strmap_t * cached_consensuses = NULL

Detailed Description

Directory server core implementation. Manages directory contents and generates directory documents.

This module implements most of directory cache functionality, and some of the directory authority functionality. The directory.c module delegates here in order to handle incoming requests from clients, via connection_dirserv_flushed_some() and its kin. In order to save RAM, this module is responsible for spooling directory objects (in whole or in part) onto buf_t instances, and then closing the dir_connection_t once the objects are totally flushed.

The directory.c module also delegates here for handling descriptor uploads via dirserv_add_multiple_descriptors().

Additionally, this module handles some aspects of voting, including: deciding how to vote on individual flags (based on decisions reached in rephist.c), of formatting routerstatus lines, and deciding what relays to include in an authority's vote. (TODO: Those functions could profitably be split off. They only live in this file because historically they were shared among the v1, v2, and v3 directory code.)

Definition in file dirserv.c.

Macro Definition Documentation


#define DIRSERV_BUFFER_MIN   16384

When we're spooling data onto our outbuf, add more whenever we dip below this threshold.

Definition at line 843 of file dirserv.c.



When spooling data from a cached_dir_t object, we always add at least this much.

Definition at line 496 of file dirserv.c.

Enumeration Type Documentation

◆ spooled_resource_flush_status_t

Return code for spooled_resource_flush_some

Definition at line 560 of file dirserv.c.

Function Documentation

◆ cached_dir_decref()

void cached_dir_decref ( cached_dir_t d)

Decrement the reference count on d, and free it if it no longer has any references.

Definition at line 186 of file dirserv.c.

References clear_cached_dir(), cached_dir_t::refcnt, and tor_free.

Referenced by free_cached_dir_(), and spooled_resource_free_().

◆ clear_cached_dir()

static void clear_cached_dir ( cached_dir_t d)

Remove all storage held in d, but do not free d itself.

Definition at line 213 of file dirserv.c.

References cached_dir_t::dir, cached_dir_t::dir_compressed, and tor_free.

Referenced by cached_dir_decref().

◆ connection_dirserv_flushed_some()

int connection_dirserv_flushed_some ( dir_connection_t conn)

Called whenever we have flushed some directory data in state SERVER_WRITING, or whenever we want to fill the buffer with initial directory data (so that subsequent writes will occur, and trigger this function again.)

Return 0 on success, and -1 on failure.

Definition at line 854 of file dirserv.c.

References DIR_CONN_STATE_SERVER_WRITING, dir_connection_t::spool, connection_t::state, and tor_assert().

Referenced by connection_flushed_some().

◆ dir_conn_clear_spool()

void dir_conn_clear_spool ( dir_connection_t conn)

Remove every element from conn's outgoing spool, and delete the spool.

Definition at line 899 of file dirserv.c.

References SMARTLIST_FOREACH, and dir_connection_t::spool.

◆ directory_caches_dir_info()

int directory_caches_dir_info ( const or_options_t options)

Return 1 if we want to fetch and serve descriptors, networkstatuses, etc Else return 0. Check options->DirPort_set and directory_permits_begindir_requests() to see if we are willing to serve these directory documents to others via the DirPort and begindir-over-ORPort, respectively.

To check if we should fetch documents, use we_want_to_fetch_flavor and we_want_to_fetch_unknown_auth_certs instead of this function.

Definition at line 143 of file dirserv.c.

References or_options_t::BridgeRelay, dir_server_mode(), and should_refuse_unknown_exits().

Referenced by directory_too_idle_to_fetch_descriptors(), we_fetch_microdescriptors(), and we_fetch_router_descriptors().

◆ directory_caches_unknown_auth_certs()

int directory_caches_unknown_auth_certs ( const or_options_t options)

Return true iff we want to serve certificates for authorities that we don't acknowledge as authorities ourself. Use we_want_to_fetch_unknown_auth_certs to check if we want to fetch and keep these certificates.

Definition at line 128 of file dirserv.c.

References or_options_t::BridgeRelay, and dir_server_mode().

◆ directory_fetches_dir_info_early()

int directory_fetches_dir_info_early ( const or_options_t options)

Return 1 if we should fetch new networkstatuses, descriptors, etc on the "mirror" schedule rather than the "client" schedule.

Definition at line 105 of file dirserv.c.

References directory_fetches_from_authorities().

Referenced by update_consensus_networkstatus_fetch_time_impl().

◆ directory_fetches_dir_info_later()

int directory_fetches_dir_info_later ( const or_options_t options)

Return 1 if we should fetch new networkstatuses, descriptors, etc on a very passive schedule – waiting long enough for ordinary clients to probably have the info we want. These would include bridge users, and maybe others in the future e.g. if a Tor client uses another Tor client as a directory guard.

Definition at line 117 of file dirserv.c.

References or_options_t::UseBridges.

◆ directory_fetches_from_authorities()

int directory_fetches_from_authorities ( const or_options_t options)

Return 1 if we fetch our directory material directly from the authorities, rather than from a mirror.

Definition at line 77 of file dirserv.c.

References or_options_t::BridgeRelay, dir_server_mode(), or_options_t::FetchDirInfoEarly, should_refuse_unknown_exits(), and routerinfo_t::supports_tunnelled_dir_requests.

Referenced by directory_fetches_dir_info_early(), directory_info_has_arrived(), and fetch_networkstatus_callback().

◆ directory_permits_begindir_requests()

int directory_permits_begindir_requests ( const or_options_t options)

Return 1 if we want to allow remote clients to ask us directory requests via the "begin_dir" interface, which doesn't require having any separate port open.

Definition at line 159 of file dirserv.c.

References or_options_t::BridgeRelay, and dir_server_mode().

◆ directory_too_idle_to_fetch_descriptors()

int directory_too_idle_to_fetch_descriptors ( const or_options_t options,
time_t  now 

Return 1 if we have no need to fetch new descriptors. This generally happens when we're not a dir cache and we haven't built any circuits lately.

Definition at line 169 of file dirserv.c.

References directory_caches_dir_info(), or_options_t::FetchUselessDescriptors, and rep_hist_circbuilding_dormant().

Referenced by directory_info_has_arrived(), update_consensus_router_descriptor_downloads(), and update_microdesc_downloads().

◆ dirserv_free_all()

void dirserv_free_all ( void  )

Release all storage used by the directory server.

Definition at line 911 of file dirserv.c.

◆ dirserv_get_consensus()

cached_dir_t* dirserv_get_consensus ( const char *  flavor_name)

Return the latest downloaded consensus networkstatus in encoded, signed, optionally compressed format, suitable for sending to clients.

Definition at line 263 of file dirserv.c.

References cached_consensuses.

◆ dirserv_get_routerdesc_spool()

int dirserv_get_routerdesc_spool ( smartlist_t spool_out,
const char *  key,
dir_spool_source_t  source,
int  conn_is_encrypted,
const char **  msg_out 

As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t pointers, adds copies of digests to fps_out, and doesn't use the /tor/server/ prefix. For a /d/ request, adds descriptor digests; for other requests, adds identity digests.

Definition at line 276 of file dirserv.c.

References router_get_routerlist(), routerlist_t::routers, and SMARTLIST_FOREACH_BEGIN.

◆ dirserv_get_routerdescs()

int dirserv_get_routerdescs ( smartlist_t descs_out,
const char *  key,
const char **  msg 

Add a signed_descriptor_t to descs_out for each router matching key. The key should be either

  • "/tor/server/authority" for our own routerinfo;
  • "/tor/server/all" for all the routerinfos we have, concatenated;
  • "/tor/server/fp/FP" where FP is a plus-separated sequence of hex identity digests; or
  • "/tor/server/d/D" where D is a plus-separated sequence of server descriptor digests, in hex.

Return 0 if we found some matching descriptors, or -1 if we do not have any descriptors, no matching descriptors, or if we did not recognize the key (URL). If -1 is returned *msg will be set to an appropriate error message.

XXXX rename this function. It's only called from the controller. XXXX in fact, refactor this function, merging as much as possible.

Definition at line 355 of file dirserv.c.

References dir_split_resource_into_fingerprints(), router_get_routerlist(), routerlist_t::routers, smartlist_add(), SMARTLIST_FOREACH, and strcmpstart().

◆ dirserv_set_cached_consensus_networkstatus()

void dirserv_set_cached_consensus_networkstatus ( const char *  networkstatus,
size_t  networkstatus_len,
const char *  flavor_name,
const common_digests_t digests,
const uint8_t *  sha3_as_signed,
time_t  published 

Replace the v3 consensus networkstatus of type flavor_name that we're serving with networkstatus, published at published. No validation is performed.

Definition at line 236 of file dirserv.c.

References cached_consensuses, and new_cached_dir().

◆ dirserv_spool_remove_missing_and_guess_size()

void dirserv_spool_remove_missing_and_guess_size ( dir_connection_t conn,
time_t  cutoff,
int  compression,
size_t *  size_out,
int *  n_expired_out 

Try to guess the number of bytes that will be needed to send the spooled objects for conn's outgoing spool. In the process, remove every element of the spool that refers to an absent object, or which was published earlier than cutoff. Set *size_out to the number of bytes, and *n_expired_out to the number of objects removed for being too old.

Definition at line 756 of file dirserv.c.

◆ dirserv_spool_sort()

void dirserv_spool_sort ( dir_connection_t conn)

Sort all the entries in conn by digest.

Definition at line 809 of file dirserv.c.

References dirserv_spool_sort_comparison_(), smartlist_sort(), and dir_connection_t::spool.

◆ dirserv_spool_sort_comparison_()

static int dirserv_spool_sort_comparison_ ( const void **  a_,
const void **  b_ 

Helper: used to sort a connection's spool.

Definition at line 800 of file dirserv.c.

References spooled_resource_t::digest, and fast_memcmp.

Referenced by dirserv_spool_sort().

◆ estimate_compression_ratio()

static double estimate_compression_ratio ( dir_spool_source_t  source)

Return an compression ratio for compressing objects from source.

Definition at line 501 of file dirserv.c.

Referenced by spooled_resource_estimate_size().

◆ free_cached_dir_()

static void free_cached_dir_ ( void *  _d)

Free all storage held by the cached_dir_t in d.

Definition at line 222 of file dirserv.c.

References cached_dir_decref().

◆ get_signed_descriptor_by_fp()

static const signed_descriptor_t * get_signed_descriptor_by_fp ( const uint8_t *  fp,
int  extrainfo 

Return the cache-info for identity fingerprint fp, or its extra-info document if extrainfo is true. Return NULL if not found or if the descriptor is older than publish_cutoff.

Definition at line 821 of file dirserv.c.

References signed_descriptor_t::extra_info_digest, router_digest_is_me(), router_get_by_id_digest(), and router_get_my_extrainfo().

◆ lookup_cached_dir_by_fp()

static cached_dir_t * lookup_cached_dir_by_fp ( const uint8_t *  fp)

Given a fingerprint fp which is either set if we're looking for a v2 status, or zeroes if we're looking for a v3 status, or a NUL-padded flavor name if we want a flavored v3 status, return a pointer to the appropriate cached dir object, or NULL if there isn't one available.

Definition at line 736 of file dirserv.c.

References cached_consensuses, DIGEST_LEN, and tor_digest_is_zero().

Referenced by spooled_resource_lookup_cached_dir().

◆ new_cached_dir()

cached_dir_t* new_cached_dir ( char *  s,
time_t  published 

Allocate and return a new cached_dir_t containing the string s, published at published.

Definition at line 197 of file dirserv.c.

Referenced by dirserv_set_cached_consensus_networkstatus().

◆ spooled_resource_estimate_size()

static size_t spooled_resource_estimate_size ( const spooled_resource_t spooled,
dir_connection_t conn,
int  compressed,
time_t *  published_out 

Return an estimated number of bytes needed for transmitting the resource in spooled on conn

As a convenient side-effect, set *published_out to the resource's publication time.

Definition at line 516 of file dirserv.c.

References spooled_resource_t::cached_dir_ref, connection_dir_is_encrypted(), spooled_resource_t::consensus_cache_entry, cached_dir_t::dir_compressed_len, cached_dir_t::dir_len, estimate_compression_ratio(), spooled_resource_t::spool_eagerly, spooled_resource_t::spool_source, spooled_resource_lookup_body(), and spooled_resource_lookup_cached_dir().

◆ spooled_resource_flush_some()

static spooled_resource_flush_status_t spooled_resource_flush_some ( spooled_resource_t spooled,
dir_connection_t conn 

Flush some or all of the bytes from spooled onto conn. Return SRFS_ERR on error, SRFS_MORE if there are more bytes to flush from this spooled resource, or SRFS_DONE if we are done flushing this spooled resource.

Definition at line 572 of file dirserv.c.

References connection_dir_is_encrypted(), spooled_resource_t::spool_eagerly, and spooled_resource_lookup_body().

◆ spooled_resource_free_()

void spooled_resource_free_ ( spooled_resource_t spooled)

Release all storage held by spooled.

Definition at line 478 of file dirserv.c.

References cached_dir_decref(), spooled_resource_t::cached_dir_ref, spooled_resource_t::consensus_cache_entry, and tor_free.

◆ spooled_resource_lookup_body()

static int spooled_resource_lookup_body ( const spooled_resource_t spooled,
int  conn_is_encrypted,
const uint8_t **  body_out,
size_t *  size_out,
time_t *  published_out 

Helper: Look up the body for an eagerly-served spooled_resource. If conn_is_encrypted is false, don't look up any resource that shouldn't be sent over an unencrypted connection. On success, set body_out, size_out, and published_out to refer to the resource's body, size, and publication date, and return 0. On failure return -1.

Definition at line 663 of file dirserv.c.

References spooled_resource_t::spool_eagerly, spooled_resource_t::spool_source, and tor_assert().

Referenced by spooled_resource_estimate_size(), and spooled_resource_flush_some().

◆ spooled_resource_lookup_cached_dir()

static cached_dir_t * spooled_resource_lookup_cached_dir ( const spooled_resource_t spooled,
time_t *  published_out 

Helper: find the cached_dir_t for a spooled_resource_t, for sending it to conn. Set *published_out, if provided, to the published time of the cached_dir_t.

DOES NOT increase the reference count on the result. Callers must do that themselves if they mean to hang on to it.

Definition at line 644 of file dirserv.c.

References spooled_resource_t::digest, lookup_cached_dir_by_fp(), cached_dir_t::published, spooled_resource_t::spool_eagerly, and tor_assert().

Referenced by spooled_resource_estimate_size().

◆ spooled_resource_new_from_cache_entry()

spooled_resource_t* spooled_resource_new_from_cache_entry ( consensus_cache_entry_t entry)

Create a new spooled_resource_t to spool the contents of entry to the user. Return the spooled object on success, or NULL on failure (which is probably caused by a failure to map the body of the item from disk).

Adds a reference to entry's reference counter.

Definition at line 457 of file dirserv.c.

Variable Documentation

◆ cached_consensuses

strmap_t* cached_consensuses = NULL

Map from flavor name to the cached_dir_t for the v3 consensuses that we're currently serving.

Definition at line 181 of file dirserv.c.

Referenced by dirserv_get_consensus(), dirserv_set_cached_consensus_networkstatus(), and lookup_cached_dir_by_fp().