mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +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 "core/or/or.h"
|
||||||
#include "feature/nodelist/routerstatus_st.h"
|
#include "feature/nodelist/routerstatus_st.h"
|
||||||
|
|
||||||
|
struct smartlist_t;
|
||||||
|
|
||||||
/** Represents information about a single trusted or fallback directory
|
/** Represents information about a single trusted or fallback directory
|
||||||
* server. */
|
* server. */
|
||||||
struct dir_server_t {
|
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
|
time_t addr_current_at; /**< When was the document that we derived the
|
||||||
* address information from published? */
|
* 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
|
routerstatus_t fake_status; /**< Used when we need to pass this trusted
|
||||||
* dir_server_t to
|
* dir_server_t to
|
||||||
* directory_request_set_routerstatus.
|
* directory_request_set_routerstatus.
|
||||||
|
@ -43,6 +43,14 @@
|
|||||||
#include "feature/dirclient/dir_server_st.h"
|
#include "feature/dirclient/dir_server_st.h"
|
||||||
#include "feature/nodelist/node_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
|
/** Global list of a dir_server_t object for each directory
|
||||||
* authority. */
|
* authority. */
|
||||||
static smartlist_t *trusted_dir_servers = NULL;
|
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. */
|
/* IPv6 DirPort is not a thing yet for authorities. */
|
||||||
nodelist_add_addr_to_address_set(&dir->ipv6_addr, dir->ipv6_orport, 0);
|
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
|
/** 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
|
/** Return true iff the given address matches a trusted directory that matches
|
||||||
* at least one bit of type.
|
* 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
|
bool
|
||||||
router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
|
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,
|
ipv6_addrport,
|
||||||
digest,
|
digest,
|
||||||
v3_auth_digest, type, weight);
|
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);
|
tor_free(hostname);
|
||||||
return result;
|
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
|
/** 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>addr</b>:<b>or_port</b>/<b>dir_port</b>, with identity key digest
|
||||||
* <b>id_digest</b> */
|
* <b>id_digest</b> */
|
||||||
@ -447,6 +551,10 @@ dir_server_free_(dir_server_t *ds)
|
|||||||
if (!ds)
|
if (!ds)
|
||||||
return;
|
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->nickname);
|
||||||
tor_free(ds->description);
|
tor_free(ds->description);
|
||||||
tor_free(ds->address);
|
tor_free(ds->address);
|
||||||
|
@ -11,6 +11,28 @@
|
|||||||
#ifndef TOR_DIRLIST_H
|
#ifndef TOR_DIRLIST_H
|
||||||
#define 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);
|
int get_n_authorities(dirinfo_type_t type);
|
||||||
const smartlist_t *router_get_trusted_dir_servers(void);
|
const smartlist_t *router_get_trusted_dir_servers(void);
|
||||||
const smartlist_t *router_get_fallback_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,
|
MOCK_DECL(int, router_digest_is_trusted_dir_type,
|
||||||
(const char *digest, dirinfo_type_t 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,
|
bool router_addr_is_trusted_dir_type(const tor_addr_t *addr,
|
||||||
dirinfo_type_t type);
|
dirinfo_type_t type);
|
||||||
#define router_addr_is_trusted_dir(d) \
|
#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 tor_addr_port_t *addrport_ipv6,
|
||||||
const char *digest, const char *v3_auth_digest,
|
const char *digest, const char *v3_auth_digest,
|
||||||
dirinfo_type_t type, double weight);
|
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,
|
dir_server_t *fallback_dir_server_new(const tor_addr_t *addr,
|
||||||
uint16_t dir_port, uint16_t or_port,
|
uint16_t dir_port, uint16_t or_port,
|
||||||
const tor_addr_port_t *addrport_ipv6,
|
const tor_addr_port_t *addrport_ipv6,
|
||||||
|
Loading…
Reference in New Issue
Block a user