mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Add support for knowing multiple HTTP DirPorts for an authority.
(These aren't yet set or used.)
This commit is contained in:
parent
97e51dd01b
commit
4e977cce40
@ -16,6 +16,8 @@
|
||||
#include "core/or/or.h"
|
||||
#include "feature/nodelist/routerstatus_st.h"
|
||||
|
||||
struct smartlist_t;
|
||||
|
||||
/** Represents information about a single trusted or fallback directory
|
||||
* server. */
|
||||
struct dir_server_t {
|
||||
@ -48,6 +50,10 @@ struct dir_server_t {
|
||||
time_t addr_current_at; /**< When was the document that we derived the
|
||||
* address information from published? */
|
||||
|
||||
/** Authority only. Can be null. If present, a list of auth_dirport_t
|
||||
* representing HTTP dirports for this authority. */
|
||||
struct smartlist_t *auth_dirports;
|
||||
|
||||
routerstatus_t fake_status; /**< Used when we need to pass this trusted
|
||||
* dir_server_t to
|
||||
* directory_request_set_routerstatus.
|
||||
|
@ -43,6 +43,14 @@
|
||||
#include "feature/dirclient/dir_server_st.h"
|
||||
#include "feature/nodelist/node_st.h"
|
||||
|
||||
/** Information about an (HTTP) dirport for a directory authority. */
|
||||
struct auth_dirport_t {
|
||||
/** What is the intended usage for this dirport? One of AUTH_USAGE_* */
|
||||
auth_dirport_usage_t usage;
|
||||
/** What is the correct address/port ? */
|
||||
tor_addr_port_t dirport;
|
||||
};
|
||||
|
||||
/** Global list of a dir_server_t object for each directory
|
||||
* authority. */
|
||||
static smartlist_t *trusted_dir_servers = NULL;
|
||||
@ -66,6 +74,11 @@ add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir)
|
||||
/* IPv6 DirPort is not a thing yet for authorities. */
|
||||
nodelist_add_addr_to_address_set(&dir->ipv6_addr, dir->ipv6_orport, 0);
|
||||
}
|
||||
if (dir->auth_dirports) {
|
||||
SMARTLIST_FOREACH_BEGIN(dir->auth_dirports, const auth_dirport_t *, p) {
|
||||
nodelist_add_addr_to_address_set(&p->dirport.addr, 0, p->dirport.port);
|
||||
} SMARTLIST_FOREACH_END(p);
|
||||
}
|
||||
}
|
||||
|
||||
/** Go over the trusted directory server list and add their address(es) to the
|
||||
@ -256,7 +269,10 @@ MOCK_IMPL(int, router_digest_is_trusted_dir_type,
|
||||
/** Return true iff the given address matches a trusted directory that matches
|
||||
* at least one bit of type.
|
||||
*
|
||||
* If type is NO_DIRINFO or ALL_DIRINFO, any authority is matched. */
|
||||
* If type is NO_DIRINFO or ALL_DIRINFO, any authority is matched.
|
||||
*
|
||||
* Only ORPorts' addresses are considered.
|
||||
*/
|
||||
bool
|
||||
router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
|
||||
{
|
||||
@ -404,10 +420,98 @@ trusted_dir_server_new(const char *nickname, const char *address,
|
||||
ipv6_addrport,
|
||||
digest,
|
||||
v3_auth_digest, type, weight);
|
||||
|
||||
if (ipv4_dirport) {
|
||||
tor_addr_port_t p;
|
||||
memset(&p, 0, sizeof(p));
|
||||
tor_addr_copy(&p.addr, &ipv4_addr);
|
||||
p.port = ipv4_dirport;
|
||||
trusted_dir_server_add_dirport(result, AUTH_USAGE_LEGACY, &p);
|
||||
}
|
||||
tor_free(hostname);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add @a dirport as an HTTP DirPort contact point for the directory authority
|
||||
* @a ds, for use when contacting that authority for the given @a usage.
|
||||
*
|
||||
* Multiple ports of the same usage are allowed; if present, then only
|
||||
* the first one of each address family is currently used.
|
||||
*/
|
||||
void
|
||||
trusted_dir_server_add_dirport(dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
const tor_addr_port_t *dirport)
|
||||
{
|
||||
tor_assert(ds);
|
||||
tor_assert(dirport);
|
||||
|
||||
if (BUG(! ds->is_authority)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ds->auth_dirports == NULL) {
|
||||
ds->auth_dirports = smartlist_new();
|
||||
}
|
||||
|
||||
auth_dirport_t *port = tor_malloc_zero(sizeof(auth_dirport_t));
|
||||
port->usage = usage;
|
||||
tor_addr_port_copy(&port->dirport, dirport);
|
||||
smartlist_add(ds->auth_dirports, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for trusted_dir_server_get_dirport: only return the exact requested
|
||||
* usage type.
|
||||
*/
|
||||
static const tor_addr_port_t *
|
||||
trusted_dir_server_get_dirport_exact(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family)
|
||||
{
|
||||
tor_assert(ds);
|
||||
tor_assert_nonfatal(addr_family == AF_INET || addr_family == AF_INET6);
|
||||
if (ds->auth_dirports == NULL)
|
||||
return NULL;
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(ds->auth_dirports, const auth_dirport_t *, port) {
|
||||
if (port->usage == usage &&
|
||||
tor_addr_family(&port->dirport.addr) == addr_family) {
|
||||
return &port->dirport;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(port);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DirPort of the authority @a ds for with the usage type
|
||||
* @a usage and address family @a addr_family. If none is found, try
|
||||
* again with an AUTH_USAGE_LEGACY dirport, if there is one. Return NULL
|
||||
* if no port can be found.
|
||||
*/
|
||||
const tor_addr_port_t *
|
||||
trusted_dir_server_get_dirport(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family)
|
||||
{
|
||||
const tor_addr_port_t *port;
|
||||
|
||||
while (1) {
|
||||
port = trusted_dir_server_get_dirport_exact(ds, usage, addr_family);
|
||||
if (port)
|
||||
return port;
|
||||
|
||||
// If we tried LEGACY, there is no fallback from this point.
|
||||
if (usage == AUTH_USAGE_LEGACY)
|
||||
return NULL;
|
||||
|
||||
// Try again with LEGACY.
|
||||
usage = AUTH_USAGE_LEGACY;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a new dir_server_t for a fallback directory server at
|
||||
* <b>addr</b>:<b>or_port</b>/<b>dir_port</b>, with identity key digest
|
||||
* <b>id_digest</b> */
|
||||
@ -447,6 +551,10 @@ dir_server_free_(dir_server_t *ds)
|
||||
if (!ds)
|
||||
return;
|
||||
|
||||
if (ds->auth_dirports) {
|
||||
SMARTLIST_FOREACH(ds->auth_dirports, auth_dirport_t *, p, tor_free(p));
|
||||
smartlist_free(ds->auth_dirports);
|
||||
}
|
||||
tor_free(ds->nickname);
|
||||
tor_free(ds->description);
|
||||
tor_free(ds->address);
|
||||
|
@ -11,6 +11,28 @@
|
||||
#ifndef TOR_DIRLIST_H
|
||||
#define TOR_DIRLIST_H
|
||||
|
||||
typedef struct auth_dirport_t auth_dirport_t;
|
||||
/**
|
||||
* Different usages for an authority's HTTP directory port.
|
||||
*
|
||||
* Historically, only legacy ports existed; proposal 330 added multiple types
|
||||
* of dirport to better enable authorities to offload work and resist DoS
|
||||
* attacks.
|
||||
**/
|
||||
typedef enum auth_dirport_usage_t {
|
||||
/** Flag for an authority's dirport that is intended for misc/legacy
|
||||
* usage. May be used when no other dirport is available. */
|
||||
AUTH_USAGE_LEGACY,
|
||||
/** Flag for an authority's dirport that is intended for descriptor uploads
|
||||
* only. */
|
||||
AUTH_USAGE_UPLOAD,
|
||||
/** Flag for an authority's dirport that is intended for voting only */
|
||||
AUTH_USAGE_VOTING,
|
||||
/** Flag for an authority's dirport that is intended for relay downloads
|
||||
* only. */
|
||||
AUTH_USAGE_DOWNLOAD,
|
||||
} auth_dirport_usage_t;
|
||||
|
||||
int get_n_authorities(dirinfo_type_t type);
|
||||
const smartlist_t *router_get_trusted_dir_servers(void);
|
||||
const smartlist_t *router_get_fallback_dir_servers(void);
|
||||
@ -28,6 +50,10 @@ MOCK_DECL(dir_server_t *, trusteddirserver_get_by_v3_auth_digest,
|
||||
MOCK_DECL(int, router_digest_is_trusted_dir_type,
|
||||
(const char *digest, dirinfo_type_t type));
|
||||
|
||||
const tor_addr_port_t *trusted_dir_server_get_dirport(const dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
int addr_family);
|
||||
|
||||
bool router_addr_is_trusted_dir_type(const tor_addr_t *addr,
|
||||
dirinfo_type_t type);
|
||||
#define router_addr_is_trusted_dir(d) \
|
||||
@ -41,6 +67,9 @@ dir_server_t *trusted_dir_server_new(const char *nickname, const char *address,
|
||||
const tor_addr_port_t *addrport_ipv6,
|
||||
const char *digest, const char *v3_auth_digest,
|
||||
dirinfo_type_t type, double weight);
|
||||
void trusted_dir_server_add_dirport(dir_server_t *ds,
|
||||
auth_dirport_usage_t usage,
|
||||
const tor_addr_port_t *dirport);
|
||||
dir_server_t *fallback_dir_server_new(const tor_addr_t *addr,
|
||||
uint16_t dir_port, uint16_t or_port,
|
||||
const tor_addr_port_t *addrport_ipv6,
|
||||
|
Loading…
Reference in New Issue
Block a user