mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
r8838@totoro: nickm | 2006-10-02 15:24:39 -0400
Partial implementation of revised nickname syntax for controllers. Implement ability to look up routers by "verbose" nicknames; add a per-v1-control-connection flag to turn the feature on in events. Needs testing, spec, ability to actually turn on the flag, double-checking that we wont overflow any nickname buffers, and changelog. svn:r8582
This commit is contained in:
@@ -44,12 +44,20 @@ x - If the client's clock is too far in the past, it will drop (or
|
||||
o Implement
|
||||
o Note that we'd like a better speed-bump too.
|
||||
o Bug 336: CIRC events should have digests when appropriate.
|
||||
N - figure out the right thing to do when telling nicknames to
|
||||
controllers. We should always give digest, and possibly sometimes give
|
||||
nickname? Or digest, and nickname, with indication of whether name is
|
||||
canonical?
|
||||
N - Improve behavior when telling nicknames and digests to controllers.
|
||||
We should give digest, and nickname, with indication of whether name is
|
||||
canonical.
|
||||
- edmanm likes $DIGEST~nickname for unNamed routers, and
|
||||
$DIGEST=nickname for Named routers. So do I.
|
||||
o Make the code accept it where we currently ask for the nickname of
|
||||
another server. Semantics should be strict to start ($D=N means, "give
|
||||
me the Named server with digest D named N"; $D~N means "give me a
|
||||
server with digest D named N". Nothing else matches.)
|
||||
o Add ability to selectively send 'long' nicknames on v1 connections.
|
||||
- Add a feature to actually turn on the switch.
|
||||
- Verify that everything actually does the right thing.
|
||||
- Specify everything.
|
||||
|
||||
N - Bug 326: make eventdns thrash less.
|
||||
N - Test guard unreachable logic; make sure that we actually attempt to
|
||||
connect to guards that we think are unreachable from time to time.
|
||||
@@ -161,10 +169,10 @@ x - Better estimates in the directory of whether servers have good uptime
|
||||
fractional uptime).
|
||||
- AKA Track uptime as %-of-time-up, as well as time-since-last-down
|
||||
|
||||
- Clients should prefer to avoid exit nodes for non-exit path positions.
|
||||
o Clients should prefer to avoid exit nodes for non-exit path positions.
|
||||
(bug 200)
|
||||
R - spec
|
||||
x - implement
|
||||
o spec
|
||||
o implement
|
||||
|
||||
- Have a "Faster" status flag that means it. Fast2, Fast4, Fast8?
|
||||
x - spec
|
||||
@@ -189,6 +197,15 @@ N - split "router is down" from "dirport shouldn't be tried for a while"?
|
||||
- update dir-spec with what we decided for each of these
|
||||
|
||||
N - provide no-cache no-index headers from the dirport?
|
||||
- Specify
|
||||
- cacheing
|
||||
- Single network-statuses, single descriptors, "all", "authority",
|
||||
and v1 directory stuff are all cacheable for a short time.
|
||||
- Multiple network-statuses or descriptors are not cacheable.
|
||||
- Be sure to be correct wrt HTTP/1.0
|
||||
- indexing
|
||||
- robots.txt
|
||||
- Implement
|
||||
|
||||
- Windows server usability
|
||||
- Solve the ENOBUFS problem.
|
||||
|
||||
@@ -159,6 +159,49 @@ circuit_list_path(origin_circuit_t *circ, int verbose)
|
||||
return s;
|
||||
}
|
||||
|
||||
/* DOCDOC long names only */
|
||||
char *
|
||||
circuit_list_path_for_controller(origin_circuit_t *circ)
|
||||
{
|
||||
smartlist_t *elements = smartlist_create();
|
||||
crypt_path_t *hop;
|
||||
char *elt, *s;
|
||||
routerinfo_t *ri;
|
||||
|
||||
hop = circ->cpath;
|
||||
do {
|
||||
if (!hop)
|
||||
break;
|
||||
if (hop->state != CPATH_STATE_OPEN)
|
||||
break;
|
||||
if (!hop->extend_info)
|
||||
break;
|
||||
elt = tor_malloc(MAX_VERBOSE_NICKNAME_LEN+1);
|
||||
if ((ri = router_get_by_digest(hop->extend_info->identity_digest))) {
|
||||
router_get_verbose_nickname(elt, ri);
|
||||
} else if (hop->extend_info->nickname &&
|
||||
is_legal_nickname(hop->extend_info->nickname)) {
|
||||
elt[0] = '$';
|
||||
base16_encode(elt+1, HEX_DIGEST_LEN+1,
|
||||
hop->extend_info->identity_digest, DIGEST_LEN);
|
||||
elt[HEX_DIGEST_LEN+1]= '~';
|
||||
strlcpy(elt+HEX_DIGEST_LEN+2,
|
||||
hop->extend_info->nickname, MAX_NICKNAME_LEN+1);
|
||||
} else {
|
||||
elt[0] = '$';
|
||||
base16_encode(elt+1, HEX_DIGEST_LEN+1,
|
||||
hop->extend_info->identity_digest, DIGEST_LEN);
|
||||
}
|
||||
smartlist_add(elements, elt);
|
||||
hop = hop->next;
|
||||
} while (hop != circ->cpath);
|
||||
|
||||
s = smartlist_join_strings(elements, ",", 0, NULL);
|
||||
SMARTLIST_FOREACH(elements, char*, cp, tor_free(cp));
|
||||
smartlist_free(elements);
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Log, at severity <b>severity</b>, the nicknames of each router in
|
||||
* circ's cpath. Also log the length of the cpath, and the intended
|
||||
* exit point.
|
||||
|
||||
+91
-37
@@ -111,7 +111,8 @@ static const char * CONTROL0_COMMANDS[_CONTROL0_CMD_MAX_RECOGNIZED+1] = {
|
||||
* list to find out.
|
||||
**/
|
||||
static uint32_t global_event_mask0 = 0;
|
||||
static uint32_t global_event_mask1 = 0;
|
||||
static uint32_t global_event_mask1long = 0;
|
||||
static uint32_t global_event_mask1short = 0;
|
||||
|
||||
/** True iff we have disabled log messages from being sent to the controller */
|
||||
static int disable_log_messages = 0;
|
||||
@@ -119,9 +120,13 @@ static int disable_log_messages = 0;
|
||||
/** Macro: true if any control connection is interested in events of type
|
||||
* <b>e</b>. */
|
||||
#define EVENT_IS_INTERESTING0(e) (global_event_mask0 & (1<<(e)))
|
||||
#define EVENT_IS_INTERESTING1(e) (global_event_mask1 & (1<<(e)))
|
||||
#define EVENT_IS_INTERESTING(e) \
|
||||
((global_event_mask0|global_event_mask1) & (1<<(e)))
|
||||
#define EVENT_IS_INTERESTING1(e) \
|
||||
((global_event_mask1long|global_event_mask1short) & (1<<(e)))
|
||||
#define EVENT_IS_INTERESTING1L(e) (global_event_mask1long & (1<<(e)))
|
||||
#define EVENT_IS_INTERESTING1S(e) (global_event_mask1short & (1<<(e)))
|
||||
#define EVENT_IS_INTERESTING(e) \
|
||||
((global_event_mask0|global_event_mask1short|global_event_mask1long) \
|
||||
& (1<<(e)))
|
||||
|
||||
/** If we're using cookie-type authentication, how long should our cookies be?
|
||||
*/
|
||||
@@ -132,6 +137,10 @@ static int disable_log_messages = 0;
|
||||
static int authentication_cookie_is_set = 0;
|
||||
static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
|
||||
|
||||
typedef enum {
|
||||
SHORT_NAMES,LONG_NAMES,ALL_NAMES
|
||||
} name_type_t;
|
||||
|
||||
static void connection_printf_to_buf(control_connection_t *conn,
|
||||
const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
@@ -148,8 +157,9 @@ static void send_control0_error(control_connection_t *conn, uint16_t error,
|
||||
const char *message);
|
||||
static void send_control0_event(uint16_t event, uint32_t len,
|
||||
const char *body);
|
||||
static void send_control1_event(uint16_t event, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
static void send_control1_event(uint16_t event, name_type_t which,
|
||||
const char *format, ...)
|
||||
CHECK_PRINTF(3,4);
|
||||
static int handle_control_setconf(control_connection_t *conn, uint32_t len,
|
||||
char *body);
|
||||
static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
|
||||
@@ -238,7 +248,8 @@ control_update_global_event_mask(void)
|
||||
connection_t **conns;
|
||||
int n_conns, i;
|
||||
global_event_mask0 = 0;
|
||||
global_event_mask1 = 0;
|
||||
global_event_mask1short = 0;
|
||||
global_event_mask1long = 0;
|
||||
get_connection_array(&conns, &n_conns);
|
||||
for (i = 0; i < n_conns; ++i) {
|
||||
if (conns[i]->type == CONN_TYPE_CONTROL &&
|
||||
@@ -246,8 +257,10 @@ control_update_global_event_mask(void)
|
||||
control_connection_t *conn = TO_CONTROL_CONN(conns[i]);
|
||||
if (STATE_IS_V0(conn->_base.state))
|
||||
global_event_mask0 |= conn->event_mask;
|
||||
else if (conn->use_long_names)
|
||||
global_event_mask1long |= conn->event_mask;
|
||||
else
|
||||
global_event_mask1 |= conn->event_mask;
|
||||
global_event_mask1short |= conn->event_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,7 +600,7 @@ send_control0_event(uint16_t event, uint32_t len, const char *body)
|
||||
/* Send an event to all v1 controllers that are listening for code
|
||||
* <b>event</b>. The event's body is given by <b>msg</b>. */
|
||||
static void
|
||||
send_control1_event_string(uint16_t event, const char *msg)
|
||||
send_control1_event_string(uint16_t event, name_type_t which, const char *msg)
|
||||
{
|
||||
connection_t **conns;
|
||||
int n_conns, i;
|
||||
@@ -600,6 +613,13 @@ send_control1_event_string(uint16_t event, const char *msg)
|
||||
!conns[i]->marked_for_close &&
|
||||
conns[i]->state == CONTROL_CONN_STATE_OPEN_V1) {
|
||||
control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
|
||||
if (which == SHORT_NAMES) {
|
||||
if (control_conn->use_long_names)
|
||||
continue;
|
||||
} else if (which == LONG_NAMES) {
|
||||
if (! control_conn->use_long_names)
|
||||
continue;
|
||||
}
|
||||
if (control_conn->event_mask & (1<<event)) {
|
||||
connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn));
|
||||
if (event == EVENT_ERR_MSG)
|
||||
@@ -616,7 +636,7 @@ send_control1_event_string(uint16_t event, const char *msg)
|
||||
* Currently the length of the message is limited to 1024 (including the
|
||||
* ending \n\r\0. */
|
||||
static void
|
||||
send_control1_event(uint16_t event, const char *format, ...)
|
||||
send_control1_event(uint16_t event, name_type_t which, const char *format, ...)
|
||||
{
|
||||
#define SEND_CONTROL1_EVENT_BUFFERSIZE 1024
|
||||
int r;
|
||||
@@ -636,7 +656,7 @@ send_control1_event(uint16_t event, const char *format, ...)
|
||||
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
|
||||
}
|
||||
|
||||
send_control1_event_string(event, buf);
|
||||
send_control1_event_string(event, which, buf);
|
||||
}
|
||||
|
||||
/** Given a text circuit <b>id</b>, return the corresponding circuit. */
|
||||
@@ -2661,12 +2681,14 @@ connection_control_process_inbuf(control_connection_t *conn)
|
||||
int
|
||||
control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp)
|
||||
{
|
||||
char *path, *msg;
|
||||
char *path=NULL, *msg;
|
||||
if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
|
||||
return 0;
|
||||
tor_assert(circ);
|
||||
|
||||
path = circuit_list_path(circ,0);
|
||||
if (EVENT_IS_INTERESTING0(EVENT_CIRCUIT_STATUS) ||
|
||||
EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS))
|
||||
path = circuit_list_path(circ,0);
|
||||
if (EVENT_IS_INTERESTING0(EVENT_CIRCUIT_STATUS)) {
|
||||
size_t path_len = strlen(path);
|
||||
msg = tor_malloc(1+4+path_len+1); /* event, circid, path, NUL. */
|
||||
@@ -2690,10 +2712,20 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp)
|
||||
log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
|
||||
return 0;
|
||||
}
|
||||
send_control1_event(EVENT_CIRCUIT_STATUS,
|
||||
"650 CIRC %lu %s %s\r\n",
|
||||
(unsigned long)circ->global_identifier,
|
||||
status, path);
|
||||
if (EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS)) {
|
||||
send_control1_event(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
|
||||
"650 CIRC %lu %s %s\r\n",
|
||||
(unsigned long)circ->global_identifier,
|
||||
status, path);
|
||||
}
|
||||
if (EVENT_IS_INTERESTING1L(EVENT_CIRCUIT_STATUS)) {
|
||||
char *vpath = circuit_list_path_for_controller(circ);
|
||||
send_control1_event(EVENT_CIRCUIT_STATUS, LONG_NAMES,
|
||||
"650 CIRC %lu %s %s\r\n",
|
||||
(unsigned long)circ->global_identifier,
|
||||
status, vpath);
|
||||
tor_free(vpath);
|
||||
}
|
||||
}
|
||||
tor_free(path);
|
||||
|
||||
@@ -2766,7 +2798,7 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp)
|
||||
circ = circuit_get_by_edge_conn(conn);
|
||||
if (circ && CIRCUIT_IS_ORIGIN(circ))
|
||||
origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
||||
send_control1_event(EVENT_STREAM_STATUS,
|
||||
send_control1_event(EVENT_STREAM_STATUS, ALL_NAMES,
|
||||
"650 STREAM %lu %s %lu %s\r\n",
|
||||
(unsigned long)conn->global_identifier, status,
|
||||
origin_circ?
|
||||
@@ -2813,7 +2845,7 @@ control_event_or_conn_status(or_connection_t *conn,or_conn_status_event_t tp)
|
||||
log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
|
||||
return 0;
|
||||
}
|
||||
send_control1_event(EVENT_OR_CONN_STATUS,
|
||||
send_control1_event(EVENT_OR_CONN_STATUS, ALL_NAMES/*XXXX NM*/,
|
||||
"650 ORCONN %s %s\r\n",
|
||||
name, status);
|
||||
}
|
||||
@@ -2833,7 +2865,7 @@ control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
|
||||
send_control0_event(EVENT_BANDWIDTH_USED, 8, buf);
|
||||
}
|
||||
if (EVENT_IS_INTERESTING1(EVENT_BANDWIDTH_USED)) {
|
||||
send_control1_event(EVENT_BANDWIDTH_USED,
|
||||
send_control1_event(EVENT_BANDWIDTH_USED, ALL_NAMES,
|
||||
"650 BW %lu %lu\r\n",
|
||||
(unsigned long)n_read,
|
||||
(unsigned long)n_written);
|
||||
@@ -2907,7 +2939,7 @@ control_event_logmsg(int severity, unsigned int domain, const char *msg)
|
||||
default: s = "UnknownLogSeverity"; break;
|
||||
}
|
||||
++disable_log_messages;
|
||||
send_control1_event(event, "650 %s %s\r\n", s, b?b:msg);
|
||||
send_control1_event(event, ALL_NAMES, "650 %s %s\r\n", s, b?b:msg);
|
||||
--disable_log_messages;
|
||||
tor_free(b);
|
||||
}
|
||||
@@ -2922,34 +2954,55 @@ control_event_descriptors_changed(smartlist_t *routers)
|
||||
{
|
||||
size_t len;
|
||||
char *msg;
|
||||
smartlist_t *identities;
|
||||
smartlist_t *identities = NULL;
|
||||
char buf[HEX_DIGEST_LEN+1];
|
||||
|
||||
if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC))
|
||||
return 0;
|
||||
identities = smartlist_create();
|
||||
SMARTLIST_FOREACH(routers, routerinfo_t *, r,
|
||||
{
|
||||
base16_encode(buf,sizeof(buf),r->cache_info.identity_digest,DIGEST_LEN);
|
||||
smartlist_add(identities, tor_strdup(buf));
|
||||
});
|
||||
if (EVENT_IS_INTERESTING0(EVENT_NEW_DESC) ||
|
||||
EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
|
||||
identities = smartlist_create();
|
||||
SMARTLIST_FOREACH(routers, routerinfo_t *, r,
|
||||
{
|
||||
base16_encode(buf,sizeof(buf),r->cache_info.identity_digest,DIGEST_LEN);
|
||||
smartlist_add(identities, tor_strdup(buf));
|
||||
});
|
||||
}
|
||||
if (EVENT_IS_INTERESTING0(EVENT_NEW_DESC)) {
|
||||
msg = smartlist_join_strings(identities, ",", 0, &len);
|
||||
send_control0_event(EVENT_NEW_DESC, len+1, msg);
|
||||
tor_free(msg);
|
||||
}
|
||||
if (EVENT_IS_INTERESTING1(EVENT_NEW_DESC)) {
|
||||
if (EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
|
||||
char *ids = smartlist_join_strings(identities, " ", 0, &len);
|
||||
size_t len = strlen(ids)+32;
|
||||
msg = tor_malloc(len);
|
||||
tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids);
|
||||
send_control1_event_string(EVENT_NEW_DESC, msg);
|
||||
send_control1_event_string(EVENT_NEW_DESC, SHORT_NAMES, msg);
|
||||
tor_free(ids);
|
||||
tor_free(msg);
|
||||
}
|
||||
SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp));
|
||||
smartlist_free(identities);
|
||||
|
||||
if (EVENT_IS_INTERESTING1L(EVENT_NEW_DESC)) {
|
||||
smartlist_t *names;
|
||||
names = smartlist_create();
|
||||
SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
|
||||
char *b = tor_malloc(MAX_VERBOSE_NICKNAME_LEN+1);
|
||||
smartlist_add(names, b);
|
||||
});
|
||||
char *ids = smartlist_join_strings(names, " ", 0, &len);
|
||||
size_t len = strlen(ids)+32;
|
||||
msg = tor_malloc(len);
|
||||
tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids);
|
||||
send_control1_event_string(EVENT_NEW_DESC, LONG_NAMES, msg);
|
||||
tor_free(ids);
|
||||
tor_free(msg);
|
||||
SMARTLIST_FOREACH(names, char *, cp, tor_free(cp));
|
||||
smartlist_free(names);
|
||||
}
|
||||
if (identities) {
|
||||
SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp));
|
||||
smartlist_free(identities);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2962,12 +3015,13 @@ control_event_address_mapped(const char *from, const char *to, time_t expires)
|
||||
return 0;
|
||||
|
||||
if (expires < 3)
|
||||
send_control1_event(EVENT_ADDRMAP,
|
||||
send_control1_event(EVENT_ADDRMAP, ALL_NAMES,
|
||||
"650 ADDRMAP %s %s NEVER\r\n", from, to);
|
||||
else {
|
||||
char buf[ISO_TIME_LEN+1];
|
||||
format_local_iso_time(buf,expires);
|
||||
send_control1_event(EVENT_ADDRMAP, "650 ADDRMAP %s %s \"%s\"\r\n",
|
||||
send_control1_event(EVENT_ADDRMAP, ALL_NAMES,
|
||||
"650 ADDRMAP %s %s \"%s\"\r\n",
|
||||
from, to, buf);
|
||||
}
|
||||
|
||||
@@ -3005,7 +3059,7 @@ control_event_or_authdir_new_descriptor(const char *action,
|
||||
buf = tor_malloc(totallen);
|
||||
strlcpy(buf, firstline, totallen);
|
||||
strlcpy(buf+strlen(firstline), esc, totallen);
|
||||
send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, buf);
|
||||
send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES, buf);
|
||||
|
||||
tor_free(esc);
|
||||
tor_free(buf);
|
||||
@@ -3018,7 +3072,7 @@ control_event_or_authdir_new_descriptor(const char *action,
|
||||
int
|
||||
control_event_my_descriptor_changed(void)
|
||||
{
|
||||
send_control1_event(EVENT_DESCCHANGED, "650 DESCCHANGED\r\n");
|
||||
send_control1_event(EVENT_DESCCHANGED, ALL_NAMES, "650 DESCCHANGED\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,9 @@
|
||||
#define MAX_NICKNAME_LEN 19
|
||||
/* Hex digest plus dollar sign. */
|
||||
#define MAX_HEX_NICKNAME_LEN (HEX_DIGEST_LEN+1)
|
||||
/* $Hexdigest=nickname */
|
||||
#define MAX_VERBOSE_NICKNAME_LEN (1+HEX_DIGEST_LEN+1+MAX_NICKNAME_LEN)
|
||||
|
||||
/** Maximum size, in bytes, for resized buffers. */
|
||||
#define MAX_BUF_SIZE ((1<<24)-1)
|
||||
#define MAX_DIR_SIZE MAX_BUF_SIZE
|
||||
@@ -783,6 +786,9 @@ typedef struct control_connection_t {
|
||||
|
||||
uint32_t event_mask; /**< Bitfield: which events does this controller
|
||||
* care about? */
|
||||
unsigned int use_long_names:1; /**< True if we should use long nicknames
|
||||
* on this (v1) connection. Only settable
|
||||
* via v1 controllers. */
|
||||
uint32_t incoming_cmd_len;
|
||||
uint32_t incoming_cmd_cur_len;
|
||||
char *incoming_cmd;
|
||||
@@ -1680,6 +1686,7 @@ void assert_buf_ok(buf_t *buf);
|
||||
/********************************* circuitbuild.c **********************/
|
||||
|
||||
char *circuit_list_path(origin_circuit_t *circ, int verbose);
|
||||
char *circuit_list_path_for_controller(origin_circuit_t *circ);
|
||||
void circuit_log_path(int severity, unsigned int domain,
|
||||
origin_circuit_t *circ);
|
||||
void circuit_rep_hist_note_result(origin_circuit_t *circ);
|
||||
@@ -2504,6 +2511,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||
int is_legal_nickname(const char *s);
|
||||
int is_legal_nickname_or_hexdigest(const char *s);
|
||||
int is_legal_hexdigest(const char *s);
|
||||
void router_get_verbose_nickname(char *buf, routerinfo_t *router);
|
||||
void router_reset_warnings(void);
|
||||
void router_free_all(void);
|
||||
|
||||
@@ -2547,6 +2555,7 @@ typedef enum {
|
||||
V1_AUTHORITY, V2_AUTHORITY, HIDSERV_AUTHORITY,
|
||||
} authority_type_t;
|
||||
routerstatus_t *router_pick_trusteddirserver(authority_type_t type,
|
||||
|
||||
int requireother,
|
||||
int fascistfirewall,
|
||||
int retry_if_no_servers);
|
||||
|
||||
+22
-2
@@ -1306,8 +1306,28 @@ is_legal_hexdigest(const char *s)
|
||||
tor_assert(s);
|
||||
if (s[0] == '$') s++;
|
||||
len = strlen(s);
|
||||
return (len == HEX_DIGEST_LEN &&
|
||||
strspn(s,HEX_CHARACTERS)==len);
|
||||
if (len > HEX_DIGEST_LEN) {
|
||||
if (s[HEX_DIGEST_LEN] == '=' ||
|
||||
s[HEX_DIGEST_LEN] == '~') {
|
||||
if (!is_legal_nickname(s+HEX_DIGEST_LEN+1))
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return (len >= HEX_DIGEST_LEN &&
|
||||
strspn(s,HEX_CHARACTERS)==HEX_DIGEST_LEN);
|
||||
}
|
||||
|
||||
/** DOCDOC buf must have MAX_VERBOSE_NICKNAME_LEN+1 bytes. */
|
||||
void
|
||||
router_get_verbose_nickname(char *buf, routerinfo_t *router)
|
||||
{
|
||||
buf[0] = '$';
|
||||
base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest,
|
||||
DIGEST_LEN);
|
||||
buf[1+HEX_DIGEST_LEN] = router->is_named ? '=' : '~';
|
||||
strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1);
|
||||
}
|
||||
|
||||
/** Forget that we have issued any router-related warnings, so that we'll
|
||||
|
||||
+39
-6
@@ -1033,12 +1033,24 @@ static INLINE int
|
||||
router_hex_digest_matches(routerinfo_t *router, const char *hexdigest)
|
||||
{
|
||||
char digest[DIGEST_LEN];
|
||||
size_t len;
|
||||
tor_assert(hexdigest);
|
||||
if (hexdigest[0] == '$')
|
||||
++hexdigest;
|
||||
|
||||
if (strlen(hexdigest) != HEX_DIGEST_LEN ||
|
||||
base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
|
||||
len = strlen(hexdigest);
|
||||
if (len < HEX_DIGEST_LEN)
|
||||
return 0;
|
||||
else if (len > HEX_DIGEST_LEN &&
|
||||
(hexdigest[HEX_DIGEST_LEN] == '=' ||
|
||||
hexdigest[HEX_DIGEST_LEN] == '~')) {
|
||||
if (strcasecmp(hexdigest+HEX_DIGEST_LEN+1, router->nickname))
|
||||
return 0;
|
||||
if (hexdigest[HEX_DIGEST_LEN] == '=' && !router->is_named)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
|
||||
return 0;
|
||||
return (!memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN));
|
||||
}
|
||||
@@ -1079,7 +1091,7 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
|
||||
!strcasecmp(nickname, get_options()->Nickname))
|
||||
return router_get_my_routerinfo();
|
||||
|
||||
maybedigest = (strlen(nickname) == HEX_DIGEST_LEN) &&
|
||||
maybedigest = (strlen(nickname) >= HEX_DIGEST_LEN) &&
|
||||
(base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
|
||||
|
||||
if (named_server_map &&
|
||||
@@ -1096,7 +1108,10 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
|
||||
} else if (maybedigest &&
|
||||
!memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN)
|
||||
) {
|
||||
return router;
|
||||
if (router_hex_digest_matches(router, nickname))
|
||||
return router;
|
||||
else
|
||||
best_match = router; // XXXX NM not exactly right.
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1190,17 +1205,35 @@ routerinfo_t *
|
||||
router_get_by_hexdigest(const char *hexdigest)
|
||||
{
|
||||
char digest[DIGEST_LEN];
|
||||
size_t len;
|
||||
routerinfo_t *ri;
|
||||
|
||||
tor_assert(hexdigest);
|
||||
if (!routerlist)
|
||||
return NULL;
|
||||
if (hexdigest[0]=='$')
|
||||
++hexdigest;
|
||||
if (strlen(hexdigest) != HEX_DIGEST_LEN ||
|
||||
len = strlen(hexdigest);
|
||||
if (len < HEX_DIGEST_LEN ||
|
||||
base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0)
|
||||
return NULL;
|
||||
|
||||
return router_get_by_digest(digest);
|
||||
ri = router_get_by_digest(digest);
|
||||
|
||||
if (len > HEX_DIGEST_LEN) {
|
||||
if (hexdigest[HEX_DIGEST_LEN] == '=') {
|
||||
if (strcasecmp(ri->nickname, hexdigest+HEX_DIGEST_LEN+1) ||
|
||||
!ri->is_named)
|
||||
return NULL;
|
||||
} else if (hexdigest[HEX_DIGEST_LEN] == '~') {
|
||||
if (strcasecmp(ri->nickname, hexdigest+HEX_DIGEST_LEN+1))
|
||||
return NULL;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ri;
|
||||
}
|
||||
|
||||
/** Return the router in our routerlist whose 20-byte key digest
|
||||
|
||||
+22
-1
@@ -1269,19 +1269,40 @@ test_dir_format(void)
|
||||
test_assert( is_legal_nickname("a"));
|
||||
test_assert(!is_legal_nickname(""));
|
||||
test_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
|
||||
test_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
|
||||
test_assert(!is_legal_nickname("hyphen-")); /* bad char */
|
||||
test_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
|
||||
test_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
|
||||
/* valid */
|
||||
test_assert( is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
|
||||
test_assert( is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
|
||||
test_assert( is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
|
||||
/* too short */
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
|
||||
/* illegal char */
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
|
||||
/* hex part too long */
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
|
||||
/* Bad nickname */
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
|
||||
"abcdefghijklmnoppqrst"));
|
||||
/* Bad extra char. */
|
||||
test_assert(!is_legal_nickname_or_hexdigest(
|
||||
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
|
||||
test_assert(is_legal_nickname_or_hexdigest("xyzzy"));
|
||||
test_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
|
||||
test_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
|
||||
|
||||
Reference in New Issue
Block a user