tor  master
Data Structures | Macros | Typedefs | Functions
directory.c File Reference

Code to send and fetch information from directory authorities and caches via HTTP. More...

#include "or.h"
#include "backtrace.h"
#include "bridges.h"
#include "buffers.h"
#include "circuitbuild.h"
#include "config.h"
#include "connection.h"
#include "connection_edge.h"
#include "conscache.h"
#include "consdiff.h"
#include "consdiffmgr.h"
#include "control.h"
#include "compat.h"
#include "crypto_rand.h"
#include "crypto_util.h"
#include "directory.h"
#include "dirserv.h"
#include "entrynodes.h"
#include "geoip.h"
#include "hs_cache.h"
#include "hs_common.h"
#include "hs_control.h"
#include "hs_client.h"
#include "main.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "relay.h"
#include "rendclient.h"
#include "rendcommon.h"
#include "rendservice.h"
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
#include "dirauth/dirvote.h"
#include "dirauth/mode.h"
#include "dirauth/shared_random.h"
Include dependency graph for directory.c:

Data Structures

struct  get_handler_args_t
 
struct  url_table_ent_s
 
struct  parsed_consensus_request_t
 

Macros

#define DIRECTORY_PRIVATE
 
#define ALLOW_DIRECTORY_TIME_SKEW   (30*60)
 
#define X_ADDRESS_HEADER   "X-Your-Address-Is: "
 
#define X_OR_DIFF_FROM_CONSENSUS_HEADER   "X-Or-Diff-From-Consensus: "
 
#define FULL_DIR_CACHE_LIFETIME   (60*60)
 
#define RUNNINGROUTERS_CACHE_LIFETIME   (20*60)
 
#define DIRPORTFRONTPAGE_CACHE_LIFETIME   (20*60)
 
#define NETWORKSTATUS_CACHE_LIFETIME   (5*60)
 
#define ROUTERDESC_CACHE_LIFETIME   (30*60)
 
#define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME   (48*60*60)
 
#define ROBOTS_CACHE_LIFETIME   (24*60*60)
 
#define MICRODESC_CACHE_LIFETIME   (48*60*60)
 
#define CONDITIONAL_CONSENSUS_FPR_LEN   3
 
#define SEND_HS_DESC_FAILED_EVENT(reason)
 
#define SEND_HS_DESC_FAILED_CONTENT()
 
#define SEND_HS_DESC_UPLOAD_FAILED_EVENT(reason)
 
#define MAX_DIRECTORY_OBJECT_SIZE   (10*(1<<20))
 
#define MAX_VOTE_DL_SIZE   (MAX_DIRECTORY_OBJECT_SIZE * 5)
 
#define TOO_OLD_WARNING_INTERVAL   (60*60)
 
#define FALLBACK_COMPRESS_METHOD   ZLIB_METHOD
 

Typedefs

typedef struct get_handler_args_t get_handler_args_t
 
typedef struct url_table_ent_s url_table_ent_t
 

Functions

