mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-20 10:12:15 +01:00
Implement more control spec functionality
- Mapaddress - Postdescriptor - GetInfo on descriptors Required changes elsewhere: - Keep the most recent running_routers_t in the routerlist_t. That way we can learn about new routers and remember whether we were last told that they were up or down. Also enables more simplifications. - Keep the signed descriptor inside routerinfo_t. This makes descriptor_entry_t in dirservers.c unneeded. - Rename AddressMap (the verb) to MapAddress. Keep AddressMap as a noun. - Check addresses for plausibility before mapping them. svn:r3696
This commit is contained in:
parent
d21f007a84
commit
bbaa3c7792
@ -86,6 +86,8 @@ int tor_snprintf(char *str, size_t size, const char *format, ...)
|
||||
CHECK_PRINTF(3,4);
|
||||
int tor_vsnprintf(char *str, size_t size, const char *format, va_list args);
|
||||
|
||||
#define TOR_ISAPLHA(c) isalpha((int)(unsigned char)(c))
|
||||
#define TOR_ISALNUM(c) isalnum((int)(unsigned char)(c))
|
||||
#define TOR_ISSPACE(c) isspace((int)(unsigned char)(c))
|
||||
#define TOR_ISXDIGIT(c) isxdigit((int)(unsigned char)(c))
|
||||
#define TOR_ISDIGIT(c) isdigit((int)(unsigned char)(c))
|
||||
|
@ -1266,6 +1266,21 @@ tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len)
|
||||
(int)(uint8_t)((a )&0xff));
|
||||
}
|
||||
|
||||
/* DOCDOC */
|
||||
int
|
||||
is_plausible_address(const char *name)
|
||||
{
|
||||
const char *cp;
|
||||
tor_assert(name);
|
||||
/* We could check better here. */
|
||||
for (cp=name; *cp; cp++) {
|
||||
if (*cp != '.' && *cp != '-' && !TOR_ISALNUM(*cp))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* =====
|
||||
* Process helpers
|
||||
* ===== */
|
||||
|
@ -128,6 +128,7 @@ int parse_addr_and_port_range(const char *s, uint32_t *addr_out,
|
||||
uint16_t *port_max_out);
|
||||
#define INET_NTOA_BUF_LEN 16
|
||||
int tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len);
|
||||
int is_plausible_address(const char *name);
|
||||
|
||||
/* Process helpers */
|
||||
void start_daemon(const char *desired_cwd);
|
||||
|
@ -123,7 +123,7 @@ static config_var_t config_vars[] = {
|
||||
VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
|
||||
VAR("TrackHostExits", CSV, TrackHostExits, NULL),
|
||||
VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
|
||||
VAR("AddressMap", LINELIST, AddressMap, NULL),
|
||||
VAR("MapAddress", LINELIST, AddressMap, NULL),
|
||||
VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
|
||||
VAR("FirewallPorts", CSV, FirewallPorts, "80,443"),
|
||||
VAR("MyFamily", STRING, MyFamily, NULL),
|
||||
@ -1824,9 +1824,18 @@ config_register_addressmaps(or_options_t *options) {
|
||||
if (smartlist_len(elts) >= 2) {
|
||||
from = smartlist_get(elts,0);
|
||||
to = smartlist_get(elts,1);
|
||||
addressmap_register(from, tor_strdup(to), 0);
|
||||
if (!is_plausible_address(from)) {
|
||||
log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",from);
|
||||
} else if (!is_plausible_address(to)) {
|
||||
log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",to);
|
||||
} else {
|
||||
addressmap_register(from, tor_strdup(to), 0);
|
||||
if (smartlist_len(elts)>2) {
|
||||
log_fn(LOG_WARN,"Ignoring extra arguments to MapAddress.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_fn(LOG_WARN,"AddressMap '%s' has too few arguments. Ignoring.", opt->value);
|
||||
log_fn(LOG_WARN,"MapAddress '%s' has too few arguments. Ignoring.", opt->value);
|
||||
}
|
||||
SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
|
||||
smartlist_clear(elts);
|
||||
|
@ -117,6 +117,7 @@ static void update_global_event_mask(void);
|
||||
static void send_control_message(connection_t *conn, uint16_t type,
|
||||
uint16_t len, const char *body);
|
||||
static void send_control_done(connection_t *conn);
|
||||
static void send_control_done2(connection_t *conn, const char *msg, size_t len);
|
||||
static void send_control_error(connection_t *conn, uint16_t error,
|
||||
const char *message);
|
||||
static void send_control_event(uint16_t event, uint16_t len, const char *body);
|
||||
@ -192,6 +193,11 @@ send_control_done(connection_t *conn)
|
||||
send_control_message(conn, CONTROL_CMD_DONE, 0, NULL);
|
||||
}
|
||||
|
||||
static void send_control_done2(connection_t *conn, const char *msg, size_t len)
|
||||
{
|
||||
send_control_message(conn, CONTROL_CMD_DONE, len, msg);
|
||||
}
|
||||
|
||||
/** Send an error message with error code <b>error</b> and body
|
||||
* <b>message</b> down the connection <b>conn</b> */
|
||||
static void
|
||||
@ -445,7 +451,46 @@ handle_control_signal(connection_t *conn, uint16_t len,
|
||||
static int
|
||||
handle_control_mapaddress(connection_t *conn, uint16_t len, const char *body)
|
||||
{
|
||||
send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
|
||||
smartlist_t *elts;
|
||||
smartlist_t *lines;
|
||||
smartlist_t *reply;
|
||||
char *r;
|
||||
size_t sz;
|
||||
lines = smartlist_create();
|
||||
elts = smartlist_create();
|
||||
reply = smartlist_create();
|
||||
smartlist_split_string(lines, body, "\n",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
SMARTLIST_FOREACH(lines, const char *, line,
|
||||
{
|
||||
smartlist_split_string(elts, body, " ", 0, 2);
|
||||
if (smartlist_len(elts) == 2) {
|
||||
const char *from = smartlist_get(elts,0);
|
||||
const char *to = smartlist_get(elts,1);
|
||||
if (!is_plausible_address(from)) {
|
||||
log_fn(LOG_WARN,"Skipping invalid argument '%s' in MapAddress msg",from);
|
||||
} else if (!is_plausible_address(to)) {
|
||||
log_fn(LOG_WARN,"Skipping invalid argument '%s' in AddressMap msg",to);
|
||||
} else {
|
||||
addressmap_register(from, tor_strdup(to), 0);
|
||||
smartlist_add(reply, tor_strdup(line));
|
||||
}
|
||||
} else {
|
||||
log_fn(LOG_WARN, "Skipping MapAddress line with wrong number of items.");
|
||||
}
|
||||
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
|
||||
smartlist_clear(elts);
|
||||
});
|
||||
SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
|
||||
smartlist_free(lines);
|
||||
smartlist_free(elts);
|
||||
|
||||
r = smartlist_join_strings(reply, "\n", 1, &sz);
|
||||
send_control_done2(conn,sz,r);
|
||||
|
||||
SMARTLIST_FOREACH(reply, char *, cp, tor_free(cp));
|
||||
smartlist_free(reply);
|
||||
tor_free(r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -455,7 +500,12 @@ handle_getinfo_helper(const char *question)
|
||||
if (!strcmp(question, "version")) {
|
||||
return tor_strdup(VERSION);
|
||||
} else if (!strcmpstart(question, "desc/id/")) {
|
||||
return NULL; /* XXXX */
|
||||
routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
|
||||
if (!ri)
|
||||
return NULL;
|
||||
if (!ri->signed_descriptor)
|
||||
return NULL;
|
||||
return tor_strdup(ri->signed_descriptor);
|
||||
} else if (!strcmp(question, "desc/all-ids")) {
|
||||
routerlist_t *rl;
|
||||
char *answer, *cp;
|
||||
@ -540,7 +590,14 @@ static int
|
||||
handle_control_postdescriptor(connection_t *conn, uint16_t len,
|
||||
const char *body)
|
||||
{
|
||||
send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
|
||||
if (router_load_single_router(body)<0) {
|
||||
/* XXXX a more specific error would be nice. */
|
||||
send_control_error(conn,ERR_UNSPECIFIED,
|
||||
"Could not parse descriptor or add it");
|
||||
return 0;
|
||||
}
|
||||
|
||||
send_control_done(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -723,9 +723,11 @@ connection_dir_client_reached_eof(connection_t *conn)
|
||||
return -1;
|
||||
}
|
||||
router_get_routerlist(&rl);
|
||||
if (rl)
|
||||
routerlist_update_from_runningrouters(rl,rrs);
|
||||
running_routers_free(rrs);
|
||||
if (rl) {
|
||||
routerlist_set_runningrouters(rl,rrs);
|
||||
} else {
|
||||
running_routers_free(rrs);
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->purpose == DIR_PURPOSE_UPLOAD_DIR) {
|
||||
|
101
src/or/dirserv.c
101
src/or/dirserv.c
@ -249,29 +249,12 @@ dirserv_free_fingerprint_list()
|
||||
* Descriptor list
|
||||
*/
|
||||
|
||||
/** A directory server's view of a server descriptor. Contains both
|
||||
* parsed and unparsed versions. */
|
||||
typedef struct descriptor_entry_t {
|
||||
char *nickname;
|
||||
time_t published;
|
||||
size_t desc_len;
|
||||
char *descriptor;
|
||||
int verified;
|
||||
routerinfo_t *router;
|
||||
} descriptor_entry_t;
|
||||
|
||||
/** List of all server descriptors that this dirserv is holding. */
|
||||
/** List of routerinfo_t for all server descriptors that this dirserv
|
||||
* is holding.
|
||||
* XXXX This should eventually get coalesced into routerlist.c
|
||||
*/
|
||||
static smartlist_t *descriptor_list = NULL;
|
||||
|
||||
/** Release the storage held by <b>desc</b> */
|
||||
static void free_descriptor_entry(descriptor_entry_t *desc)
|
||||
{
|
||||
tor_free(desc->descriptor);
|
||||
tor_free(desc->nickname);
|
||||
routerinfo_free(desc->router);
|
||||
tor_free(desc);
|
||||
}
|
||||
|
||||
/** Release all storage that the dirserv is holding for server
|
||||
* descriptors. */
|
||||
void
|
||||
@ -279,8 +262,8 @@ dirserv_free_descriptors()
|
||||
{
|
||||
if (!descriptor_list)
|
||||
return;
|
||||
SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
|
||||
free_descriptor_entry(d));
|
||||
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
|
||||
routerinfo_free(ri));
|
||||
smartlist_clear(descriptor_list);
|
||||
}
|
||||
|
||||
@ -319,12 +302,10 @@ dirserv_router_has_valid_address(routerinfo_t *ri)
|
||||
int
|
||||
dirserv_add_descriptor(const char **desc, const char **msg)
|
||||
{
|
||||
descriptor_entry_t *ent = NULL;
|
||||
routerinfo_t *ri = NULL;
|
||||
routerinfo_t *ri = NULL, *ri_old=NULL;
|
||||
int i, r, found=-1;
|
||||
char *start, *end;
|
||||
char *desc_tmp = NULL;
|
||||
const char *cp;
|
||||
size_t desc_len;
|
||||
time_t now;
|
||||
int verified=1; /* whether we knew its fingerprint already */
|
||||
@ -346,10 +327,10 @@ dirserv_add_descriptor(const char **desc, const char **msg)
|
||||
end = start+strlen(start);
|
||||
}
|
||||
desc_len = end-start;
|
||||
cp = desc_tmp = tor_strndup(start, desc_len);
|
||||
desc_tmp = tor_strndup(start, desc_len); /* Is this strndup still needed???*/
|
||||
|
||||
/* Check: is the descriptor syntactically valid? */
|
||||
ri = router_parse_entry_from_string(cp, NULL);
|
||||
ri = router_parse_entry_from_string(desc_tmp, NULL);
|
||||
tor_free(desc_tmp);
|
||||
if (!ri) {
|
||||
log(LOG_WARN, "Couldn't parse descriptor");
|
||||
@ -402,15 +383,15 @@ dirserv_add_descriptor(const char **desc, const char **msg)
|
||||
|
||||
/* Do we already have an entry for this router? */
|
||||
for (i = 0; i < smartlist_len(descriptor_list); ++i) {
|
||||
ent = smartlist_get(descriptor_list, i);
|
||||
if (!strcasecmp(ri->nickname, ent->nickname)) {
|
||||
ri_old = smartlist_get(descriptor_list, i);
|
||||
if (!strcasecmp(ri->nickname, ri_old->nickname)) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found >= 0) {
|
||||
/* if so, decide whether to update it. */
|
||||
if (ent->published >= ri->published_on) {
|
||||
if (ri_old->published_on >= ri->published_on) {
|
||||
/* We already have a newer or equal-time descriptor */
|
||||
log_fn(LOG_INFO,"We already have a new enough desc for nickname '%s'. Not adding.",ri->nickname);
|
||||
*msg = "We already have a newer descriptor.";
|
||||
@ -419,10 +400,10 @@ dirserv_add_descriptor(const char **desc, const char **msg)
|
||||
*desc = end;
|
||||
return verified;
|
||||
}
|
||||
/* We don't have a newer one; we'll update this one. */
|
||||
/* We don't alrady have a newer one; we'll update this one. */
|
||||
log_fn(LOG_INFO,"Dirserv updating desc for nickname '%s'",ri->nickname);
|
||||
*msg = verified?"Verified server updated":"Unverified server updated. (Have you sent us your key fingerprint?)";
|
||||
free_descriptor_entry(ent);
|
||||
routerinfo_free(ri_old);
|
||||
smartlist_del_keeporder(descriptor_list, found);
|
||||
} else {
|
||||
/* Add at the end. */
|
||||
@ -430,14 +411,8 @@ dirserv_add_descriptor(const char **desc, const char **msg)
|
||||
*msg = verified?"Verified server added":"Unverified server added. (Have you sent us your key fingerprint?)";
|
||||
}
|
||||
|
||||
ent = tor_malloc(sizeof(descriptor_entry_t));
|
||||
ent->nickname = tor_strdup(ri->nickname);
|
||||
ent->published = ri->published_on;
|
||||
ent->desc_len = desc_len;
|
||||
ent->descriptor = tor_strndup(start,desc_len);
|
||||
ent->router = ri;
|
||||
ent->verified = verified;
|
||||
smartlist_add(descriptor_list, ent);
|
||||
ri->is_verified = verified;
|
||||
smartlist_add(descriptor_list, ri);
|
||||
|
||||
*desc = end;
|
||||
directory_set_dirty();
|
||||
@ -453,16 +428,16 @@ static void
|
||||
directory_remove_unrecognized(void)
|
||||
{
|
||||
int i;
|
||||
descriptor_entry_t *ent;
|
||||
routerinfo_t *ent;
|
||||
if (!descriptor_list)
|
||||
descriptor_list = smartlist_create();
|
||||
|
||||
for (i = 0; i < smartlist_len(descriptor_list); ++i) {
|
||||
ent = smartlist_get(descriptor_list, i);
|
||||
if (dirserv_router_fingerprint_is_known(ent->router)<=0) {
|
||||
if (dirserv_router_fingerprint_is_known(ent)<=0) {
|
||||
log(LOG_INFO, "Router '%s' is no longer recognized",
|
||||
ent->nickname);
|
||||
free_descriptor_entry(ent);
|
||||
routerinfo_free(ent);
|
||||
smartlist_del(descriptor_list, i--);
|
||||
}
|
||||
}
|
||||
@ -510,28 +485,27 @@ dirserv_load_from_directory_string(const char *dir)
|
||||
* as running iff <b>is_live</b> is true.
|
||||
*/
|
||||
static char *
|
||||
list_single_server_status(descriptor_entry_t *desc, int is_live,
|
||||
list_single_server_status(routerinfo_t *desc, int is_live,
|
||||
int rr_format)
|
||||
{
|
||||
char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
|
||||
char *cp;
|
||||
|
||||
tor_assert(desc);
|
||||
tor_assert(desc->router);
|
||||
|
||||
cp = buf;
|
||||
if (!is_live) {
|
||||
*cp++ = '!';
|
||||
}
|
||||
if (desc->verified) {
|
||||
if (desc->is_verified) {
|
||||
strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
|
||||
cp += strlen(cp);
|
||||
if (!rr_format)
|
||||
*cp++ = '=';
|
||||
}
|
||||
if (!desc->verified || !rr_format) {
|
||||
if (!desc->is_verified || !rr_format) {
|
||||
*cp++ = '$';
|
||||
base16_encode(cp, HEX_DIGEST_LEN+1, desc->router->identity_digest,
|
||||
base16_encode(cp, HEX_DIGEST_LEN+1, desc->identity_digest,
|
||||
DIGEST_LEN);
|
||||
}
|
||||
return tor_strdup(buf);
|
||||
@ -556,20 +530,19 @@ list_server_status(char **running_routers_out, char **router_status_out)
|
||||
rr_entries = smartlist_create();
|
||||
rs_entries = smartlist_create();
|
||||
|
||||
SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
|
||||
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
|
||||
{
|
||||
int is_live;
|
||||
connection_t *conn;
|
||||
tor_assert(d->router);
|
||||
conn = connection_get_by_identity_digest(
|
||||
d->router->identity_digest, CONN_TYPE_OR);
|
||||
ri->identity_digest, CONN_TYPE_OR);
|
||||
/* Treat a router as alive if
|
||||
* - It's me, and I'm not hibernating.
|
||||
* or - we're connected to it. */
|
||||
is_live = (router_is_me(d->router) && !we_are_hibernating()) ||
|
||||
is_live = (router_is_me(ri) && !we_are_hibernating()) ||
|
||||
(conn && conn->state == OR_CONN_STATE_OPEN);
|
||||
smartlist_add(rr_entries, list_single_server_status(d, is_live, 1));
|
||||
smartlist_add(rs_entries, list_single_server_status(d, is_live, 0));
|
||||
smartlist_add(rr_entries, list_single_server_status(ri, is_live, 1));
|
||||
smartlist_add(rs_entries, list_single_server_status(ri, is_live, 0));
|
||||
});
|
||||
|
||||
if (running_routers_out)
|
||||
@ -593,16 +566,16 @@ dirserv_remove_old_servers(int age)
|
||||
{
|
||||
int i;
|
||||
time_t cutoff;
|
||||
descriptor_entry_t *ent;
|
||||
routerinfo_t *ent;
|
||||
if (!descriptor_list)
|
||||
descriptor_list = smartlist_create();
|
||||
|
||||
cutoff = time(NULL) - age;
|
||||
for (i = 0; i < smartlist_len(descriptor_list); ++i) {
|
||||
ent = smartlist_get(descriptor_list, i);
|
||||
if (ent->published <= cutoff) {
|
||||
if (ent->published_on <= cutoff) {
|
||||
/* descriptor_list[i] is too old. Remove it. */
|
||||
free_descriptor_entry(ent);
|
||||
routerinfo_free(ent);
|
||||
smartlist_del(descriptor_list, i--);
|
||||
directory_set_dirty();
|
||||
}
|
||||
@ -677,8 +650,8 @@ dirserv_dump_directory_to_string(char **dir_out,
|
||||
|
||||
buf_len = 2048+strlen(recommended_versions)+strlen(running_routers)+
|
||||
strlen(router_status);
|
||||
SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
|
||||
buf_len += strlen(d->descriptor));
|
||||
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
|
||||
buf_len += strlen(ri->signed_descriptor));
|
||||
buf = tor_malloc(buf_len);
|
||||
/* We'll be comparing against buf_len throughout the rest of the
|
||||
function, though strictly speaking we shouldn't be able to exceed
|
||||
@ -702,8 +675,8 @@ dirserv_dump_directory_to_string(char **dir_out,
|
||||
i = strlen(buf);
|
||||
cp = buf+i;
|
||||
|
||||
SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
|
||||
if (strlcat(buf, d->descriptor, buf_len) >= buf_len)
|
||||
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
|
||||
if (strlcat(buf, ri->signed_descriptor, buf_len) >= buf_len)
|
||||
goto truncated);
|
||||
|
||||
/* These multiple strlcat calls are inefficient, but dwarfed by the RSA
|
||||
@ -1010,8 +983,8 @@ dirserv_free_all(void)
|
||||
fingerprint_list = NULL;
|
||||
}
|
||||
if (descriptor_list) {
|
||||
SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t*, d,
|
||||
free_descriptor_entry(d));
|
||||
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
|
||||
routerinfo_free(ri));
|
||||
smartlist_free(descriptor_list);
|
||||
descriptor_list = NULL;
|
||||
}
|
||||
|
23
src/or/or.h
23
src/or/or.h
@ -620,6 +620,8 @@ typedef struct addr_policy_t {
|
||||
|
||||
/** Information about another onion router in the network. */
|
||||
typedef struct {
|
||||
char *signed_descriptor; /**< The original signed descriptor for this router*/
|
||||
|
||||
char *address; /**< Location of OR: either a hostname or an IP address. */
|
||||
char *nickname; /**< Human-readable OR name. */
|
||||
|
||||
@ -654,6 +656,14 @@ typedef struct {
|
||||
* claims are its family. */
|
||||
} routerinfo_t;
|
||||
|
||||
/** Contents of a running-routers list */
|
||||
typedef struct running_routers_t {
|
||||
time_t published_on; /**< When was the list marked as published? */
|
||||
/** Which ORs are on the list? Entries may be prefixed with ! and $. */
|
||||
smartlist_t *running_routers;
|
||||
int is_running_routers_format; /**< Are we using the old entry format? */
|
||||
} running_routers_t;
|
||||
|
||||
/** Contents of a directory of onion routers. */
|
||||
typedef struct {
|
||||
/** List of routerinfo_t */
|
||||
@ -665,18 +675,13 @@ typedef struct {
|
||||
*/
|
||||
time_t published_on;
|
||||
time_t running_routers_updated_on;
|
||||
/** DOCDOC
|
||||
*/
|
||||
running_routers_t *running_routers;
|
||||
/** Which router is claimed to have signed it? */
|
||||
char *signing_router;
|
||||
} routerlist_t;
|
||||
|
||||
/** Contents of a running-routers list */
|
||||
typedef struct running_routers_t {
|
||||
time_t published_on; /**< When was the list marked as published? */
|
||||
/** Which ORs are on the list? Entries may be prefixed with ! and $. */
|
||||
smartlist_t *running_routers;
|
||||
int is_running_routers_format; /**< Are we using the old entry format? */
|
||||
} running_routers_t;
|
||||
|
||||
/** Holds accounting information for a single step in the layered encryption
|
||||
* performed by a circuit. Used only at the client edge of a circuit. */
|
||||
struct crypt_path_t {
|
||||
@ -1696,6 +1701,7 @@ void free_trusted_dir_servers(void);
|
||||
routerinfo_t *routerinfo_copy(const routerinfo_t *router);
|
||||
void router_mark_as_down(const char *digest);
|
||||
void routerlist_remove_old_routers(int age);
|
||||
int router_load_single_router(const char *s);
|
||||
int router_load_routerlist_from_directory(const char *s,crypto_pk_env_t *pkey,
|
||||
int dir_is_recent, int dir_is_cached);
|
||||
int router_compare_addr_to_addr_policy(uint32_t addr, uint16_t port,
|
||||
@ -1708,6 +1714,7 @@ int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
|
||||
|
||||
int router_exit_policy_rejects_all(routerinfo_t *router);
|
||||
void running_routers_free(running_routers_t *rr);
|
||||
void routerlist_set_runningrouters(routerlist_t *list, running_routers_t *rr);
|
||||
void routerlist_update_from_runningrouters(routerlist_t *list,
|
||||
running_routers_t *rr);
|
||||
int routers_update_status_from_entry(smartlist_t *routers,
|
||||
|
@ -427,8 +427,6 @@ int router_is_clique_mode(routerinfo_t *router) {
|
||||
|
||||
/** My routerinfo. */
|
||||
static routerinfo_t *desc_routerinfo = NULL;
|
||||
/** String representation of my descriptor, signed by me. */
|
||||
static char descriptor[8192];
|
||||
/** Boolean: do we need to regenerate the above? */
|
||||
static int desc_is_dirty = 1;
|
||||
/** Boolean: do we need to regenerate the above? */
|
||||
@ -527,8 +525,8 @@ const char *router_get_my_descriptor(void) {
|
||||
if (router_rebuild_descriptor(1))
|
||||
return NULL;
|
||||
}
|
||||
log_fn(LOG_DEBUG,"my desc is '%s'",descriptor);
|
||||
return descriptor;
|
||||
log_fn(LOG_DEBUG,"my desc is '%s'",desc_routerinfo->signed_descriptor);
|
||||
return desc_routerinfo->signed_descriptor;
|
||||
}
|
||||
|
||||
/** Rebuild a fresh routerinfo and signed server descriptor for this
|
||||
@ -579,14 +577,17 @@ int router_rebuild_descriptor(int force) {
|
||||
smartlist_split_string(ri->declared_family, options->MyFamily, ",",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
}
|
||||
ri->signed_descriptor = tor_malloc(8192);
|
||||
if (router_dump_router_to_string(ri->signed_descriptor, 8192,
|
||||
ri, get_identity_key())<0) {
|
||||
log_fn(LOG_WARN, "Couldn't dump router to string.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (desc_routerinfo)
|
||||
routerinfo_free(desc_routerinfo);
|
||||
desc_routerinfo = ri;
|
||||
if (router_dump_router_to_string(descriptor, 8192, ri, get_identity_key())<0) {
|
||||
log_fn(LOG_WARN, "Couldn't dump router to string.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc_is_dirty = 0;
|
||||
desc_needs_upload = 1;
|
||||
return 0;
|
||||
|
@ -659,6 +659,7 @@ void routerinfo_free(routerinfo_t *router)
|
||||
if (!router)
|
||||
return;
|
||||
|
||||
tor_free(router->signed_descriptor);
|
||||
tor_free(router->address);
|
||||
tor_free(router->nickname);
|
||||
tor_free(router->platform);
|
||||
@ -713,6 +714,7 @@ void routerlist_free(routerlist_t *rl)
|
||||
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
|
||||
routerinfo_free(r));
|
||||
smartlist_free(rl->routers);
|
||||
running_routers_free(rl->running_routers);
|
||||
tor_free(rl->software_versions);
|
||||
tor_free(rl);
|
||||
}
|
||||
@ -856,6 +858,29 @@ routerlist_remove_old_routers(int age)
|
||||
/*
|
||||
* Code to parse router descriptors and directories.
|
||||
*/
|
||||
int
|
||||
router_load_single_router(const char *s)
|
||||
{
|
||||
routerinfo_t *ri;
|
||||
|
||||
if (!(ri = router_parse_entry_from_string(s, NULL))) {
|
||||
log_fn(LOG_WARN, "Error parsing router descriptor; dropping.");
|
||||
return -1;
|
||||
}
|
||||
if (routerlist && routerlist->running_routers) {
|
||||
running_routers_t *rr = routerlist->running_routers;
|
||||
router_update_status_from_smartlist(ri,
|
||||
rr->published_on,
|
||||
rr->running_routers,
|
||||
rr->is_running_routers_format);
|
||||
}
|
||||
if (router_add_to_routerlist(ri)<0) {
|
||||
log_fn(LOG_WARN, "Couldn't add router to list; dropping.");
|
||||
return -1;
|
||||
}
|
||||
log_fn(LOG_DEBUG, "Added router to list");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Add to the current routerlist each router stored in the
|
||||
* signed directory <b>s</b>. If pkey is provided, check the signature against
|
||||
@ -1137,7 +1162,8 @@ int router_exit_policy_rejects_all(routerinfo_t *router) {
|
||||
/** Release all space held in <b>rr</b>. */
|
||||
void running_routers_free(running_routers_t *rr)
|
||||
{
|
||||
tor_assert(rr);
|
||||
if (!rr)
|
||||
return;
|
||||
if (rr->running_routers) {
|
||||
SMARTLIST_FOREACH(rr->running_routers, char *, s, tor_free(s));
|
||||
smartlist_free(rr->running_routers);
|
||||
@ -1145,6 +1171,17 @@ void running_routers_free(running_routers_t *rr)
|
||||
tor_free(rr);
|
||||
}
|
||||
|
||||
/** DOCDOC*/
|
||||
void
|
||||
routerlist_set_runningrouters(routerlist_t *list, running_routers_t *rr)
|
||||
{
|
||||
routerlist_update_from_runningrouters(list,rr);
|
||||
if (list->running_routers != rr) {
|
||||
running_routers_free(list->running_routers);
|
||||
list->running_routers = rr;
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the running/not-running status of every router in <b>list</b>, based
|
||||
* on the contents of <b>rr</b>. */
|
||||
/* Note: this function is not yet used, since nobody publishes just
|
||||
|
@ -312,6 +312,7 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
char digest[DIGEST_LEN];
|
||||
routerlist_t *new_dir = NULL;
|
||||
char *versions = NULL;
|
||||
int nickname_list_is_running_routers;
|
||||
smartlist_t *good_nickname_list = NULL;
|
||||
time_t published_on;
|
||||
int i, r;
|
||||
@ -426,6 +427,7 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
}
|
||||
}
|
||||
|
||||
nickname_list_is_running_routers = (tok->tp == K_RUNNING_ROUTERS);
|
||||
good_nickname_list = smartlist_create();
|
||||
for (i=0; i<tok->n_args; ++i) {
|
||||
smartlist_add(good_nickname_list, tok->args[i]);
|
||||
@ -459,6 +461,11 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
|
||||
new_dir->software_versions = versions; versions = NULL;
|
||||
new_dir->published_on = published_on;
|
||||
new_dir->running_routers = tor_malloc_zero(sizeof(running_routers_t));
|
||||
new_dir->running_routers->published_on = published_on;
|
||||
new_dir->running_routers->running_routers = good_nickname_list;
|
||||
new_dir->running_routers->is_running_routers_format =
|
||||
nickname_list_is_running_routers;
|
||||
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
|
||||
smartlist_free(tokens);
|
||||
@ -475,16 +482,16 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
if (new_dir)
|
||||
routerlist_free(new_dir);
|
||||
tor_free(versions);
|
||||
if (good_nickname_list) {
|
||||
SMARTLIST_FOREACH(good_nickname_list, char *, n, tor_free(n));
|
||||
smartlist_free(good_nickname_list);
|
||||
}
|
||||
done:
|
||||
if (declared_key) crypto_free_pk_env(declared_key);
|
||||
if (tokens) {
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok));
|
||||
smartlist_free(tokens);
|
||||
}
|
||||
if (good_nickname_list) {
|
||||
SMARTLIST_FOREACH(good_nickname_list, char *, n, tor_free(n));
|
||||
smartlist_free(good_nickname_list);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -802,6 +809,7 @@ routerinfo_t *router_parse_entry_from_string(const char *s,
|
||||
}
|
||||
|
||||
router = tor_malloc_zero(sizeof(routerinfo_t));
|
||||
router->signed_descriptor = tor_strndup(s, end-s);
|
||||
ports_set = bw_set = 0;
|
||||
|
||||
if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
|
||||
|
Loading…
Reference in New Issue
Block a user