2010-07-22 12:09:49 +02:00
|
|
|
/* Copyright (c) 2001 Matej Pfajfar.
|
|
|
|
* Copyright (c) 2001-2004, Roger Dingledine.
|
|
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
2020-01-08 18:39:17 -05:00
|
|
|
* Copyright (c) 2007-2020, The Tor Project, Inc. */
|
2010-07-22 12:09:49 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \file dirserv.h
|
|
|
|
* \brief Header file for dirserv.c.
|
|
|
|
**/
|
|
|
|
|
2012-10-12 12:13:10 -04:00
|
|
|
#ifndef TOR_DIRSERV_H
|
|
|
|
#define TOR_DIRSERV_H
|
2010-07-22 12:09:49 +02:00
|
|
|
|
2018-07-01 13:04:21 -04:00
|
|
|
struct ed25519_public_key_t;
|
|
|
|
|
2018-06-21 13:12:23 -04:00
|
|
|
#include "lib/testsupport/testsupport.h"
|
2013-06-06 17:58:28 -04:00
|
|
|
|
2017-03-13 15:38:20 -04:00
|
|
|
/** Ways to convert a spoolable_resource_t to a bunch of bytes. */
|
|
|
|
typedef enum dir_spool_source_t {
|
|
|
|
DIR_SPOOL_SERVER_BY_DIGEST=1, DIR_SPOOL_SERVER_BY_FP,
|
|
|
|
DIR_SPOOL_EXTRA_BY_DIGEST, DIR_SPOOL_EXTRA_BY_FP,
|
|
|
|
DIR_SPOOL_MICRODESC,
|
|
|
|
DIR_SPOOL_NETWORKSTATUS,
|
2017-04-16 17:47:28 -04:00
|
|
|
DIR_SPOOL_CONSENSUS_CACHE_ENTRY,
|
2017-03-13 15:38:20 -04:00
|
|
|
} dir_spool_source_t;
|
|
|
|
#define dir_spool_source_bitfield_t ENUM_BF(dir_spool_source_t)
|
|
|
|
|
|
|
|
/** Object to remember the identity of an object that we are spooling,
|
|
|
|
* or about to spool, in response to a directory request.
|
|
|
|
*
|
|
|
|
* (Why do we spool? Because some directory responses are very large,
|
|
|
|
* and we don't want to just shove the complete answer into the output
|
|
|
|
* buffer: that would take a ridiculous amount of RAM.)
|
|
|
|
*
|
|
|
|
* If the spooled resource is relatively small (like microdescriptors,
|
|
|
|
* descriptors, etc), we look them up by ID as needed, and add the whole
|
|
|
|
* thing onto the output buffer at once. If the spooled reseource is
|
|
|
|
* big (like networkstatus documents), we reference-count it, and add it
|
|
|
|
* a few K at a time.
|
|
|
|
*/
|
|
|
|
typedef struct spooled_resource_t {
|
|
|
|
/**
|
|
|
|
* If true, we add the entire object to the outbuf. If false,
|
|
|
|
* we spool the object a few K at a time.
|
|
|
|
*/
|
|
|
|
unsigned spool_eagerly : 1;
|
|
|
|
/**
|
|
|
|
* Tells us what kind of object to get, and how to look it up.
|
|
|
|
*/
|
|
|
|
dir_spool_source_bitfield_t spool_source : 7;
|
|
|
|
/**
|
|
|
|
* Tells us the specific object to spool.
|
|
|
|
*/
|
|
|
|
uint8_t digest[DIGEST256_LEN];
|
|
|
|
/**
|
|
|
|
* A large object that we're spooling. Holds a reference count. Only
|
|
|
|
* used when spool_eagerly is false.
|
|
|
|
*/
|
|
|
|
struct cached_dir_t *cached_dir_ref;
|
|
|
|
/**
|
2017-04-16 17:47:28 -04:00
|
|
|
* A different kind of large object that we might be spooling. Also
|
|
|
|
* reference-counted. Also only used when spool_eagerly is false.
|
|
|
|
*/
|
|
|
|
struct consensus_cache_entry_t *consensus_cache_entry;
|
|
|
|
const uint8_t *cce_body;
|
|
|
|
size_t cce_len;
|
|
|
|
/**
|
|
|
|
* The current offset into cached_dir or cce_body. Only used when
|
|
|
|
* spool_eagerly is false */
|
2017-03-13 15:38:20 -04:00
|
|
|
off_t cached_dir_offset;
|
|
|
|
} spooled_resource_t;
|
|
|
|
|
2010-07-22 12:09:49 +02:00
|
|
|
int connection_dirserv_flushed_some(dir_connection_t *conn);
|
|
|
|
|
2020-01-08 21:24:26 -05:00
|
|
|
enum dir_spool_source_t;
|
|
|
|
int dir_split_resource_into_spoolable(const char *resource,
|
|
|
|
enum dir_spool_source_t source,
|
|
|
|
smartlist_t *spool_out,
|
|
|
|
int *compressed_out,
|
|
|
|
int flags);
|
|
|
|
|
2020-01-15 12:30:43 -05:00
|
|
|
#ifdef HAVE_MODULE_DIRCACHE
|
2020-01-15 12:45:56 -05:00
|
|
|
/** Is the dircache module enabled? */
|
|
|
|
#define have_module_dircache() (1)
|
2012-03-30 15:20:06 -04:00
|
|
|
int directory_caches_unknown_auth_certs(const or_options_t *options);
|
2011-06-14 13:01:38 -04:00
|
|
|
int directory_caches_dir_info(const or_options_t *options);
|
|
|
|
int directory_permits_begindir_requests(const or_options_t *options);
|
2019-09-17 00:11:18 +05:30
|
|
|
MOCK_DECL(cached_dir_t *, dirserv_get_consensus, (const char *flavor_name));
|
2010-07-22 12:09:49 +02:00
|
|
|
void dirserv_set_cached_consensus_networkstatus(const char *consensus,
|
2018-10-24 11:06:34 -04:00
|
|
|
size_t consensus_len,
|
2016-02-10 15:35:46 -05:00
|
|
|
const char *flavor_name,
|
|
|
|
const common_digests_t *digests,
|
2017-05-03 10:17:37 -04:00
|
|
|
const uint8_t *sha3_as_signed,
|
2016-02-10 15:35:46 -05:00
|
|
|
time_t published);
|
2020-01-15 12:30:43 -05:00
|
|
|
#else
|
2020-01-15 12:45:56 -05:00
|
|
|
#define have_module_dircache() (0)
|
2020-01-15 12:30:43 -05:00
|
|
|
#define directory_caches_unknown_auth_certs(opt) \
|
|
|
|
((void)(opt), 0)
|
|
|
|
#define directory_caches_dir_info(opt) \
|
|
|
|
((void)(opt), 0)
|
|
|
|
#define directory_permits_begindir_requests(opt) \
|
|
|
|
((void)(opt), 0)
|
|
|
|
#define dirserv_get_consensus(flav) \
|
|
|
|
((void)(flav), NULL)
|
|
|
|
#define dirserv_set_cached_consensus_networkstatus(a,b,c,d,e,f) \
|
|
|
|
STMT_BEGIN { \
|
|
|
|
(void)(a); \
|
|
|
|
(void)(b); \
|
|
|
|
(void)(c); \
|
|
|
|
(void)(d); \
|
|
|
|
(void)(e); \
|
|
|
|
(void)(f); \
|
|
|
|
} STMT_END
|
|
|
|
#endif
|
|
|
|
|
2010-07-22 12:09:49 +02:00
|
|
|
void dirserv_clear_old_networkstatuses(time_t cutoff);
|
2017-03-13 15:38:20 -04:00
|
|
|
int dirserv_get_routerdesc_spool(smartlist_t *spools_out, const char *key,
|
|
|
|
dir_spool_source_t source,
|
2018-01-24 14:25:15 +05:30
|
|
|
int conn_is_encrypted,
|
2017-03-13 15:38:20 -04:00
|
|
|
const char **msg_out);
|
Initial conversion to use node_t throughout our codebase.
A node_t is an abstraction over routerstatus_t, routerinfo_t, and
microdesc_t. It should try to present a consistent interface to all
of them. There should be a node_t for a server whenever there is
* A routerinfo_t for it in the routerlist
* A routerstatus_t in the current_consensus.
(note that a microdesc_t alone isn't enough to make a node_t exist,
since microdescriptors aren't usable on their own.)
There are three ways to get a node_t right now: looking it up by ID,
looking it up by nickname, and iterating over the whole list of
microdescriptors.
All (or nearly all) functions that are supposed to return "a router"
-- especially those used in building connections and circuits --
should return a node_t, not a routerinfo_t or a routerstatus_t.
A node_t should hold all the *mutable* flags about a node. This
patch moves the is_foo flags from routerinfo_t into node_t. The
flags in routerstatus_t remain, but they get set from the consensus
and should not change.
Some other highlights of this patch are:
* Looking up routerinfo and routerstatus by nickname is now
unified and based on the "look up a node by nickname" function.
This tries to look only at the values from current consensus,
and not get confused by the routerinfo_t->is_named flag, which
could get set for other weird reasons. This changes the
behavior of how authorities (when acting as clients) deal with
nodes that have been listed by nickname.
* I tried not to artificially increase the size of the diff here
by moving functions around. As a result, some functions that
now operate on nodes are now in the wrong file -- they should
get moved to nodelist.c once this refactoring settles down.
This moving should happen as part of a patch that moves
functions AND NOTHING ELSE.
* Some old code is now left around inside #if 0/1 blocks, and
should get removed once I've verified that I don't want it
sitting around to see how we used to do things.
There are still some unimplemented functions: these are flagged
with "UNIMPLEMENTED_NODELIST()." I'll work on filling in the
implementation here, piece by piece.
I wish this patch could have been smaller, but there did not seem to
be any piece of it that was independent from the rest. Moving flags
forces many functions that once returned routerinfo_t * to return
node_t *, which forces their friends to change, and so on.
2010-09-29 15:00:41 -04:00
|
|
|
|
2010-07-22 12:09:49 +02:00
|
|
|
void dirserv_free_all(void);
|
|
|
|
void cached_dir_decref(cached_dir_t *d);
|
|
|
|
cached_dir_t *new_cached_dir(char *s, time_t published);
|
2015-01-29 14:54:47 +00:00
|
|
|
|
2017-03-13 15:38:20 -04:00
|
|
|
spooled_resource_t *spooled_resource_new(dir_spool_source_t source,
|
|
|
|
const uint8_t *digest,
|
|
|
|
size_t digestlen);
|
2017-04-16 17:47:28 -04:00
|
|
|
spooled_resource_t *spooled_resource_new_from_cache_entry(
|
|
|
|
struct consensus_cache_entry_t *entry);
|
2017-11-21 09:37:47 -05:00
|
|
|
void spooled_resource_free_(spooled_resource_t *spooled);
|
2017-12-07 10:52:55 -05:00
|
|
|
#define spooled_resource_free(sp) \
|
|
|
|
FREE_AND_NULL(spooled_resource_t, spooled_resource_free_, (sp))
|
2017-03-13 15:38:20 -04:00
|
|
|
void dirserv_spool_remove_missing_and_guess_size(dir_connection_t *conn,
|
|
|
|
time_t cutoff,
|
|
|
|
int compression,
|
2017-03-28 21:41:59 +02:00
|
|
|
size_t *size_out,
|
2017-03-13 15:38:20 -04:00
|
|
|
int *n_expired_out);
|
|
|
|
void dirserv_spool_sort(dir_connection_t *conn);
|
|
|
|
void dir_conn_clear_spool(dir_connection_t *conn);
|
|
|
|
|
2017-09-15 16:24:44 -04:00
|
|
|
#endif /* !defined(TOR_DIRSERV_H) */
|