int purpose_needs_anonymity (uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
 
STATIC char * authdir_type_to_string (dirinfo_type_t auth)
 
STATIC const char * dir_conn_purpose_to_string (int purpose)
 
STATIC dirinfo_type_t dir_fetch_type (int dir_purpose, int router_purpose, const char *resource)
 
int router_supports_extrainfo (const char *identity_digest, int is_authority)
 
int directories_have_accepted_server_descriptor (void)
 
void directory_post_to_dirservers (uint8_t dir_purpose, uint8_t router_purpose, dirinfo_type_t type, const char *payload, size_t payload_len, size_t extrainfo_len)
 
STATIC int should_use_directory_guards (const or_options_t *options)
 
 MOCK_IMPL (void, directory_get_from_dirserver,(uint8_t dir_purpose, uint8_t router_purpose, const char *resource, int pds_flags, download_want_authority_t want_authority))
 
void directory_get_from_all_authorities (uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
 
int directory_must_use_begindir (const or_options_t *options)
 
directory_request_tdirectory_request_new (uint8_t dir_purpose)
 
void directory_request_free_ (directory_request_t *req)
 
void directory_request_set_or_addr_port (directory_request_t *req, const tor_addr_port_t *p)
 
void directory_request_set_dir_addr_port (directory_request_t *req, const tor_addr_port_t *p)
 
void directory_request_set_directory_id_digest (directory_request_t *req, const char *digest)
 
void directory_request_set_router_purpose (directory_request_t *req, uint8_t router_purpose)
 
void directory_request_set_indirection (directory_request_t *req, dir_indirection_t indirection)
 
void directory_request_set_resource (directory_request_t *req, const char *resource)
 
void directory_request_set_payload (directory_request_t *req, const char *payload, size_t payload_len)
 
void directory_request_set_if_modified_since (directory_request_t *req, time_t if_modified_since)
 
void directory_request_add_header (directory_request_t *req, const char *key, const char *val)
 
void directory_request_set_rend_query (directory_request_t *req, const rend_data_t *query)
 
void directory_request_upload_set_hs_ident (directory_request_t *req, const hs_ident_dir_conn_t *ident)
 
void directory_request_fetch_set_hs_ident (directory_request_t *req, const hs_ident_dir_conn_t *ident)
 
void directory_request_set_guard_state (directory_request_t *req, circuit_guard_state_t *state)
 
void directory_request_set_routerstatus (directory_request_t *req, const routerstatus_t *status)
 
 MOCK_IMPL (void, directory_initiate_request,(directory_request_t *request))
 
int connection_dir_is_encrypted (const dir_connection_t *conn)
 
STATIC int parse_http_url (const char *headers, char **url)
 
int parse_http_command (const char *headers, char **command_out, char **url_out)
 
char * http_get_header (const char *headers, const char *which)
 
int parse_http_response (const char *headers, int *code, time_t *date, compress_method_t *compression, char **reason)
 
STATIC int handle_response_fetch_consensus (dir_connection_t *conn, const response_handler_args_t *args)
 
STATIC int handle_response_fetch_microdesc (dir_connection_t *conn, const response_handler_args_t *args)
 
STATIC int handle_response_fetch_hsdesc_v3 (dir_connection_t *conn, const response_handler_args_t *args)
 
int connection_dir_reached_eof (dir_connection_t *conn)
 
int connection_dir_process_inbuf (dir_connection_t *conn)
 
void connection_dir_about_to_close (dir_connection_t *dir_conn)
 
STATIC unsigned parse_accept_encoding_header (const char *h)
 
STATIC char * accept_encoding_header (void)
 
STATIC compression_level_t choose_compression_level (ssize_t n_bytes)
 
 MOCK_IMPL (STATIC int, directory_handle_command_get,(dir_connection_t *conn, const char *headers, const char *req_body, size_t req_body_len))
 
STATIC int allowed_anonymous_connection_compression_method (compress_method_t method)
 
STATIC void warn_disallowed_anonymous_compression_method (compress_method_t method)
 
STATIC int handle_get_hs_descriptor_v3 (dir_connection_t *conn, const get_handler_args_t *args)
 
STATIC int parse_hs_version_from_post (const char *url, const char *prefix, const char **end_pos)
 
STATIC int handle_post_hs_descriptor (const char *url, const char *body)
 
 MOCK_IMPL (STATIC int, directory_handle_command_post,(dir_connection_t *conn, const char *headers, const char *body, size_t body_len))
 
STATIC int directory_handle_command (dir_connection_t *conn)
 
int connection_dir_finished_flushing (dir_connection_t *conn)
 
int connection_dir_finished_connecting (dir_connection_t *conn)
 
STATIC int find_dl_min_delay (const download_status_t *dls, const or_options_t *options)
 
STATIC void next_random_exponential_delay_range (int *low_bound_out, int *high_bound_out, int delay, int base_delay)
 
STATIC int next_random_exponential_delay (int delay, int base_delay)
 
STATIC int download_status_schedule_get_delay (download_status_t *dls, int min_delay, time_t now)
 
time_t download_status_increment_failure (download_status_t *dls, int status_code, const char *item, int server, time_t now)
 
time_t download_status_increment_attempt (download_status_t *dls, const char *item, time_t now)
 
void download_status_reset (download_status_t *dls)
 
int download_status_get_n_failures (const download_status_t *dls)
 
int download_status_get_n_attempts (const download_status_t *dls)
 
time_t download_status_get_next_attempt_at (const download_status_t *dls)
 
int dir_split_resource_into_fingerprint_pairs (const char *res, smartlist_t *pairs_out)
 
int dir_split_resource_into_fingerprints (const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
 
int dir_split_resource_into_spoolable (const char *resource, dir_spool_source_t source, smartlist_t *spool_out, int *compressed_out, int flags)
 

Detailed Description

Code to send and fetch information from directory authorities and caches via HTTP.

Directory caches and authorities use dirserv.c to generate the results of a query and stream them to the connection; clients use routerparse.c to parse them.

Every directory request has a dir_connection_t on the client side and on the server side. In most cases, the dir_connection_t object is a linked connection, tunneled through an edge_connection_t so that it can be a stream on the Tor network. The only non-tunneled connections are those that are used to upload material (descriptors and votes) to authorities. Among tunneled connections, some use one-hop circuits, and others use multi-hop circuits for anonymity.

Directory requests are launched by calling directory_initiate_request(). This launch the connection, will construct an HTTP request with directory_send_command(), send the and wait for a response. The client later handles the response with connection_dir_client_reached_eof(), which passes the information received to another part of Tor.

On the server side, requests are read in directory_handle_command(), which dispatches first on the request type (GET or POST), and then on the URL requested. GET requests are processed with a table-based dispatcher in url_table[]. The process of handling larger GET requests is complicated because we need to avoid allocating a copy of all the data to be sent to the client in one huge buffer. Instead, we spool the data into the buffer using logic in connection_dirserv_flushed_some() in dirserv.c. (TODO: If we extended buf.c to have a zero-copy reference-based buffer type, we could remove most of that code, at the cost of a bit more reference counting.)

Macro Definition Documentation

◆ ALLOW_DIRECTORY_TIME_SKEW

#define ALLOW_DIRECTORY_TIME_SKEW   (30*60)

How far in the future do we allow a directory server to tell us it is before deciding that one of us has the wrong time?

◆ FALLBACK_COMPRESS_METHOD

#define FALLBACK_COMPRESS_METHOD   ZLIB_METHOD

Fallback compression method. The fallback compression method is used in case a client requests a non-compressed document. We only store compressed documents, so we use this compression method to fetch the document and let the spooling system do the streaming decompression.

◆ FULL_DIR_CACHE_LIFETIME

#define FULL_DIR_CACHE_LIFETIME   (60*60)

HTTP cache control: how long do we tell proxies they can cache each kind of document we serve?

◆ MAX_DIRECTORY_OBJECT_SIZE

#define MAX_DIRECTORY_OBJECT_SIZE   (10*(1<<20))

If any directory object is arriving, and it's over 10MB large, we're getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never ask for more than 96 router descriptors at a time.)

◆ SEND_HS_DESC_FAILED_CONTENT

#define SEND_HS_DESC_FAILED_CONTENT ( )
Value:
rend_data_get_address(conn->rend_data), \
conn->requested_resource, \
conn->identity_digest, \
NULL))
void control_event_hs_descriptor_content(const char *onion_address, const char *desc_id, const char *hsdir_id_digest, const char *content)
Definition: control.c:7643

