diff --git a/src/common/log.c b/src/common/log.c index f117b877e2..09f83d08f2 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -93,6 +93,7 @@ logv(int severity, const char *funcname, const char *format, va_list ap) formatted = 1; } fputs(buf, lf->file); + /* XXX check for EOF */ } } diff --git a/src/common/util.c b/src/common/util.c index 7b14039b6d..5cb2eb6de4 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -405,7 +405,7 @@ char *read_file_to_str(const char *filename) { } if(stat(filename, &statbuf) < 0) { - log_fn(LOG_WARNING,"Could not stat %s.",filename); + log_fn(LOG_INFO,"Could not stat %s.",filename); return NULL; } diff --git a/src/or/command.c b/src/or/command.c index e3943cc793..157da99f64 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -118,7 +118,7 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) { circ = circuit_get_by_aci_conn(cell->aci, conn); if(!circ) { - log_fn(LOG_WARNING,"received CREATED cell (aci %d) for unknown circ. Dropping.", cell->aci); + log_fn(LOG_INFO,"(aci %d) unknown circ (probably got a destroy earlier). Dropping.", cell->aci); return; } diff --git a/src/or/directory.c b/src/or/directory.c index d0234fd196..a250e7eed6 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -186,6 +186,7 @@ static int directory_handle_command(connection_t *conn) { log_fn(LOG_DEBUG,"headers '%s', body '%s'.",headers,body); if(!strncasecmp(headers,"GET",3)) { /* XXX should check url and http version */ + log_fn(LOG_DEBUG,"Received GET command."); dlen = dirserv_get_directory(&cp); @@ -206,7 +207,7 @@ static int directory_handle_command(connection_t *conn) { if(!strncasecmp(headers,"POST",4)) { /* XXX should check url and http version */ - log_fn(LOG_DEBUG,"Received POST command, body '%s'", body); + log_fn(LOG_DEBUG,"Received POST command."); cp = body; if(dirserv_add_descriptor(&cp) < 0) { log_fn(LOG_WARNING,"dirserv_add_descriptor() failed. Dropping."); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 93d9930bf9..f97fdc79cb 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -4,6 +4,8 @@ #include "or.h" +extern or_options_t options; /* command-line and config-file options */ + static int the_directory_is_dirty = 1; static char *the_directory = NULL; static int the_directory_len = -1; @@ -155,7 +157,7 @@ dirserv_add_descriptor(const char **desc) routerinfo_t *ri = NULL; int i; char *start, *end; - char *desc_tmp = NULL; + char *desc_tmp = NULL, *cp; size_t desc_len; start = strstr(*desc, "router "); @@ -170,12 +172,12 @@ dirserv_add_descriptor(const char **desc) end = start+strlen(start); } desc_len = end-start; - desc_tmp = tor_malloc(desc_len+1); + cp = desc_tmp = tor_malloc(desc_len+1); strncpy(desc_tmp, start, desc_len); desc_tmp[desc_len]='\0'; /* Check: is the descriptor syntactically valid? */ - ri = router_get_entry_from_string(&desc_tmp); + ri = router_get_entry_from_string(&cp); if (!ri) { log(LOG_WARNING, "Couldn't parse descriptor"); goto err; @@ -198,6 +200,7 @@ dirserv_add_descriptor(const char **desc) /* if so, decide whether to update it. */ if ((*desc_ent_ptr)->published > ri->published_on) { /* We already have a newer descriptor */ + log_fn(LOG_INFO,"We already have a newer desc for nickname %s. Ignoring.",ri->nickname); goto err; } /* We don't have a newer one; we'll update this one. */ @@ -278,7 +281,7 @@ dirserv_dump_directory_to_string(char *s, int maxlen, for (i = 0; i < n_descriptors; ++i) { strncat(cp, descriptor_list[i]->descriptor, descriptor_list[i]->desc_len); cp += descriptor_list[i]->desc_len; - assert(!cp); + assert(!*cp); } /* These multiple strlen calls are inefficient, but dwarfed by the RSA signature. @@ -322,6 +325,7 @@ dirserv_dump_directory_to_string(char *s, int maxlen, size_t dirserv_get_directory(const char **directory) { char *new_directory; + char filename[512]; if (the_directory_is_dirty) { new_directory = tor_malloc(MAX_DIR_SIZE); if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE, @@ -341,11 +345,16 @@ size_t dirserv_get_directory(const char **directory) * router lists. This does more signature checking than is strictly * necessary, but safe is better than sorry. */ new_directory = strdup(the_directory); + /* use a new copy of the dir, since get_dir_from_string scribbles on it */ if (router_get_dir_from_string(new_directory, get_identity_key())) { log_fn(LOG_ERR, "We just generated a directory we can't parse. Dying."); exit(0); } free(new_directory); + sprintf(filename,"%s/cached-directory", options.DataDirectory); + if(write_str_to_file(filename,the_directory) < 0) { + log_fn(LOG_WARNING, "Couldn't write cached directory to disk. Ignoring."); + } } else { log(LOG_INFO,"Directory still clean, reusing."); } diff --git a/src/or/main.c b/src/or/main.c index c9b32282b6..c39aa08108 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -502,7 +502,8 @@ static int init_keys(void) crypto_pk_env_t *prkey; /* OP's don't need keys. Just initialize the TLS context.*/ - if (!options.OnionRouter && !options.DirPort) { + if (!options.OnionRouter) { + assert(!options.DirPort); if (tor_tls_context_new(NULL, 0, NULL)<0) { log_fn(LOG_ERR, "Error creating TLS context for OP."); return -1; @@ -514,32 +515,31 @@ static int init_keys(void) log_fn(LOG_ERR, "DataDirectory is too long."); return -1; } - strcpy(keydir, options.DataDirectory); - if (check_private_dir(keydir, 1)) { + if (check_private_dir(options.DataDirectory, 1)) { return -1; } - strcat(keydir, "/keys"); + sprintf(keydir,"%s/keys",options.DataDirectory); if (check_private_dir(keydir, 1)) { return -1; } cp = keydir + strlen(keydir); /* End of string. */ - assert(!*cp); /* 1. Read identity key. Make it if none is found. */ - strcat(keydir, "/identity.key"); + strcpy(cp, "/identity.key"); + log_fn(LOG_INFO,"Reading/making identity key %s...",keydir); prkey = init_key_from_file(keydir); if (!prkey) return -1; set_identity_key(prkey); /* 2. Read onion key. Make it if none is found. */ - *cp = '\0'; - strcat(keydir, "/onion.key"); + strcpy(cp, "/onion.key"); + log_fn(LOG_INFO,"Reading/making onion key %s...",keydir); prkey = init_key_from_file(keydir); if (!prkey) return -1; set_onion_key(prkey); /* 3. Initialize link key and TLS context. */ - *cp = '\0'; - strcat(keydir, "/link.key"); + strcpy(cp, "/link.key"); + log_fn(LOG_INFO,"Reading/making link key %s...",keydir); prkey = init_key_from_file(keydir); if (!prkey) return -1; set_link_key(prkey); @@ -553,14 +553,14 @@ static int init_keys(void) log_fn(LOG_ERR, "Error initializing descriptor."); return -1; } - strcpy(keydir, options.DataDirectory); - strcat(keydir, "/router.desc"); + sprintf(keydir,"%s/router.desc", options.DataDirectory); + log_fn(LOG_INFO,"Dumping descriptor to %s...",keydir); if (write_str_to_file(keydir, router_get_my_descriptor())) { return -1; } /* 5. Dump fingerprint to 'fingerprint' */ - strcpy(keydir, options.DataDirectory); - strcat(keydir, "/fingerprint"); + sprintf(keydir,"%s/fingerprint", options.DataDirectory); + log_fn(LOG_INFO,"Dumping fingerprint to %s...",keydir); assert(strlen(options.Nickname) <= MAX_NICKNAME_LEN); strcpy(fingerprint, options.Nickname); strcat(fingerprint, " "); @@ -572,6 +572,30 @@ static int init_keys(void) strcat(fingerprint, "\n"); if (write_str_to_file(keydir, fingerprint)) return -1; + if(!options.DirPort) + return 0; + /* 6. [dirserver only] load approved-routers file */ + sprintf(keydir,"%s/approved-routers", options.DataDirectory); + log_fn(LOG_INFO,"Loading approved fingerprints from %s...",keydir); + if(dirserv_parse_fingerprint_file(keydir) < 0) { + log_fn(LOG_ERR, "Error loading fingerprints"); + return -1; + } + /* 7. [dirserver only] load old directory, if it's there */ + sprintf(keydir,"%s/cached-directory", options.DataDirectory); + log_fn(LOG_INFO,"Loading cached directory from %s...",keydir); + cp = read_file_to_str(keydir); + if(!cp) { + log_fn(LOG_INFO,"Cached directory %s not present. Ok.",keydir); + } else { + if(dirserv_init_from_directory_string(cp) < 0) { + log_fn(LOG_ERR, "Cached directory %s is corrupt", keydir); + free(cp); + return -1; + } + free(cp); + } + /* success */ return 0; } @@ -829,6 +853,8 @@ list_running_servers(char **nicknames_out) conn = connection_array[i]; if (conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN) continue; /* only list successfully handshaked OR's. */ + if(!conn->nickname) /* it's an OP, don't list it */ + continue; nickname_lst[n++] = conn->nickname; } length = n + 1; /* spaces + EOS + 1. */ diff --git a/src/or/routers.c b/src/or/routers.c index e8995a8547..f1207bc980 100644 --- a/src/or/routers.c +++ b/src/or/routers.c @@ -669,7 +669,7 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest, NEXT_TOK(); TOK_IS(K_RECOMMENDED_SOFTWARE, "recommended-software"); if (tok.val.cmd.n_args != 1) { - log_fn(LOG_WARNING, "Invalid recommded-software line"); + log_fn(LOG_WARNING, "Invalid recommended-software line"); goto err; } versions = strdup(tok.val.cmd.args[0]); @@ -677,7 +677,7 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest, NEXT_TOK(); TOK_IS(K_RUNNING_ROUTERS, "running-routers"); n_good_nicknames = tok.val.cmd.n_args; - memcpy(good_nickname_lst, tok.val.cmd.args, n_good_nicknames); + memcpy(good_nickname_lst, tok.val.cmd.args, n_good_nicknames*sizeof(char *)); if (router_get_list_from_string_impl(&s, &new_dir, n_good_nicknames, good_nickname_lst)) {