Finish most pre2 items: make running-routers list work right; rename secret key files; make even more lookup-by-nickname use lookup-by-id; default nicknames to hostname.

svn:r2043
This commit is contained in:
Nick Mathewson 2004-07-13 18:23:40 +00:00
parent e9365f9ed5
commit c2103eb63a
9 changed files with 185 additions and 87 deletions

View File

@ -27,10 +27,6 @@ NICK pre1:
o make ORs parse-and-keep-and-serve the directory they pull down o make ORs parse-and-keep-and-serve the directory they pull down
o authoritativedirservers should pull down directories from o authoritativedirservers should pull down directories from
other authdirservers, to merge descriptors. other authdirservers, to merge descriptors.
D Have clients and dirservers preserve reputation info over
reboots.
[Deferred until we know what reputation info we actually want to
maintain. Our current algorithm Couldn't Possibly Work.]
. allow dirservers to serve running-router list separately. . allow dirservers to serve running-router list separately.
o "get /running-routers" will fetch just this. o "get /running-routers" will fetch just this.
o actually make the clients use this sometimes. o actually make the clients use this sometimes.
@ -50,23 +46,25 @@ NICK pre1:
o write tor version at the top of each log file o write tor version at the top of each log file
pre2: pre2:
- refer to things by key: . refer to things by key:
o extend cells need ip:port:identitykeyhash. o extend cells need ip:port:identitykeyhash.
. Lookup routers and connections by key digest; accept hex o Lookup routers and connections by key digest; accept hex
key digest in place of nicknames. key digest in place of nicknames.
. Audit all uses of lookup-by-hostname and lookup-by-addr-port o Audit all uses of lookup-by-hostname and lookup-by-addr-port
to search by digest when appropriate. to search by digest when appropriate.
- Rep-hist functions o Rep-hist functions need to store info by keyid
- also use this in intro points and rendezvous points, and - also use this in intro points and rendezvous points, and
hidserv descs. [XXXX This isn't enough.] hidserv descs. [XXXX This isn't enough.]
- figure out what to do about ip:port:differentkey - figure out what to do about ip:port:differentkey
o ORs connect on demand. attach circuits to new connections, keep o ORs connect on demand. attach circuits to new connections, keep
create cells around somewhere, send destroy if fail. create cells around somewhere, send destroy if fail.
- nickname defaults to first piece of hostname o nickname defaults to first piece of hostname
- running-routers list refers to nickname if verified, else o running-routers list refers to nickname if verified, else
hash-base64'ed. hash-base64'ed.
- Mark routers as verified or unverified based on whether
running-routers list includes nickname or id hash.
o put OR uptime in descriptor o put OR uptime in descriptor
- name the secret-key directory something to discourage people o name the secret-key directory something to discourage people
from mailing their identity key to tor-ops from mailing their identity key to tor-ops
pre3: pre3:
@ -83,6 +81,10 @@ NICK pre1:
- start counting again if your IP ever changes. - start counting again if your IP ever changes.
- never regenerate identity keys, for now. - never regenerate identity keys, for now.
- you can set a bit for not-being-an-OR. - you can set a bit for not-being-an-OR.
- Reputation info needs to give better weight to recent events than
very old ones.
- Have clients and dirservers preserve reputation info over
reboots.
- clients choose nodes proportional to advertised bandwidth - clients choose nodes proportional to advertised bandwidth
- authdirserver includes descriptor and lists as running iff: - authdirserver includes descriptor and lists as running iff:
- he can connect to you - he can connect to you

View File

@ -102,7 +102,7 @@ void circuit_log_path(int severity, circuit_t *circ) {
*/ */
void circuit_rep_hist_note_result(circuit_t *circ) { void circuit_rep_hist_note_result(circuit_t *circ) {
struct crypt_path_t *hop; struct crypt_path_t *hop;
char *prev_nickname = NULL; char *prev_digest = NULL;
routerinfo_t *router; routerinfo_t *router;
hop = circ->cpath; hop = circ->cpath;
if(!hop) { if(!hop) {
@ -114,22 +114,22 @@ void circuit_rep_hist_note_result(circuit_t *circ) {
return; return;
} }
if (options.ORPort) { if (options.ORPort) {
prev_nickname = options.Nickname; prev_digest = router_get_my_routerinfo()->identity_digest;
} }
do { do {
router = router_get_by_digest(hop->identity_digest); router = router_get_by_digest(hop->identity_digest);
if (router) { if (router) {
if (prev_nickname) { if (prev_digest) {
if (hop->state == CPATH_STATE_OPEN) if (hop->state == CPATH_STATE_OPEN)
rep_hist_note_extend_succeeded(prev_nickname, router->nickname); rep_hist_note_extend_succeeded(prev_digest, router->identity_digest);
else { else {
rep_hist_note_extend_failed(prev_nickname, router->nickname); rep_hist_note_extend_failed(prev_digest, router->identity_digest);
break; break;
} }
} }
prev_nickname = router->nickname; prev_digest = router->identity_digest;
} else { } else {
prev_nickname = NULL; prev_digest = NULL;
} }
hop=hop->next; hop=hop->next;
} while (hop!=circ->cpath); } while (hop!=circ->cpath);
@ -445,6 +445,8 @@ int circuit_extend(cell_t *cell, circuit_t *circ) {
relay_header_unpack(&rh, cell->payload); relay_header_unpack(&rh, cell->payload);
if (rh.length == 4+2+ONIONSKIN_CHALLENGE_LEN) { if (rh.length == 4+2+ONIONSKIN_CHALLENGE_LEN) {
/* Once this format is no longer supported, nobody will use
* connection_*_get_by_addr_port. */
old_format = 1; old_format = 1;
} else if (rh.length == 4+2+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN) { } else if (rh.length == 4+2+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN) {
old_format = 0; old_format = 0;

View File

@ -467,6 +467,40 @@ static int resolve_my_address(or_options_t *options) {
return 0; return 0;
} }
static char *get_default_nickname(void)
{
char localhostname[256];
char *cp, *out, *outp;
if(gethostname(localhostname,sizeof(localhostname)) < 0) {
log_fn(LOG_WARN,"Error obtaining local hostname");
return NULL;
}
/* Put it in lowercase; stop at the first dot. */
for(cp = localhostname; *cp; ++cp) {
if (*cp == '.') {
*cp = '\0';
break;
}
*cp = tolower(*cp);
}
/* Strip invalid characters. */
cp = localhostname;
out = outp = tor_malloc(strlen(localhostname)+1);
while (*cp) {
if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
*outp++ = *cp++;
else
cp++;
}
*outp = '\0';
/* Enforce length. */
if (strlen(out) > MAX_NICKNAME_LEN)
out[MAX_NICKNAME_LEN]='\0';
return out;
}
/** Release storage held by <b>options</b> */ /** Release storage held by <b>options</b> */
static void free_options(or_options_t *options) { static void free_options(or_options_t *options) {
config_free_lines(options->LogOptions); config_free_lines(options->LogOptions);
@ -633,8 +667,9 @@ int getconfig(int argc, char **argv, or_options_t *options) {
if (options->ORPort) { if (options->ORPort) {
if (options->Nickname == NULL) { if (options->Nickname == NULL) {
log_fn(LOG_WARN,"Nickname required if ORPort is set, but not found."); if (!(options->Nickname = get_default_nickname()))
result = -1; return -1;
log_fn(LOG_INFO, "Choosing default nickname %s", options->Nickname);
} else { } else {
if (strspn(options->Nickname, LEGAL_NICKNAME_CHARACTERS) != if (strspn(options->Nickname, LEGAL_NICKNAME_CHARACTERS) !=
strlen(options->Nickname)) { strlen(options->Nickname)) {

View File

@ -192,13 +192,13 @@ void connection_about_to_close_connection(connection_t *conn)
if (conn->state != OR_CONN_STATE_OPEN) { if (conn->state != OR_CONN_STATE_OPEN) {
/* XXX Nick: this still isn't right, because it might be /* XXX Nick: this still isn't right, because it might be
* dying even though we didn't initiate the connect. Can * dying even though we didn't initiate the connect. Can
* you look at this more? -RD */ * you look at this more? -RD XXXX008 -NM*/
if(conn->nickname) if(conn->nickname)
rep_hist_note_connect_failed(conn->nickname, time(NULL)); rep_hist_note_connect_failed(conn->identity_digest, time(NULL));
} else if (0) { // XXX reason == CLOSE_REASON_UNUSED_OR_CONN) { } else if (0) { // XXX reason == CLOSE_REASON_UNUSED_OR_CONN) {
rep_hist_note_disconnect(conn->nickname, time(NULL)); rep_hist_note_disconnect(conn->identity_digest, time(NULL));
} else { } else {
rep_hist_note_connection_died(conn->nickname, time(NULL)); rep_hist_note_connection_died(conn->identity_digest, time(NULL));
} }
break; break;
case CONN_TYPE_AP: case CONN_TYPE_AP:

View File

@ -329,7 +329,7 @@ connection_tls_finish_handshake(connection_t *conn) {
directory_set_dirty(); directory_set_dirty();
circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */ circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
/* Note the success */ /* Note the success */
rep_hist_note_connect_succeeded(nickname, time(NULL)); rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
return 0; return 0;
} }

View File

@ -19,7 +19,7 @@ extern or_options_t options; /* command-line and config-file options */
#define MIN_CPUWORKERS 1 #define MIN_CPUWORKERS 1
/** The tag specifies which circuit this onionskin was from. */ /** The tag specifies which circuit this onionskin was from. */
#define TAG_LEN 8 #define TAG_LEN (DIGEST_LEN+2)
/** How many bytes are sent from tor to the cpuworker? */ /** How many bytes are sent from tor to the cpuworker? */
#define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN) #define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN)
/** How many bytes are sent from the cpuworker back to tor? */ /** How many bytes are sent from the cpuworker back to tor? */
@ -55,23 +55,17 @@ int connection_cpu_finished_flushing(connection_t *conn) {
/** Pack addr,port,and circ_id; set *tag to the result. (See note on /** Pack addr,port,and circ_id; set *tag to the result. (See note on
* cpuworker_main for wire format.) */ * cpuworker_main for wire format.) */
static void tag_pack(char *tag, uint32_t addr, uint16_t port, uint16_t circ_id) { static void tag_pack(char *tag, uint16_t circ_id, const char *identity_digest){
*(uint32_t *)tag = addr; *(uint16_t *)(tag) = circ_id;
*(uint16_t *)(tag+4) = port; memcpy(tag+2, identity_digest, DIGEST_LEN);
*(uint16_t *)(tag+6) = circ_id;
} }
/** Unpack <b>tag</b> into addr, port, and circ_id. /** Unpack <b>tag</b> into addr, port, and circ_id.
*/ */
static void tag_unpack(const char *tag, uint32_t *addr, uint16_t *port, uint16_t *circ_id) { static void tag_unpack(const char *tag, uint16_t *circ_id,
struct in_addr in; char *identity_digest) {
*circ_id = *(const uint16_t *)(tag);
*addr = *(const uint32_t *)tag; memcpy(identity_digest, tag+2, DIGEST_LEN);
*port = *(const uint16_t *)(tag+4);
*circ_id = *(const uint16_t *)(tag+6);
in.s_addr = htonl(*addr);
log_fn(LOG_DEBUG,"onion was from %s:%d, circ_id %d.", inet_ntoa(in), *port, *circ_id);
} }
/** Called when the onion key has changed and we need to spawn new /** Called when the onion key has changed and we need to spawn new
@ -98,11 +92,10 @@ void cpuworkers_rotate(void)
int connection_cpu_process_inbuf(connection_t *conn) { int connection_cpu_process_inbuf(connection_t *conn) {
char success; char success;
unsigned char buf[LEN_ONION_RESPONSE]; unsigned char buf[LEN_ONION_RESPONSE];
uint32_t addr;
uint16_t port;
uint16_t circ_id; uint16_t circ_id;
connection_t *p_conn; connection_t *p_conn;
circuit_t *circ; circuit_t *circ;
char identity_digest[DIGEST_LEN];
tor_assert(conn && conn->type == CONN_TYPE_CPUWORKER); tor_assert(conn && conn->type == CONN_TYPE_CPUWORKER);
@ -130,11 +123,11 @@ int connection_cpu_process_inbuf(connection_t *conn) {
connection_fetch_from_buf(buf,LEN_ONION_RESPONSE-1,conn); connection_fetch_from_buf(buf,LEN_ONION_RESPONSE-1,conn);
/* parse out the circ it was talking about */ /* parse out the circ it was talking about */
tag_unpack(buf, &addr, &port, &circ_id); tag_unpack(buf, &circ_id, identity_digest);
circ = NULL; circ = NULL;
/* XXXX This is actually right: we want a specific port here in /* XXXX This is actually right: we want a specific port here in
* case there are multiple connections. */ * case there are multiple connections. */
p_conn = connection_exact_get_by_addr_port(addr,port); p_conn = connection_get_by_identity_digest(identity_digest,CONN_TYPE_OR);
if(p_conn) if(p_conn)
circ = circuit_get_by_circ_id_conn(circ_id, p_conn); circ = circuit_get_by_circ_id_conn(circ_id, p_conn);
@ -358,7 +351,7 @@ int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type,
log_fn(LOG_INFO,"circ->p_conn gone. Failing circ."); log_fn(LOG_INFO,"circ->p_conn gone. Failing circ.");
return -1; return -1;
} }
tag_pack(tag, circ->p_conn->addr, circ->p_conn->port, circ->p_circ_id); tag_pack(tag, circ->p_circ_id, circ->p_conn->identity_digest);
cpuworker->state = CPUWORKER_STATE_BUSY_ONION; cpuworker->state = CPUWORKER_STATE_BUSY_ONION;
num_cpuworkers_busy++; num_cpuworkers_busy++;

View File

@ -181,16 +181,25 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router)
/** Return true iff any router named <b>nickname</b> is in the fingerprint /** Return true iff any router named <b>nickname</b> is in the fingerprint
* list. */ * list. */
static int static int
router_nickname_is_approved(const char *nickname) router_nickname_is_approved(const char *nickname, const char *digest)
{ {
int i; int i,j;
fingerprint_entry_t *ent; fingerprint_entry_t *ent;
char fp[FINGERPRINT_LEN+1];
if (!fingerprint_list) if (!fingerprint_list)
return 0; return 0;
for (i=j=0;i<DIGEST_LEN;++i,++j) {
fp[i]=digest[j];
if ((j%4)==3 && j != 19)
fp[++i]=' ';
}
fp[i]='\0';
for (i=0;i<smartlist_len(fingerprint_list);++i) { for (i=0;i<smartlist_len(fingerprint_list);++i) {
ent = smartlist_get(fingerprint_list, i); ent = smartlist_get(fingerprint_list, i);
if (!strcasecmp(nickname,ent->nickname)) { if (!strcasecmp(nickname,ent->nickname) &&
!strcasecmp(fp,ent->fingerprint)) {
return 1; return 1;
} }
} }
@ -227,6 +236,7 @@ typedef struct descriptor_entry_t {
time_t published; time_t published;
size_t desc_len; size_t desc_len;
char *descriptor; char *descriptor;
int verified;
routerinfo_t *router; routerinfo_t *router;
} descriptor_entry_t; } descriptor_entry_t;
@ -368,6 +378,7 @@ dirserv_add_descriptor(const char **desc)
strncpy(ent->descriptor, start, desc_len); strncpy(ent->descriptor, start, desc_len);
ent->descriptor[desc_len] = '\0'; ent->descriptor[desc_len] = '\0';
ent->router = ri; ent->router = ri;
ent->verified = 1; /* XXXX008 support other possibilities. */
smartlist_add(descriptor_list, ent); smartlist_add(descriptor_list, ent);
*desc = end; *desc = end;
@ -447,19 +458,25 @@ list_running_servers(char **nicknames_out)
*nicknames_out = NULL; *nicknames_out = NULL;
nicknames_up = smartlist_create(); nicknames_up = smartlist_create();
nicknames_down = smartlist_create(); nicknames_down = smartlist_create();
smartlist_add(nicknames_up, options.Nickname); smartlist_add(nicknames_up, tor_strdup(options.Nickname));
get_connection_array(&connection_array, &n_conns); get_connection_array(&connection_array, &n_conns);
for (i = 0; i<n_conns; ++i) { for (i = 0; i<n_conns; ++i) {
char *name;
conn = connection_array[i]; conn = connection_array[i];
if (conn->type != CONN_TYPE_OR || !conn->nickname) if (conn->type != CONN_TYPE_OR || !conn->nickname)
continue; /* only list ORs. */ continue; /* only list ORs. */
if (!router_nickname_is_approved(conn->nickname)) if (router_nickname_is_approved(conn->nickname, conn->identity_digest)) {
continue; /* If we removed them from the approved list, don't list it.*/ name = tor_strdup(conn->nickname);
} else {
name = tor_malloc(HEX_DIGEST_LEN+1);
base16_encode(name, HEX_DIGEST_LEN, conn->identity_digest, DIGEST_LEN);
}
if(conn->state == OR_CONN_STATE_OPEN) if(conn->state == OR_CONN_STATE_OPEN)
smartlist_add(nicknames_up, conn->nickname); smartlist_add(nicknames_up, name);
else else
smartlist_add(nicknames_down, conn->nickname); smartlist_add(nicknames_down, name);
} }
length = smartlist_len(nicknames_up) + length = smartlist_len(nicknames_up) +
2*smartlist_len(nicknames_down) + 1; 2*smartlist_len(nicknames_down) + 1;
@ -481,6 +498,8 @@ list_running_servers(char **nicknames_out)
while (*cp) while (*cp)
++cp; ++cp;
} }
SMARTLIST_FOREACH(nicknames_up, char *, victim, tor_free(victim));
SMARTLIST_FOREACH(nicknames_down, char *, victim, tor_free(victim));
smartlist_free(nicknames_up); smartlist_free(nicknames_up);
smartlist_free(nicknames_down); smartlist_free(nicknames_down);
return 0; return 0;

View File

@ -7,6 +7,8 @@
* \brief Basic history functionality for reputation module. * \brief Basic history functionality for reputation module.
**/ **/
/* DOCDOC references to 'nicknames' in docs here are mostly wrong. */
#include "or.h" #include "or.h"
/** History of an OR-\>OR link. */ /** History of an OR-\>OR link. */
@ -47,15 +49,18 @@ static strmap_t *history_map = NULL;
/** Return the or_history_t for the named OR, creating it if necessary. /** Return the or_history_t for the named OR, creating it if necessary.
*/ */
static or_history_t *get_or_history(const char* nickname) static or_history_t *get_or_history(const char* id)
{ {
or_history_t *hist; or_history_t *hist;
hist = (or_history_t*) strmap_get(history_map, nickname); char hexid[HEX_DIGEST_LEN+1];
base16_encode(hexid, HEX_DIGEST_LEN+1, id, DIGEST_LEN);
hist = (or_history_t*) strmap_get(history_map, hexid);
if (!hist) { if (!hist) {
hist = tor_malloc_zero(sizeof(or_history_t)); hist = tor_malloc_zero(sizeof(or_history_t));
hist->link_history_map = strmap_new(); hist->link_history_map = strmap_new();
hist->since = time(NULL); hist->since = time(NULL);
strmap_set(history_map, nickname, hist); strmap_set(history_map, hexid, hist);
} }
return hist; return hist;
} }
@ -63,17 +68,19 @@ static or_history_t *get_or_history(const char* nickname)
/** Return the link_history_t for the link from the first named OR to /** Return the link_history_t for the link from the first named OR to
* the second, creating it if necessary. * the second, creating it if necessary.
*/ */
static link_history_t *get_link_history(const char *from_name, static link_history_t *get_link_history(const char *from_id,
const char *to_name) const char *to_id)
{ {
or_history_t *orhist; or_history_t *orhist;
link_history_t *lhist; link_history_t *lhist;
orhist = get_or_history(from_name); char to_hexid[HEX_DIGEST_LEN+1];
lhist = (link_history_t*) strmap_get(orhist->link_history_map, to_name); orhist = get_or_history(from_id);
base16_encode(to_hexid, HEX_DIGEST_LEN+1, to_id, DIGEST_LEN);
lhist = (link_history_t*) strmap_get(orhist->link_history_map, to_hexid);
if (!lhist) { if (!lhist) {
lhist = tor_malloc_zero(sizeof(link_history_t)); lhist = tor_malloc_zero(sizeof(link_history_t));
lhist->since = time(NULL); lhist->since = time(NULL);
strmap_set(orhist->link_history_map, to_name, lhist); strmap_set(orhist->link_history_map, to_hexid, lhist);
} }
return lhist; return lhist;
} }
@ -104,10 +111,10 @@ void rep_hist_init(void)
/** Remember that an attempt to connect to the OR <b>nickname</b> failed at /** Remember that an attempt to connect to the OR <b>nickname</b> failed at
* <b>when</b>. * <b>when</b>.
*/ */
void rep_hist_note_connect_failed(const char* nickname, time_t when) void rep_hist_note_connect_failed(const char* id, time_t when)
{ {
or_history_t *hist; or_history_t *hist;
hist = get_or_history(nickname); hist = get_or_history(id);
++hist->n_conn_fail; ++hist->n_conn_fail;
if (hist->up_since) { if (hist->up_since) {
hist->uptime += (when - hist->up_since); hist->uptime += (when - hist->up_since);
@ -120,10 +127,10 @@ void rep_hist_note_connect_failed(const char* nickname, time_t when)
/** Remember that an attempt to connect to the OR <b>nickname</b> succeeded /** Remember that an attempt to connect to the OR <b>nickname</b> succeeded
* at <b>when</b>. * at <b>when</b>.
*/ */
void rep_hist_note_connect_succeeded(const char* nickname, time_t when) void rep_hist_note_connect_succeeded(const char* id, time_t when)
{ {
or_history_t *hist; or_history_t *hist;
hist = get_or_history(nickname); hist = get_or_history(id);
++hist->n_conn_ok; ++hist->n_conn_ok;
if (hist->down_since) { if (hist->down_since) {
hist->downtime += (when - hist->down_since); hist->downtime += (when - hist->down_since);
@ -136,10 +143,10 @@ void rep_hist_note_connect_succeeded(const char* nickname, time_t when)
/** Remember that we intentionally closed our connection to the OR /** Remember that we intentionally closed our connection to the OR
* <b>nickname</b> at <b>when</b>. * <b>nickname</b> at <b>when</b>.
*/ */
void rep_hist_note_disconnect(const char* nickname, time_t when) void rep_hist_note_disconnect(const char* id, time_t when)
{ {
or_history_t *hist; or_history_t *hist;
hist = get_or_history(nickname); hist = get_or_history(id);
++hist->n_conn_ok; ++hist->n_conn_ok;
if (hist->up_since) { if (hist->up_since) {
hist->uptime += (when - hist->up_since); hist->uptime += (when - hist->up_since);
@ -147,20 +154,21 @@ void rep_hist_note_disconnect(const char* nickname, time_t when)
} }
} }
/** Remember that our connection to the OR <b>nickname</b> had an error and /** Remember that our connection to the OR <b>id</b> had an error and
* stopped working at <b>when</b>. * stopped working at <b>when</b>.
*/ */
void rep_hist_note_connection_died(const char* nickname, time_t when) void rep_hist_note_connection_died(const char* id, time_t when)
{ {
or_history_t *hist; or_history_t *hist;
if(!nickname) { if(!id) {
/* XXXX008 not so. */
/* If conn has no nickname, it's either an OP, or it is an OR /* If conn has no nickname, it's either an OP, or it is an OR
* which didn't complete its handshake (or did and was unapproved). * which didn't complete its handshake (or did and was unapproved).
* Ignore it. * Ignore it.
*/ */
return; return;
} }
hist = get_or_history(nickname); hist = get_or_history(id);
if (hist->up_since) { if (hist->up_since) {
hist->uptime += (when - hist->up_since); hist->uptime += (when - hist->up_since);
hist->up_since = 0; hist->up_since = 0;
@ -172,23 +180,23 @@ void rep_hist_note_connection_died(const char* nickname, time_t when)
/** Remember that we successfully extended from the OR <b>from_name</b> to /** Remember that we successfully extended from the OR <b>from_name</b> to
* the OR <b>to_name</b>. * the OR <b>to_name</b>.
*/ */
void rep_hist_note_extend_succeeded(const char *from_name, void rep_hist_note_extend_succeeded(const char *from_id,
const char *to_name) const char *to_id)
{ {
link_history_t *hist; link_history_t *hist;
/* log_fn(LOG_WARN, "EXTEND SUCCEEDED: %s->%s",from_name,to_name); */ /* log_fn(LOG_WARN, "EXTEND SUCCEEDED: %s->%s",from_name,to_name); */
hist = get_link_history(from_name, to_name); hist = get_link_history(from_id, to_id);
++hist->n_extend_ok; ++hist->n_extend_ok;
} }
/** Remember that we tried to extend from the OR <b>from_name</b> to the OR /** Remember that we tried to extend from the OR <b>from_name</b> to the OR
* <b>to_name</b>, but failed. * <b>to_name</b>, but failed.
*/ */
void rep_hist_note_extend_failed(const char *from_name, const char *to_name) void rep_hist_note_extend_failed(const char *from_id, const char *to_id)
{ {
link_history_t *hist; link_history_t *hist;
/* log_fn(LOG_WARN, "EXTEND FAILED: %s->%s",from_name,to_name); */ /* log_fn(LOG_WARN, "EXTEND FAILED: %s->%s",from_name,to_name); */
hist = get_link_history(from_name, to_name); hist = get_link_history(from_id, to_id);
++hist->n_extend_fail; ++hist->n_extend_fail;
} }
@ -199,7 +207,7 @@ void rep_hist_dump_stats(time_t now, int severity)
{ {
strmap_iter_t *lhist_it; strmap_iter_t *lhist_it;
strmap_iter_t *orhist_it; strmap_iter_t *orhist_it;
const char *name1, *name2; const char *name1, *name2, *hexdigest1, *hexdigest2;
or_history_t *or_history; or_history_t *or_history;
link_history_t *link_history; link_history_t *link_history;
void *or_history_p, *link_history_p; void *or_history_p, *link_history_p;
@ -207,14 +215,20 @@ void rep_hist_dump_stats(time_t now, int severity)
char buffer[2048]; char buffer[2048];
int len; int len;
unsigned long upt, downt; unsigned long upt, downt;
routerinfo_t *r;
log(severity, "--------------- Dumping history information:"); log(severity, "--------------- Dumping history information:");
for (orhist_it = strmap_iter_init(history_map); !strmap_iter_done(orhist_it); for (orhist_it = strmap_iter_init(history_map); !strmap_iter_done(orhist_it);
orhist_it = strmap_iter_next(history_map,orhist_it)) { orhist_it = strmap_iter_next(history_map,orhist_it)) {
strmap_iter_get(orhist_it, &name1, &or_history_p); strmap_iter_get(orhist_it, &hexdigest1, &or_history_p);
or_history = (or_history_t*) or_history_p; or_history = (or_history_t*) or_history_p;
if ((r = router_get_by_hexdigest(hexdigest1)))
name1 = r->nickname;
else
name1 = "(unknown)";
update_or_history(or_history, now); update_or_history(or_history, now);
upt = or_history->uptime; upt = or_history->uptime;
downt = or_history->downtime; downt = or_history->downtime;
@ -224,8 +238,8 @@ void rep_hist_dump_stats(time_t now, int severity)
uptime=1.0; uptime=1.0;
} }
log(severity, log(severity,
"OR %s: %ld/%ld good connections; uptime %ld/%ld sec (%.2f%%)", "OR %s [%s]: %ld/%ld good connections; uptime %ld/%ld sec (%.2f%%)",
name1, name1, hexdigest1,
or_history->n_conn_ok, or_history->n_conn_fail+or_history->n_conn_ok, or_history->n_conn_ok, or_history->n_conn_fail+or_history->n_conn_ok,
upt, upt+downt, uptime*100.0); upt, upt+downt, uptime*100.0);
@ -234,7 +248,12 @@ void rep_hist_dump_stats(time_t now, int severity)
for (lhist_it = strmap_iter_init(or_history->link_history_map); for (lhist_it = strmap_iter_init(or_history->link_history_map);
!strmap_iter_done(lhist_it); !strmap_iter_done(lhist_it);
lhist_it = strmap_iter_next(or_history->link_history_map, lhist_it)) { lhist_it = strmap_iter_next(or_history->link_history_map, lhist_it)) {
strmap_iter_get(lhist_it, &name2, &link_history_p); strmap_iter_get(lhist_it, &hexdigest2, &link_history_p);
if ((r = router_get_by_hexdigest(hexdigest2)))
name2 = r->nickname;
else
name2 = "(unknown)";
link_history = (link_history_t*) link_history_p; link_history = (link_history_t*) link_history_p;
len += snprintf(buffer+len, 2048-len, "%s(%ld/%ld); ", name2, len += snprintf(buffer+len, 2048-len, "%s(%ld/%ld); ", name2,
link_history->n_extend_ok, link_history->n_extend_ok,
@ -275,7 +294,6 @@ void write_rep_history(const char *filename)
name1, or_history->since1, name1, or_history->since1,
} }
done: done:
if (f) if (f)
fclose(f); fclose(f);

View File

@ -124,6 +124,32 @@ void rotate_onion_key(void)
log_fn(LOG_WARN, "Couldn't rotate onion key."); log_fn(LOG_WARN, "Couldn't rotate onion key.");
} }
/* Read an RSA secret key key from a file that was once named fname_old,
* but is now named fname_new. Rename the file from old to new as needed.
*/
crypto_pk_env_t *init_key_from_file_name_changed(const char *fname_old,
const char *fname_new)
{
int fs;
fs = file_status(fname_new);
if (fs == FN_FILE)
/* The new filename is there. */
return init_key_from_file(fname_new);
fs = file_status(fname_old);
if (fs != FN_FILE)
/* There is no key under either name. */
return init_key_from_file(fname_new);
/* The old filename exists, and the new one doesn't. Rename and load. */
if (rename(fname_old, fname_new) < 0) {
log_fn(LOG_ERR, "Couldn't rename %s to %s: %s", fname_old, fname_new,
strerror(errno));
return NULL;
}
return init_key_from_file(fname_new);
}
/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist, /** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist,
* create a new RSA key and save it in <b>fname</b>. Return the read/created * create a new RSA key and save it in <b>fname</b>. Return the read/created
* key, or NULL on error. * key, or NULL on error.
@ -182,6 +208,7 @@ crypto_pk_env_t *init_key_from_file(const char *fname)
*/ */
int init_keys(void) { int init_keys(void) {
char keydir[512]; char keydir[512];
char keydir2[512];
char fingerprint[FINGERPRINT_LEN+MAX_NICKNAME_LEN+3]; char fingerprint[FINGERPRINT_LEN+MAX_NICKNAME_LEN+3];
char *cp; char *cp;
const char *tmp, *mydesc, *datadir; const char *tmp, *mydesc, *datadir;
@ -217,15 +244,17 @@ int init_keys(void) {
cp = keydir + strlen(keydir); /* End of string. */ cp = keydir + strlen(keydir); /* End of string. */
/* 1. Read identity key. Make it if none is found. */ /* 1. Read identity key. Make it if none is found. */
strcpy(cp, "/identity.key"); sprintf(keydir,"%s/keys/identity.key",datadir);
log_fn(LOG_INFO,"Reading/making identity key %s...",keydir); sprintf(keydir2,"%s/keys/secret_id_key",datadir);
prkey = init_key_from_file(keydir); log_fn(LOG_INFO,"Reading/making identity key %s...",keydir2);
prkey = init_key_from_file_name_changed(keydir,keydir2);
if (!prkey) return -1; if (!prkey) return -1;
set_identity_key(prkey); set_identity_key(prkey);
/* 2. Read onion key. Make it if none is found. */ /* 2. Read onion key. Make it if none is found. */
strcpy(cp, "/onion.key"); sprintf(keydir,"%s/keys/onion.key",datadir);
log_fn(LOG_INFO,"Reading/making onion key %s...",keydir); sprintf(keydir2,"%s/keys/secret_onion_key",datadir);
prkey = init_key_from_file(keydir); log_fn(LOG_INFO,"Reading/making onion key %s...",keydir2);
prkey = init_key_from_file_name_changed(keydir,keydir2);
if (!prkey) return -1; if (!prkey) return -1;
set_onion_key(prkey); set_onion_key(prkey);