◆ SEND_HS_DESC_FAILED_EVENT

#define SEND_HS_DESC_FAILED_EVENT (   reason)
Value:
conn->identity_digest, \
reason))
void control_event_hsv2_descriptor_failed(const rend_data_t *rend_data, const char *hsdir_id_digest, const char *reason)
Definition: control.c:7583

◆ SEND_HS_DESC_UPLOAD_FAILED_EVENT

#define SEND_HS_DESC_UPLOAD_FAILED_EVENT (   reason)
Value:
conn->identity_digest, \
rend_data_get_address(conn->rend_data), \
reason))
void control_event_hs_descriptor_upload_failed(const char *id_digest, const char *onion_address, const char *reason)
Definition: control.c:7680

Typedef Documentation

◆ get_handler_args_t

Information passed to handle a GET request.

◆ url_table_ent_t

Entry for handling an HTTP GET request.

This entry matches a request if "string" is equal to the requested resource, or if "is_prefix" is true and "string" is a prefix of the requested resource.

The 'handler' function is called to handle the request. It receives an arguments structure, and must return 0 on success or -1 if we should close the connection.

Function Documentation

◆ accept_encoding_header()

STATIC char* accept_encoding_header ( void  )

Return a newly allocated string containing a comma separated list of supported encodings.

