diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-07-13 18:23:40 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-07-13 18:23:40 +0000 |
commit | c2103eb63a15d2bb840e4ce7932ff12f21c95145 (patch) | |
tree | cc2ec74c32ea0957ac351cb0dea5ea3e774c412a /src/or | |
parent | e9365f9ed58c783efe93abe020fd6f53e0068a8b (diff) | |
download | tor-c2103eb63a15d2bb840e4ce7932ff12f21c95145.tar tor-c2103eb63a15d2bb840e4ce7932ff12f21c95145.tar.gz |
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
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 16 | ||||
-rw-r--r-- | src/or/config.c | 39 | ||||
-rw-r--r-- | src/or/connection.c | 8 | ||||
-rw-r--r-- | src/or/connection_or.c | 2 | ||||
-rw-r--r-- | src/or/cpuworker.c | 31 | ||||
-rw-r--r-- | src/or/dirserv.c | 35 | ||||
-rw-r--r-- | src/or/rephist.c | 76 | ||||
-rw-r--r-- | src/or/router.c | 41 |
8 files changed, 172 insertions, 76 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index fe158a8f3..0afdaf3c1 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -102,7 +102,7 @@ void circuit_log_path(int severity, circuit_t *circ) { */ void circuit_rep_hist_note_result(circuit_t *circ) { struct crypt_path_t *hop; - char *prev_nickname = NULL; + char *prev_digest = NULL; routerinfo_t *router; hop = circ->cpath; if(!hop) { @@ -114,22 +114,22 @@ void circuit_rep_hist_note_result(circuit_t *circ) { return; } if (options.ORPort) { - prev_nickname = options.Nickname; + prev_digest = router_get_my_routerinfo()->identity_digest; } do { router = router_get_by_digest(hop->identity_digest); if (router) { - if (prev_nickname) { + if (prev_digest) { 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 { - rep_hist_note_extend_failed(prev_nickname, router->nickname); + rep_hist_note_extend_failed(prev_digest, router->identity_digest); break; } } - prev_nickname = router->nickname; + prev_digest = router->identity_digest; } else { - prev_nickname = NULL; + prev_digest = NULL; } hop=hop->next; } while (hop!=circ->cpath); @@ -445,6 +445,8 @@ int circuit_extend(cell_t *cell, circuit_t *circ) { relay_header_unpack(&rh, cell->payload); 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; } else if (rh.length == 4+2+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN) { old_format = 0; diff --git a/src/or/config.c b/src/or/config.c index e9068bd2d..2941174a6 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -467,6 +467,40 @@ static int resolve_my_address(or_options_t *options) { 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> */ static void free_options(or_options_t *options) { config_free_lines(options->LogOptions); @@ -633,8 +667,9 @@ int getconfig(int argc, char **argv, or_options_t *options) { if (options->ORPort) { if (options->Nickname == NULL) { - log_fn(LOG_WARN,"Nickname required if ORPort is set, but not found."); - result = -1; + if (!(options->Nickname = get_default_nickname())) + return -1; + log_fn(LOG_INFO, "Choosing default nickname %s", options->Nickname); } else { if (strspn(options->Nickname, LEGAL_NICKNAME_CHARACTERS) != strlen(options->Nickname)) { diff --git a/src/or/connection.c b/src/or/connection.c index fb7357662..0beb36a3d 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -192,13 +192,13 @@ void connection_about_to_close_connection(connection_t *conn) if (conn->state != OR_CONN_STATE_OPEN) { /* XXX Nick: this still isn't right, because it might be * 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) - 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) { - rep_hist_note_disconnect(conn->nickname, time(NULL)); + rep_hist_note_disconnect(conn->identity_digest, time(NULL)); } else { - rep_hist_note_connection_died(conn->nickname, time(NULL)); + rep_hist_note_connection_died(conn->identity_digest, time(NULL)); } break; case CONN_TYPE_AP: diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 87e2f9df2..094612a03 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -329,7 +329,7 @@ connection_tls_finish_handshake(connection_t *conn) { directory_set_dirty(); circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */ /* Note the success */ - rep_hist_note_connect_succeeded(nickname, time(NULL)); + rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL)); return 0; } diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index c3e567cdf..04b54fc00 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -19,7 +19,7 @@ extern or_options_t options; /* command-line and config-file options */ #define MIN_CPUWORKERS 1 /** 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? */ #define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN) /** 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 * cpuworker_main for wire format.) */ -static void tag_pack(char *tag, uint32_t addr, uint16_t port, uint16_t circ_id) { - *(uint32_t *)tag = addr; - *(uint16_t *)(tag+4) = port; - *(uint16_t *)(tag+6) = circ_id; +static void tag_pack(char *tag, uint16_t circ_id, const char *identity_digest){ + *(uint16_t *)(tag) = circ_id; + memcpy(tag+2, identity_digest, DIGEST_LEN); } /** 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) { - struct in_addr in; - - *addr = *(const uint32_t *)tag; - *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); +static void tag_unpack(const char *tag, uint16_t *circ_id, + char *identity_digest) { + *circ_id = *(const uint16_t *)(tag); + memcpy(identity_digest, tag+2, DIGEST_LEN); } /** 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) { char success; unsigned char buf[LEN_ONION_RESPONSE]; - uint32_t addr; - uint16_t port; uint16_t circ_id; connection_t *p_conn; circuit_t *circ; + char identity_digest[DIGEST_LEN]; 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); /* parse out the circ it was talking about */ - tag_unpack(buf, &addr, &port, &circ_id); + tag_unpack(buf, &circ_id, identity_digest); circ = NULL; /* XXXX This is actually right: we want a specific port here in * 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) 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."); 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; num_cpuworkers_busy++; diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 7de6a1e53..3da343285 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -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 * list. */ 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; + char fp[FINGERPRINT_LEN+1]; if (!fingerprint_list) 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) { ent = smartlist_get(fingerprint_list, i); - if (!strcasecmp(nickname,ent->nickname)) { + if (!strcasecmp(nickname,ent->nickname) && + !strcasecmp(fp,ent->fingerprint)) { return 1; } } @@ -227,6 +236,7 @@ typedef struct descriptor_entry_t { time_t published; size_t desc_len; char *descriptor; + int verified; routerinfo_t *router; } descriptor_entry_t; @@ -368,6 +378,7 @@ dirserv_add_descriptor(const char **desc) strncpy(ent->descriptor, start, desc_len); ent->descriptor[desc_len] = '\0'; ent->router = ri; + ent->verified = 1; /* XXXX008 support other possibilities. */ smartlist_add(descriptor_list, ent); *desc = end; @@ -447,19 +458,25 @@ list_running_servers(char **nicknames_out) *nicknames_out = NULL; nicknames_up = 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); for (i = 0; i<n_conns; ++i) { + char *name; conn = connection_array[i]; if (conn->type != CONN_TYPE_OR || !conn->nickname) continue; /* only list ORs. */ - if (!router_nickname_is_approved(conn->nickname)) - continue; /* If we removed them from the approved list, don't list it.*/ + if (router_nickname_is_approved(conn->nickname, conn->identity_digest)) { + 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) - smartlist_add(nicknames_up, conn->nickname); + smartlist_add(nicknames_up, name); else - smartlist_add(nicknames_down, conn->nickname); + smartlist_add(nicknames_down, name); } length = smartlist_len(nicknames_up) + 2*smartlist_len(nicknames_down) + 1; @@ -481,6 +498,8 @@ list_running_servers(char **nicknames_out) while (*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_down); return 0; diff --git a/src/or/rephist.c b/src/or/rephist.c index fb282f469..cdc25567b 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -7,6 +7,8 @@ * \brief Basic history functionality for reputation module. **/ +/* DOCDOC references to 'nicknames' in docs here are mostly wrong. */ + #include "or.h" /** 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. */ -static or_history_t *get_or_history(const char* nickname) +static or_history_t *get_or_history(const char* id) { 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) { hist = tor_malloc_zero(sizeof(or_history_t)); hist->link_history_map = strmap_new(); hist->since = time(NULL); - strmap_set(history_map, nickname, hist); + strmap_set(history_map, hexid, 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 * the second, creating it if necessary. */ -static link_history_t *get_link_history(const char *from_name, - const char *to_name) +static link_history_t *get_link_history(const char *from_id, + const char *to_id) { or_history_t *orhist; link_history_t *lhist; - orhist = get_or_history(from_name); - lhist = (link_history_t*) strmap_get(orhist->link_history_map, to_name); + char to_hexid[HEX_DIGEST_LEN+1]; + 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) { lhist = tor_malloc_zero(sizeof(link_history_t)); lhist->since = time(NULL); - strmap_set(orhist->link_history_map, to_name, lhist); + strmap_set(orhist->link_history_map, to_hexid, 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 * <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; - hist = get_or_history(nickname); + hist = get_or_history(id); ++hist->n_conn_fail; if (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 * 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; - hist = get_or_history(nickname); + hist = get_or_history(id); ++hist->n_conn_ok; if (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 * <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; - hist = get_or_history(nickname); + hist = get_or_history(id); ++hist->n_conn_ok; if (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>. */ -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; - if(!nickname) { + if(!id) { + /* XXXX008 not so. */ /* 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). * Ignore it. */ return; } - hist = get_or_history(nickname); + hist = get_or_history(id); if (hist->up_since) { hist->uptime += (when - hist->up_since); 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 * the OR <b>to_name</b>. */ -void rep_hist_note_extend_succeeded(const char *from_name, - const char *to_name) +void rep_hist_note_extend_succeeded(const char *from_id, + const char *to_id) { link_history_t *hist; /* 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; } /** Remember that we tried to extend from the OR <b>from_name</b> to the OR * <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; /* 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; } @@ -199,7 +207,7 @@ void rep_hist_dump_stats(time_t now, int severity) { strmap_iter_t *lhist_it; strmap_iter_t *orhist_it; - const char *name1, *name2; + const char *name1, *name2, *hexdigest1, *hexdigest2; or_history_t *or_history; link_history_t *link_history; void *or_history_p, *link_history_p; @@ -207,14 +215,20 @@ void rep_hist_dump_stats(time_t now, int severity) char buffer[2048]; int len; unsigned long upt, downt; + routerinfo_t *r; log(severity, "--------------- Dumping history information:"); for (orhist_it = strmap_iter_init(history_map); !strmap_iter_done(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; + if ((r = router_get_by_hexdigest(hexdigest1))) + name1 = r->nickname; + else + name1 = "(unknown)"; + update_or_history(or_history, now); upt = or_history->uptime; downt = or_history->downtime; @@ -224,8 +238,8 @@ void rep_hist_dump_stats(time_t now, int severity) uptime=1.0; } log(severity, - "OR %s: %ld/%ld good connections; uptime %ld/%ld sec (%.2f%%)", - name1, + "OR %s [%s]: %ld/%ld good connections; uptime %ld/%ld sec (%.2f%%)", + name1, hexdigest1, or_history->n_conn_ok, or_history->n_conn_fail+or_history->n_conn_ok, 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); !strmap_iter_done(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; len += snprintf(buffer+len, 2048-len, "%s(%ld/%ld); ", name2, link_history->n_extend_ok, @@ -275,7 +294,6 @@ void write_rep_history(const char *filename) name1, or_history->since1, } - done: if (f) fclose(f); diff --git a/src/or/router.c b/src/or/router.c index 4d1d6bf97..e4dc0bc4a 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -124,6 +124,32 @@ void rotate_onion_key(void) 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, * create a new RSA key and save it in <b>fname</b>. Return the read/created * key, or NULL on error. @@ -182,6 +208,7 @@ crypto_pk_env_t *init_key_from_file(const char *fname) */ int init_keys(void) { char keydir[512]; + char keydir2[512]; char fingerprint[FINGERPRINT_LEN+MAX_NICKNAME_LEN+3]; char *cp; const char *tmp, *mydesc, *datadir; @@ -217,15 +244,17 @@ int init_keys(void) { cp = keydir + strlen(keydir); /* End of string. */ /* 1. Read identity key. Make it if none is found. */ - strcpy(cp, "/identity.key"); - log_fn(LOG_INFO,"Reading/making identity key %s...",keydir); - prkey = init_key_from_file(keydir); + sprintf(keydir,"%s/keys/identity.key",datadir); + sprintf(keydir2,"%s/keys/secret_id_key",datadir); + log_fn(LOG_INFO,"Reading/making identity key %s...",keydir2); + prkey = init_key_from_file_name_changed(keydir,keydir2); if (!prkey) return -1; set_identity_key(prkey); /* 2. Read onion key. Make it if none is found. */ - strcpy(cp, "/onion.key"); - log_fn(LOG_INFO,"Reading/making onion key %s...",keydir); - prkey = init_key_from_file(keydir); + sprintf(keydir,"%s/keys/onion.key",datadir); + sprintf(keydir2,"%s/keys/secret_onion_key",datadir); + log_fn(LOG_INFO,"Reading/making onion key %s...",keydir2); + prkey = init_key_from_file_name_changed(keydir,keydir2); if (!prkey) return -1; set_onion_key(prkey); |