diff options
author | Roger Dingledine <arma@torproject.org> | 2003-09-29 07:50:08 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2003-09-29 07:50:08 +0000 |
commit | 467d278b8b00740e876ae5ba9e0798ad702b5a67 (patch) | |
tree | b19da3d974a3c3d4290ea748f40283cb75c6651f /src | |
parent | 5d31f7155793b80285ba61ec8688dbc6c117ed52 (diff) | |
download | tor-467d278b8b00740e876ae5ba9e0798ad702b5a67.tar tor-467d278b8b00740e876ae5ba9e0798ad702b5a67.tar.gz |
more cleanup and rearranging
still not finished integrating new dirserv stuff
svn:r507
Diffstat (limited to 'src')
-rw-r--r-- | src/common/util.c | 50 | ||||
-rw-r--r-- | src/common/util.h | 10 | ||||
-rw-r--r-- | src/or/config.c | 85 | ||||
-rw-r--r-- | src/or/directory.c | 7 | ||||
-rw-r--r-- | src/or/dirserv.c | 109 | ||||
-rw-r--r-- | src/or/main.c | 12 |
6 files changed, 126 insertions, 147 deletions
diff --git a/src/common/util.c b/src/common/util.c index e290ab047..7b14039b6 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -430,3 +430,53 @@ char *read_file_to_str(const char *filename) { return string; } +/* read lines from f (no more than maxlen-1 bytes each) until we + * get one with a well-formed "key value". + * point *key to the first word in line, point *value to the second. + * Put a \0 at the end of key, remove everything at the end of value + * that is whitespace or comment. + * Return 1 if success, 0 if no more lines, -1 if error. + */ +int parse_line_from_file(char *line, int maxlen, FILE *f, char **key_out, char **value_out) { + char *s, *key, *end, *value; + +try_next_line: + if(!fgets(line, maxlen, f)) { + if(feof(f)) + return 0; + return -1; /* real error */ + } + + if((s = strchr(line,'#'))) /* strip comments */ + *s = 0; /* stop the line there */ + + /* remove end whitespace */ + s = strchr(line, 0); /* now we're at the null */ + do { + *s = 0; + s--; + } while (isspace(*s)); + + key = line; + while(isspace(*key)) + key++; + if(*key == 0) + goto try_next_line; /* this line has nothing on it */ + end = key; + while(*end && !isspace(*end)) + end++; + value = end; + while(*value && isspace(*value)) + value++; + + if(!*end || !*value) { /* only a key on this line. no value. */ + log_fn(LOG_WARNING,"Line has keyword '%s' but no value. Skipping.",s); + goto try_next_line; + } + *end = 0; /* null it out */ + + log_fn(LOG_DEBUG,"got keyword '%s', value '%s'", key, value); + *key_out = key, *value_out = value; + return 1; +} + diff --git a/src/common/util.h b/src/common/util.h index 65f2760c8..0f7ac3b4d 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -5,21 +5,14 @@ #ifndef __UTIL_H #define __UTIL_H -#include "orconfig.h" +#include "../or/or.h" -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef HAVE_TIME_H -#include <time.h> -#endif #if _MSC_VER > 1300 #include <winsock2.h> #include <ws2tcpip.h> #elif defined(_MSC_VER) #include <winsock.h> #endif -#include <errno.h> #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_FTIME #define USING_FAKE_TIMEVAL @@ -68,6 +61,7 @@ file_status_t file_status(const char *filename); int check_private_dir(const char *dirname, int create); int write_str_to_file(const char *fname, const char *str); char *read_file_to_str(const char *filename); +int parse_line_from_file(char *line, int maxlen, FILE *f, char **key_out, char **value_out); /* Minimalist interface to run a void function in the background. On unix calls fork, on win32 calls beginthread. Returns -1 on failure. diff --git a/src/or/config.c b/src/or/config.c index 4212cdff7..df0e643ae 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -73,64 +73,26 @@ static struct config_line *config_get_commandlines(int argc, char **argv) { return front; } -/* parse the config file and strdup into key/value strings. Return list. +/* parse the config file and strdup into key/value strings. Return list, + * or NULL if parsing the file failed. * Warn and ignore mangled lines. */ static struct config_line *config_get_lines(FILE *f) { struct config_line *new; struct config_line *front = NULL; char line[CONFIG_LINE_MAXLEN]; - int lineno=0; /* current line number */ - char *s; - char *start, *end; - - assert(f); - - fseek(f,0,SEEK_SET); /* make sure we start at the beginning of file */ - - while(fgets(line, CONFIG_LINE_MAXLEN, f)) { - lineno++; - - /* first strip comments */ - s = strchr(line,'#'); - if(s) { - *s = 0; /* stop the line there */ - } - - /* walk to the end, remove end whitespace */ - s = strchr(line, 0); /* now we're at the null */ - do { - *s = 0; - s--; - } while (isspace(*s)); - - start = line; - while(isspace(*start)) - start++; - if(*start == 0) - continue; /* this line has nothing on it */ - - end = start; - while(*end && !isspace(*end)) - end++; - s = end; - while(*s && isspace(*s)) - s++; - if(!*end || !*s) { /* only a keyword on this line. no value. */ - log(LOG_WARNING,"Config line %d has keyword '%s' but no value. Skipping.",lineno,s); - } - *end = 0; /* null it out */ + int result; + char *key, *value; - /* prepare to parse the string into key / value */ + while( (result=parse_line_from_file(line,sizeof(line),f,&key,&value)) > 0) { new = tor_malloc(sizeof(struct config_line)); - new->key = strdup(start); - new->value = strdup(s); + new->key = strdup(key); + new->value = strdup(value); - log(LOG_DEBUG,"Config line %d: parsed keyword '%s', value '%s'", - lineno, new->key, new->value); new->next = front; front = new; } - + if(result < 0) + return NULL; return front; } @@ -261,11 +223,12 @@ int getconfig(int argc, char **argv, or_options_t *options) { cf = config_open(fname); if(!cf) { - log(LOG_ERR, "Unable to open configuration file '%s'.",fname); + log(LOG_WARNING, "Unable to open configuration file '%s'.",fname); return -1; } cl = config_get_lines(cf); + if(!cl) return -1; config_assign(options,cl); config_free_lines(cl); config_close(cf); @@ -287,69 +250,69 @@ int getconfig(int argc, char **argv, or_options_t *options) { else if(!strcmp(options->LogLevel,"debug")) options->loglevel = LOG_DEBUG; else { - log(LOG_ERR,"LogLevel must be one of err|warning|info|debug."); + log(LOG_WARNING,"LogLevel must be one of err|warning|info|debug."); result = -1; } } if(options->RouterFile == NULL) { - log(LOG_ERR,"RouterFile option required, but not found."); + log(LOG_WARNING,"RouterFile option required, but not found."); result = -1; } if(options->ORPort < 0) { - log(LOG_ERR,"ORPort option can't be negative."); + log(LOG_WARNING,"ORPort option can't be negative."); result = -1; } if(options->OnionRouter && options->ORPort == 0) { - log(LOG_ERR,"If OnionRouter is set, then ORPort must be positive."); + log(LOG_WARNING,"If OnionRouter is set, then ORPort must be positive."); result = -1; } if(options->OnionRouter && options->DataDirectory == NULL) { - log(LOG_ERR,"DataDirectory option required for OnionRouter, but not found."); + log(LOG_WARNING,"DataDirectory option required for OnionRouter, but not found."); result = -1; } if(options->OnionRouter && options->Nickname == NULL) { - log_fn(LOG_ERR,"Nickname required for OnionRouter, but not found."); + log_fn(LOG_WARNING,"Nickname required for OnionRouter, but not found."); result = -1; } if(options->APPort < 0) { - log(LOG_ERR,"APPort option can't be negative."); + log(LOG_WARNING,"APPort option can't be negative."); result = -1; } if(options->DirPort < 0) { - log(LOG_ERR,"DirPort option can't be negative."); + log(LOG_WARNING,"DirPort option can't be negative."); result = -1; } if(options->APPort > 1 && (options->CoinWeight < 0.0 || options->CoinWeight >= 1.0)) { - log(LOG_ERR,"CoinWeight option must be >=0.0 and <1.0."); + log(LOG_WARNING,"CoinWeight option must be >=0.0 and <1.0."); result = -1; } if(options->MaxConn < 1) { - log(LOG_ERR,"MaxConn option must be a non-zero positive integer."); + log(LOG_WARNING,"MaxConn option must be a non-zero positive integer."); result = -1; } if(options->MaxConn >= MAXCONNECTIONS) { - log(LOG_ERR,"MaxConn option must be less than %d.", MAXCONNECTIONS); + log(LOG_WARNING,"MaxConn option must be less than %d.", MAXCONNECTIONS); result = -1; } if(options->DirFetchPeriod < 1) { - log(LOG_ERR,"DirFetchPeriod option must be positive."); + log(LOG_WARNING,"DirFetchPeriod option must be positive."); result = -1; } if(options->KeepalivePeriod < 1) { - log(LOG_ERR,"KeepalivePeriod option must be positive."); + log(LOG_WARNING,"KeepalivePeriod option must be positive."); result = -1; } diff --git a/src/or/directory.c b/src/or/directory.c index 804ad6999..d0234fd19 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -191,7 +191,7 @@ static int directory_handle_command(connection_t *conn) { if(dlen == 0) { log_fn(LOG_WARNING,"My directory is empty. Closing."); - return -1; + return -1; /* XXX send some helpful http error code */ } log_fn(LOG_DEBUG,"Dumping directory to client."); @@ -207,6 +207,11 @@ 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); + cp = body; + if(dirserv_add_descriptor(&cp) < 0) { + log_fn(LOG_WARNING,"dirserv_add_descriptor() failed. Dropping."); + return -1; /* XXX should write an http failed code */ + } if(connection_write_to_buf(answerstring, strlen(answerstring), conn) < 0) { log_fn(LOG_WARNING,"Failed to write answerstring to outbuf."); return -1; diff --git a/src/or/dirserv.c b/src/or/dirserv.c index a6ff12d8a..93d9930bf 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -8,9 +8,8 @@ static int the_directory_is_dirty = 1; static char *the_directory = NULL; static int the_directory_len = -1; -/* - * Fingerprint handling code. - */ +/************** Fingerprint handling code ************/ + typedef struct fingerprint_entry_t { char *nickname; char *fingerprint; @@ -24,83 +23,54 @@ int dirserv_parse_fingerprint_file(const char *fname) { FILE *file; -#define BUF_LEN (FINGERPRINT_LEN+MAX_NICKNAME_LEN+20) - char buf[BUF_LEN+1]; - char *cp, *nickname, *fingerprint; + char line[FINGERPRINT_LEN+MAX_NICKNAME_LEN+20+1]; + char *nickname, *fingerprint; fingerprint_entry_t fingerprint_list_tmp[MAX_ROUTERS_IN_DIR]; int n_fingerprints_tmp = 0; - int lineno=0; - int i; - if (!(file = fopen(fname, "r"))) { - log(LOG_WARNING, "Cannot open fingerprint file %s", fname); - goto err; + int i, result; + + if(!(file = fopen(fname, "r"))) { + log_fn(LOG_WARNING, "Cannot open fingerprint file %s", fname); + return -1; } - while (1) { - cp = fgets(buf, BUF_LEN, file); - ++lineno; - if (!cp) { - if (feof(file)) - break; - else { - log(LOG_WARNING, "Error reading from fingerprint file"); - goto err; - } - } - buf[BUF_LEN]='\0'; - cp = buf; - while (isspace(*cp)) - ++cp; - if (*cp == '#' || *cp == '\0') - continue; - nickname = cp; - cp = strchr(cp, ' '); - if (!cp) { - log(LOG_WARNING, "Bad line %d of fingerprint file", lineno); - goto err; - } - *cp++ = '\0'; - while (isspace(*cp)) - ++cp; - if (strlen(cp) < FINGERPRINT_LEN) { - log(LOG_WARNING, "Bad line %d of fingerprint file", lineno); - goto err; - } - fingerprint = cp; - cp[FINGERPRINT_LEN] = '\0'; + while( (result=parse_line_from_file(line, sizeof(line),file,&nickname,&fingerprint)) > 0) { if (strlen(nickname) > MAX_NICKNAME_LEN) { - log(LOG_WARNING, "Nickname too long on line %d of fingerprint file", - lineno); - goto err; + log(LOG_WARNING, "Nickname %s too long in fingerprint file. Skipping.", nickname); + continue; } - if (!crypto_pk_check_fingerprint_syntax(fingerprint)) { - log(LOG_WARNING, "Invalid fingerprint on line %d of fingerprint file", - lineno); - goto err; + if(strlen(fingerprint) != FINGERPRINT_LEN || + !crypto_pk_check_fingerprint_syntax(fingerprint)) { + log_fn(LOG_WARNING, "Invalid fingerprint (nickname %s, fingerprint %s). Skipping.", + nickname, fingerprint); + continue; } for (i = 0; i < n_fingerprints_tmp; ++i) { if (0==strcasecmp(fingerprint_list_tmp[i].nickname, nickname)) { - log(LOG_WARNING, "Duplicate nickname on line %d of fingerprint file", lineno); - goto err; + log(LOG_WARNING, "Duplicate nickname %s. Skipping.",nickname); + break; /* out of the for. the 'if' below means skip to the next line. */ } } - fingerprint_list_tmp[n_fingerprints_tmp].nickname = strdup(nickname); - fingerprint_list_tmp[n_fingerprints_tmp].fingerprint = strdup(fingerprint); - ++n_fingerprints_tmp; + if(i == n_fingerprints_tmp) { /* not a duplicate */ + fingerprint_list_tmp[n_fingerprints_tmp].nickname = strdup(nickname); + fingerprint_list_tmp[n_fingerprints_tmp].fingerprint = strdup(fingerprint); + ++n_fingerprints_tmp; + } } - /* replace the global fingerprints list. */ - dirserv_free_fingerprint_list(); - memcpy(fingerprint_list, fingerprint_list_tmp, - sizeof(fingerprint_entry_t)*n_fingerprints_tmp); - n_fingerprints = n_fingerprints_tmp; - return 0; - - err: + fclose(file); + if(result == 0) { /* eof; replace the global fingerprints list. */ + dirserv_free_fingerprint_list(); + memcpy(fingerprint_list, fingerprint_list_tmp, + sizeof(fingerprint_entry_t)*n_fingerprints_tmp); + n_fingerprints = n_fingerprints_tmp; + return 0; + } + /* error */ + log_fn(LOG_WARNING, "Error reading from fingerprint file"); for (i = 0; i < n_fingerprints_tmp; ++i) { free(fingerprint_list_tmp[i].nickname); free(fingerprint_list_tmp[i].fingerprint); } return -1; -#undef BUF_LEN } /* return 1 if router's identity and nickname match. */ @@ -118,20 +88,17 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router) } } - if (!ent) { - /* No such server known */ + if (!ent) { /* No such server known */ return 0; } if (crypto_pk_get_fingerprint(router->identity_pkey, fp)) { - /* XXX Error computing fingerprint: log */ + log_fn(LOG_WARNING,"error computing fingerprint"); return 0; } if (0==strcasecmp(ent->fingerprint, fp)) { - /* Right fingerprint. */ - return 1; + return 1; /* Right fingerprint. */ } else { - /* Wrong fingerprint. */ - return 0; + return 0; /* Wrong fingerprint. */ } } diff --git a/src/or/main.c b/src/or/main.c index 83f10ee19..c9b32282b 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -912,10 +912,11 @@ void daemonize(void) { } int tor_main(int argc, char *argv[]) { - int retval = 0; - if(getconfig(argc,argv,&options)) - exit(1); + if(getconfig(argc,argv,&options)) { + log_fn(LOG_ERR,"Reading config file failed. exiting."); + return -1; + } log_set_severity(options.loglevel); /* assign logging severity level from options */ global_read_bucket = options.TotalBandwidth; /* start it at 1 second of traffic */ @@ -936,10 +937,9 @@ int tor_main(int argc, char *argv[]) { crypto_global_init(); crypto_seed_rng(); - retval = do_main_loop(); + do_main_loop(); crypto_global_cleanup(); - - return retval; + return -1; } /* |