◆ allowed_anonymous_connection_compression_method()

STATIC int allowed_anonymous_connection_compression_method ( compress_method_t  method)

Check if the given compression method is allowed for a connection that is supposed to be anonymous. Returns 1 if the compression method is allowed, otherwise 0.

◆ authdir_type_to_string()

STATIC char* authdir_type_to_string ( dirinfo_type_t  auth)

Return a newly allocated string describing auth. Only describes authority features.

Here is the call graph for this function:

◆ choose_compression_level()

STATIC compression_level_t choose_compression_level ( ssize_t  n_bytes)

Return the compression level we should use for sending a compressed response of size n_bytes.

Here is the call graph for this function:

◆ connection_dir_about_to_close()

void connection_dir_about_to_close ( dir_connection_t dir_conn)

Called when we're about to finally unlink and free a directory connection: perform necessary accounting and cleanup

Here is the caller graph for this function:

◆ connection_dir_finished_connecting()

int connection_dir_finished_connecting ( dir_connection_t conn)

Connected handler for directory connections: begin sending data to the server, and return 0. Only used when connections don't immediately connect.

◆ connection_dir_finished_flushing()

int connection_dir_finished_flushing ( dir_connection_t conn)

Write handler for directory connections; called when all data has been flushed. Close the connection or wait for a response as appropriate.

Here is the call graph for this function:

◆ connection_dir_is_encrypted()

int connection_dir_is_encrypted ( const dir_connection_t conn)

Return true iff anything we say on conn is being encrypted before we send it to the client/server.

Here is the caller graph for this function:

◆ connection_dir_process_inbuf()

int connection_dir_process_inbuf ( dir_connection_t conn)

Read handler for directory connections. (That's connections to directory servers and connections at directory servers.)

Here is the call graph for this function:

◆ connection_dir_reached_eof()

int connection_dir_reached_eof ( dir_connection_t conn)

Called when a directory connection reaches EOF.

◆ dir_conn_purpose_to_string()

STATIC const char* dir_conn_purpose_to_string ( int  purpose)

Return a string describing a given directory connection purpose.

◆ dir_fetch_type()

STATIC dirinfo_type_t dir_fetch_type ( int  dir_purpose,
int  router_purpose,
const char *  resource 
)

Return the requisite directory information types.

◆ dir_split_resource_into_fingerprint_pairs()

int dir_split_resource_into_fingerprint_pairs ( const char *  res,
smartlist_t pairs_out 
)

Divide a string res of the form FP1-FP2+FP3-FP4...[.z], where each FP is a hex-encoded fingerprint, into a sequence of distinct sorted fp_pair_t. Skip malformed pairs. On success, return 0 and add those fp_pair_t into pairs_out. On failure, return -1.

Here is the call graph for this function:

◆ dir_split_resource_into_fingerprints()

int dir_split_resource_into_fingerprints ( const char *  resource,
smartlist_t fp_out,
int *  compressed_out,
int  flags 
)

Given a directory resource request, containing zero or more strings separated by plus signs, followed optionally by ".z", store the strings, in order, into fp_out. If compressed_out is non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.

If (flags & DSR_HEX), then delete all elements that aren't hex digests, and decode the rest. If (flags & DSR_BASE64), then use "-" rather than "+" as a separator, delete all the elements that aren't base64-encoded digests, and decode the rest. If (flags & DSR_DIGEST256), these digests should be 256 bits long; else they should be 160.

If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.

◆ dir_split_resource_into_spoolable()

int dir_split_resource_into_spoolable ( const char *  resource,
dir_spool_source_t  source,
smartlist_t spool_out,
int *  compressed_out,
int  flags 
)

As dir_split_resource_into_fingerprints, but instead fills spool_out with a list of spoolable_resource_t for the resource identified through source.

◆ directories_have_accepted_server_descriptor()

int directories_have_accepted_server_descriptor ( void  )

Return true iff any trusted directory authority has accepted our server descriptor.

We consider any authority sufficient because waiting for all of them means it never happens while any authority is down; we don't go for something more complex in the middle (like >1/3 or >1/2 or >=1/2) because that doesn't seem necessary yet.

Here is the call graph for this function:

◆ directory_get_from_all_authorities()

void directory_get_from_all_authorities ( uint8_t  dir_purpose,
uint8_t  router_purpose,
const char *  resource 
)

As directory_get_from_dirserver, but initiates a request to every directory authority other than ourself. Only for use by authorities when searching for missing information while voting.

Here is the call graph for this function:

◆ directory_handle_command()

STATIC int directory_handle_command ( dir_connection_t conn)

Called when a dirserver receives data on a directory connection; looks for an HTTP request. If the request is complete, remove it from the inbuf, try to process it; otherwise, leave it on the buffer. Return a 0 on success, or -1 on error.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ directory_post_to_dirservers()

void directory_post_to_dirservers ( uint8_t  dir_purpose,
uint8_t  router_purpose,
dirinfo_type_t  type,
const char *  payload,
size_t  payload_len,
size_t  extrainfo_len 
)

Start a connection to every suitable directory authority, using connection purpose dir_purpose and uploading payload (of length payload_len). The dir_purpose should be one of 'DIR_PURPOSE_UPLOAD_{DIR|VOTE|SIGNATURES}'.

router_purpose describes the type of descriptor we're publishing, if we're publishing a descriptor – e.g. general or bridge.

type specifies what sort of dir authorities (V3, BRIDGE, etc) we should upload to.

If extrainfo_len is nonzero, the first payload_len bytes of payload hold a router descriptor, and the next extrainfo_len bytes of payload hold an extra-info document. Upload the descriptor to all authorities, and the extra-info document to all authorities that support it.

◆ directory_request_add_header()

void directory_request_add_header ( directory_request_t req,
const char *  key,
const char *  val 
)

Include a header of name key with content val in the request. Neither may include newlines or other odd characters. Their ordering is not currently guaranteed.

Note that, as elsewhere in this module, header keys include a trailing colon and space.

◆ directory_request_fetch_set_hs_ident()

void directory_request_fetch_set_hs_ident ( directory_request_t req,
const hs_ident_dir_conn_t ident 
)

Set an object containing HS connection identifier to be associated with this fetch request. Note that only an alias to ident is stored, so the ident object must outlive the request.

◆ directory_request_free_()

void directory_request_free_ ( directory_request_t req)

Release all resources held by req.

◆ directory_request_new()

directory_request_t* directory_request_new ( uint8_t  dir_purpose)

Create and return a new directory_request_t with purpose dir_purpose.

Here is the caller graph for this function:

◆ directory_request_set_dir_addr_port()

void directory_request_set_dir_addr_port ( directory_request_t req,
const tor_addr_port_t p 
)

Set the address and dirport to use for this directory request. If there is no dirport, we'll have to connect over the OR port. (If there are both, the indirection setting determines which to use.)

◆ directory_request_set_directory_id_digest()

void directory_request_set_directory_id_digest ( directory_request_t req,
const char *  digest 
)

Set the RSA identity digest of the directory to use for this directory request.

◆ directory_request_set_guard_state()

void directory_request_set_guard_state ( directory_request_t req,
circuit_guard_state_t *  state 
)

Set a static circuit_guard_state_t object to affliate with the request in req. This object will receive notification when the attempt to connect to the guard either succeeds or fails.

◆ directory_request_set_if_modified_since()

void directory_request_set_if_modified_since ( directory_request_t req,
time_t  if_modified_since 
)

Set an if-modified-since date to send along with the request. The default is 0 (meaning, send no if-modified-since header).

◆ directory_request_set_indirection()

void directory_request_set_indirection ( directory_request_t req,
dir_indirection_t  indirection 
)

Set the indirection to be used for the directory request. The indirection parameter configures whether to connect to a DirPort or ORPort, and whether to anonymize the connection. DIRIND_ONEHOP (use ORPort, don't anonymize) is the default. See dir_indirection_t for more information.

◆ directory_request_set_or_addr_port()

void directory_request_set_or_addr_port ( directory_request_t req,
const tor_addr_port_t p 
)

Set the address and OR port to use for this directory request. If there is no OR port, we'll have to connect over the dirport. (If there are both, the indirection setting determines which to use.)

◆ directory_request_set_payload()

void directory_request_set_payload ( directory_request_t req,
const char *  payload,
size_t  payload_len 
)

Set a pointer to the payload to include with this directory request, along with its length. Note that only an alias to payload is stored, so the payload must outlive the request.

◆ directory_request_set_rend_query()

void directory_request_set_rend_query ( directory_request_t req,
const rend_data_t query 
)

Set an object containing HS data to be associated with this request. Note that only an alias to query is stored, so the query object must outlive the request.

◆ directory_request_set_resource()

void directory_request_set_resource ( directory_request_t req,
const char *  resource 
)

Set a pointer to the resource to request from a directory. Different request types use resources to indicate different components of their URL. Note that only an alias to resource is stored, so the resource must outlive the request.

Here is the caller graph for this function:

◆ directory_request_set_router_purpose()

void directory_request_set_router_purpose ( directory_request_t req,
uint8_t  router_purpose 
)

Set the router purpose associated with uploaded and downloaded router descriptors and extrainfo documents in this directory request. The purpose must be one of ROUTER_PURPOSE_GENERAL (the default) or ROUTER_PURPOSE_BRIDGE.

Here is the caller graph for this function:

◆ directory_request_set_routerstatus()

void directory_request_set_routerstatus ( directory_request_t req,
const routerstatus_t status 
)

Set the routerstatus to use for the directory associated with this request. If this option is set, then no other function to set the directory's address or identity should be called.

Here is the caller graph for this function:

◆ directory_request_upload_set_hs_ident()

void directory_request_upload_set_hs_ident ( directory_request_t req,
const hs_ident_dir_conn_t ident 
)

Set an object containing HS connection identifier to be associated with this request. Note that only an alias to ident is stored, so the ident object must outlive the request.

◆ download_status_get_n_attempts()

int download_status_get_n_attempts ( const download_status_t dls)

Return the number of attempts to download dls since the last success (if any). This can differ from download_status_get_n_failures() due to outstanding concurrent attempts.

◆ download_status_get_n_failures()

int download_status_get_n_failures ( const download_status_t dls)

Return the number of failures on dls since the last success (if any).

Here is the caller graph for this function:

◆ download_status_get_next_attempt_at()

time_t download_status_get_next_attempt_at ( const download_status_t dls)

Return the next time to attempt to download dls.

◆ download_status_increment_attempt()

time_t download_status_increment_attempt ( download_status_t dls,
const char *  item,
time_t  now 
)

Determine when the next download attempt should be made when using an attempt-based (potentially concurrent) download schedule. Called when an attempt to download dls is being initiated. Increment the attempt count and set dls->next_attempt_at to an appropriate time in the future and return it. If dls->increment_on is DL_SCHED_INCREMENT_FAILURE, don't increment the attempts, and return a time in the far future (to avoid launching a concurrent attempt).

Here is the call graph for this function:

◆ download_status_increment_failure()

time_t download_status_increment_failure ( download_status_t dls,
int  status_code,
const char *  item,
int  server,
time_t  now 
)

Determine when a failed download attempt should be retried. Called when an attempt to download dls has failed with HTTP status status_code. Increment the failure count (if the code indicates a real failure, or if we're a server) and set dls->next_attempt_at to an appropriate time in the future and return it. If dls->increment_on is DL_SCHED_INCREMENT_ATTEMPT, increment the failure count, and return a time in the far future for the next attempt (to avoid an immediate retry).

Here is the call graph for this function:

◆ download_status_reset()

void download_status_reset ( download_status_t dls)

Reset dls so that it will be considered downloadable immediately, and/or to show that we don't need it anymore.

Must be called to initialise a download schedule, otherwise the zeroth item in the schedule will never be used.

(We find the zeroth element of the download schedule, and set next_attempt_at to be the appropriate offset from 'now'. In most cases this means setting it to 'now', so the item will be immediately downloadable; when using authorities with fallbacks, there is a few seconds' delay.)

Here is the caller graph for this function:

◆ download_status_schedule_get_delay()

STATIC int download_status_schedule_get_delay ( download_status_t dls,
int  min_delay,
time_t  now 
)

Find the current delay for dls based on min_delay.

This function sets dls->next_attempt_at based on now, and returns the delay. Helper for download_status_increment_failure and download_status_increment_attempt.

◆ find_dl_min_delay()

STATIC int find_dl_min_delay ( const download_status_t dls,
const or_options_t options 
)

Decide which download schedule we want to use based on descriptor type in dls and options.

Then, return the initial delay for that download schedule, in seconds.

Helper function for download_status_increment_failure(), download_status_reset(), and download_status_increment_attempt().

◆ handle_get_hs_descriptor_v3()

STATIC int handle_get_hs_descriptor_v3 ( dir_connection_t conn,
const get_handler_args_t args 
)

Helper function for GET /tor/hs/3/<z>. Only for version 3.

Here is the call graph for this function:

◆ handle_response_fetch_consensus()

STATIC int handle_response_fetch_consensus ( dir_connection_t conn,
const response_handler_args_t *  args 
)

Handler function: processes a response to a request for a networkstatus consensus document by checking the consensus, storing it, and marking router requests as reachable.

Here is the call graph for this function:

◆ handle_response_fetch_hsdesc_v3()

STATIC int handle_response_fetch_hsdesc_v3 ( dir_connection_t conn,
const response_handler_args_t *  args 
)

Handler function: processes a response to a request for a v3 hidden service descriptor.

◆ handle_response_fetch_microdesc()

STATIC int handle_response_fetch_microdesc ( dir_connection_t conn,
const response_handler_args_t *  args 
)

Handler function: processes a response to a request for a group of microdescriptors

◆ http_get_header()

char* http_get_header ( const char *  headers,
const char *  which 
)

Return a copy of the first HTTP header in headers whose key is which. The key should be given with a terminating colon and space; this function copies everything after, up to but not including the following \r\n.

Here is the call graph for this function:

◆ MOCK_IMPL() [1/4]

MOCK_IMPL ( void  ,
directory_get_from_dirserver  ,
( uint8_t dir_purpose, uint8_t router_purpose, const char *resource, int pds_flags, download_want_authority_t want_authority)   
)

Start a connection to a random running directory server, using connection purpose dir_purpose, intending to fetch descriptors of purpose router_purpose, and requesting resource. Use pds_flags as arguments to router_pick_directory_server() or router_pick_trusteddirserver().

Here is the call graph for this function:

◆ MOCK_IMPL() [2/4]

MOCK_IMPL ( void  ,
directory_initiate_request  ,
(directory_request_t *request)   
)

Launch the provided directory request, configured in request. After this function is called, you can free request.

◆ MOCK_IMPL() [3/4]

MOCK_IMPL ( STATIC  int,
directory_handle_command_get  ,
(dir_connection_t *conn, const char *headers, const char *req_body, size_t req_body_len)   
)

Helper function: called when a dirserver gets a complete HTTP GET request. Look for a request for a directory or for a rendezvous service descriptor. On finding one, write a response into conn->outbuf. If the request is unrecognized, send a 404. Return 0 if we handled this successfully, or -1 if we need to close the connection.

◆ MOCK_IMPL() [4/4]

MOCK_IMPL ( STATIC  int,
directory_handle_command_post  ,
(dir_connection_t *conn, const char *headers, const char *body, size_t body_len)   
)

Helper function: called when a dirserver gets a complete HTTP POST request. Look for an uploaded server descriptor or rendezvous service descriptor. On finding one, process it and write a response into conn->outbuf. If the request is unrecognized, send a

  1. Always return 0.

◆ next_random_exponential_delay()

STATIC int next_random_exponential_delay ( int  delay,
int  base_delay 
)

Advance one delay step. The algorithm will generate a random delay, such that each failure is possibly (random) longer than the ones before.

We then clamp that value to be no larger than max_delay, and return it.

The base_delay parameter is lowest possible delay time (can't be zero); the backoff_position parameter is the number of times we've generated a delay; and the delay argument is the most recently used delay.

◆ next_random_exponential_delay_range()

STATIC void next_random_exponential_delay_range ( int *  low_bound_out,
int *  high_bound_out,
int  delay,
int  base_delay 
)

As next_random_exponential_delay() below, but does not compute a random value. Instead, compute the range of values that next_random_exponential_delay() should use when computing its random value. Store the low bound into *low_bound_out, and the high bound into *high_bound_out. Guarantees that the low bound is strictly less than the high bound.

◆ parse_accept_encoding_header()

STATIC unsigned parse_accept_encoding_header ( const char *  h)

Parse the compression methods listed in an Accept-Encoding header h, and convert them to a bitfield where compression method x is supported if and only if 1 << x is set in the bitfield.

◆ parse_http_command()

int parse_http_command ( const char *  headers,
char **  command_out,
char **  url_out 
)

Parse an HTTP request line at the start of a headers string. On failure, return -1. On success, set *command_out to a copy of the HTTP command ("get", "post", etc), set *url_out to a copy of the URL, and return 0.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_http_response()

int parse_http_response ( const char *  headers,
int *  code,
time_t *  date,
compress_method_t compression,
char **  reason 
)

Parse an HTTP response string headers of the form

* "HTTP/1.\%d \%d\%s\r\n...".
* 

If it's well-formed, assign the status code to *code and return 0. Otherwise, return -1.

On success: If date is provided, set *date to the Date header in the http headers, or 0 if no such header is found. If compression is provided, set *compression to the compression method given in the Content-Encoding header, or 0 if no such header is found, or -1 if the value of the header is not recognized. If reason is provided, strdup the reason string into it.

◆ parse_http_url()

STATIC int parse_http_url ( const char *  headers,
char **  url 
)

Parse an HTTP request string headers of the form

* "\%s [http[s]://]\%s HTTP/1..."
* 

If it's well-formed, strdup the second %s into *url, and nul-terminate it. If the url doesn't start with "/tor/", rewrite it so it does. Return 0. Otherwise, return -1.

Here is the call graph for this function:

◆ purpose_needs_anonymity()

int purpose_needs_anonymity ( uint8_t  dir_purpose,
uint8_t  router_purpose,
const char *  resource 
)

Return false if the directory purpose dir_purpose does not require an anonymous (three-hop) connection.

Return true 1) by default, 2) if all directory actions have specifically been configured to be over an anonymous connection, or 3) if the router is a bridge

◆ router_supports_extrainfo()

int router_supports_extrainfo ( const char *  identity_digest,
int  is_authority 
)

Return true iff identity_digest is the digest of a router which says that it caches extrainfos. (If is_authority we always believe that to be true.)

◆ should_use_directory_guards()

STATIC int should_use_directory_guards ( const or_options_t options)

Return true iff, according to the values in options, we should be using directory guards for direct downloads of directory information.

◆ warn_disallowed_anonymous_compression_method()

STATIC void warn_disallowed_anonymous_compression_method ( compress_method_t  method)

Log a warning when a remote server has sent us a document using a compression method that is not allowed for anonymous directory requests.