diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-06-21 04:37:27 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-06-21 04:37:27 +0000 |
commit | 8aec3a730155af7528928123c0dbc98a4f0293dd (patch) | |
tree | b97f7834dd7e7960419689bc2d9a2de4533e283d /src/or | |
parent | 207fcb35d1123cc918b8787e55e3a7e5d60aa0c5 (diff) | |
download | tor-8aec3a730155af7528928123c0dbc98a4f0293dd.tar tor-8aec3a730155af7528928123c0dbc98a4f0293dd.tar.gz |
Implement several 008pre1 items: needs more testing
svn:r1981
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 37 | ||||
-rw-r--r-- | src/or/dirserv.c | 26 | ||||
-rw-r--r-- | src/or/main.c | 7 | ||||
-rw-r--r-- | src/or/or.h | 5 | ||||
-rw-r--r-- | src/or/router.c | 24 | ||||
-rw-r--r-- | src/or/routerlist.c | 1 | ||||
-rw-r--r-- | src/or/routerparse.c | 61 | ||||
-rw-r--r-- | src/or/test.c | 1 |
8 files changed, 147 insertions, 15 deletions
diff --git a/src/or/config.c b/src/or/config.c index 332a6e009..10ac50028 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -188,10 +188,13 @@ static int config_assign(or_options_t *options, struct config_line_t *list) { /* string options */ config_compare(list, "Address", CONFIG_TYPE_STRING, &options->Address) || + config_compare(list, "AuthoritativeDirectory",CONFIG_TYPE_BOOL, &options->AuthoritativeDir) || config_compare(list, "BandwidthRate", CONFIG_TYPE_INT, &options->BandwidthRate) || config_compare(list, "BandwidthBurst", CONFIG_TYPE_INT, &options->BandwidthBurst) || + config_compare(list, "ContactInfo", CONFIG_TYPE_STRING, &options->ContactInfo) || + config_compare(list, "DebugLogFile", CONFIG_TYPE_STRING, &options->DebugLogFile) || config_compare(list, "DataDirectory", CONFIG_TYPE_STRING, &options->DataDirectory) || config_compare(list, "DirPort", CONFIG_TYPE_INT, &options->DirPort) || @@ -627,10 +630,12 @@ int getconfig(int argc, char **argv, or_options_t *options) { result = -1; } +#if 0 if(options->ORPort && options->DataDirectory == NULL) { log(LOG_WARN,"DataDirectory option required if ORPort is set, but not found."); result = -1; } +#endif if (options->ORPort) { if (options->Nickname == NULL) { @@ -675,6 +680,11 @@ int getconfig(int argc, char **argv, or_options_t *options) { result = -1; } + if(options->AuthoritativeDir && !options->DirPort) { + log(LOG_WARN,"Running as authoritative directory, but no DirPort set."); + result = -1; + } + if(options->SocksPort > 1 && (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) { log(LOG_WARN,"PathlenCoinWeight option must be >=0.0 and <1.0."); @@ -880,6 +890,33 @@ void exit_policy_free(struct exit_policy_t *p) { } } +const char *get_data_directory(or_options_t *options) { + const char *d; + char buf[1024]; + const char *home; + size_t n; + if (options->DataDirectory) + d = options->DataDirectory; + else + d = "~/.tor"; + + if (!strncmp(d,"~/",2)) { + home = getenv("HOME"); + if (!home) { + log_fn(LOG_ERR, "Couldn't find $HOME environment variable for data directory %s", d); + exit(1); + } + n = snprintf(buf,1020,"%s/%s",home,d+2); + if (n>=1020) { + log_fn(LOG_ERR, "Overlong data directory name."); + exit(1); + } + tor_free(options->DataDirectory); + options->DataDirectory = tor_strdup(buf); + } + return options->DataDirectory; +} + /* Local Variables: mode:c diff --git a/src/or/dirserv.c b/src/or/dirserv.c index d2d41627f..e8e727892 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -576,6 +576,23 @@ dirserv_dump_directory_to_string(char *s, unsigned int maxlen, /** Most recently generated encoded signed directory. */ static char *the_directory = NULL; static int the_directory_len = -1; +static char *cached_directory = NULL; +static time_t cached_directory_published = 0; +static int cached_directory_len = -1; + +void dirserv_set_cached_directory(const char *directory, time_t when) +{ + time_t now; + if (!options.AuthoritativeDir) + return; + now = time(NULL); + if (when>cached_directory_published && + when<now+ROUTER_ALLOW_SKEW) { + tor_free(cached_directory); + cached_directory = tor_strdup(directory); + cached_directory_len = strlen(cached_directory); + } +} /** Set *<b>directory</b> to the most recently generated encoded signed * directory, generating a new one as necessary. */ @@ -583,6 +600,15 @@ size_t dirserv_get_directory(const char **directory) { char *new_directory; char filename[512]; + if (!options.AuthoritativeDir) { + if (cached_directory) { + *directory = cached_directory; + return (size_t) cached_directory_len; + } else { + /* no directory yet retrieved */ + return 0; + } + } if (the_directory_is_dirty) { new_directory = tor_malloc(MAX_DIR_SIZE); if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE, diff --git a/src/or/main.c b/src/or/main.c index 4f40f8adb..983e9a34d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -576,6 +576,13 @@ static int init_from_config(int argc, char **argv) { } } + /* Ensure data directory is private; create if possible. */ + if (check_private_dir(get_data_directory(&options), 1) != 0) { + log_fn(LOG_ERR, "Couldn't access/create private data directory %s", + get_data_directory(&options)); + return -1; + } + /* Start backgrounding the process, if requested. */ if (options.RunAsDaemon) { start_daemon(options.DataDirectory); diff --git a/src/or/or.h b/src/or/or.h index a91fae419..e6a014dc5 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -363,7 +363,6 @@ #define RELAY_COMMAND_INTRODUCE2 35 #define RELAY_COMMAND_RENDEZVOUS1 36 #define RELAY_COMMAND_RENDEZVOUS2 37 -/* DOCDOC Spec these next two. */ #define RELAY_COMMAND_INTRO_ESTABLISHED 38 #define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39 #define RELAY_COMMAND_INTRODUCE_ACK 40 @@ -823,6 +822,7 @@ typedef struct { int ORPort; /**< Port to listen on for OR connections. */ int SocksPort; /**< Port to listen on for SOCKS connections. */ int DirPort; /**< Port to listen on for directory connections. */ + int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */ int MaxConn; /**< Maximum number of simultaneous connections. */ int TrafficShaping; /**< Unused. */ int LinkPadding; /**< Unused. */ @@ -848,6 +848,7 @@ typedef struct { * other ORs are running. */ struct config_line_t *RendConfigLines; /**< List of configuration lines * for rendezvous services. */ + char *ContactInfo; /** Contact info to be published in the directory */ } or_options_t; /* XXX are these good enough defaults? */ @@ -989,6 +990,7 @@ int config_init_logs(or_options_t *options); void config_parse_exit_policy(struct config_line_t *cfg, struct exit_policy_t **dest); void exit_policy_free(struct exit_policy_t *p); +const char *get_data_directory(or_options_t *options); /********************************* connection.c ***************************/ @@ -1136,6 +1138,7 @@ int dirserv_dump_directory_to_string(char *s, unsigned int maxlen, void directory_set_dirty(void); size_t dirserv_get_directory(const char **cp); size_t dirserv_get_runningrouters(const char **rr); +void dirserv_set_cached_directory(const char *directory, time_t when); /********************************* dns.c ***************************/ diff --git a/src/or/router.c b/src/or/router.c index ebdea64cd..bd9d5276c 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -532,8 +532,10 @@ int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router, router->address, router->or_port, router->socks_port, - router->dir_port, - /* XXX008 only use dir_port here if authoritative server, else use opt line below */ + /* Due to an 0.0.7 bug, we can't actually say that we have a dirport unles + * we're an authoritative directory. + */ + router->is_trusted_dir ? router->dir_port : 0, router->platform, published, (int) router->bandwidthrate, @@ -550,6 +552,24 @@ int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router, /* From now on, we use 'written' to remember the current length of 's'. */ written = result; + if (router->dir_port && !router->is_trusted_dir) { + /* dircacheport wasn't recognized before 0.0.8pre. (When 0.0.7 is gone, + * we can fold this back into dirport anyway.) + result = snprintf(s+written,maxlen-written, "opt dircacheport %d\n", + router->dir_port); + if (result<0 || result+written > maxlen) + return -1; + written += result; + } + + if (options.ContactInfo && strlen(options.ContactInfo)) { + result = snprintf(s+written,maxlen-written, "opt contact %s\n", + options.ContactInfo); + if (result<0 || result+written > maxlen) + return -1; + written += result; + } + /* Write the exit policy to the end of 's'. */ for(tmpe=router->exit_policy; tmpe; tmpe=tmpe->next) { in.s_addr = htonl(tmpe->addr); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index b77c79692..ed9a06420 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -477,6 +477,7 @@ int router_load_routerlist_from_directory(const char *s, log_fn(LOG_WARN, "Error resolving routerlist"); return -1; } + dirserv_set_cached_directory(s, routerlist->published_on); return 0; } diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 130497501..efd8f3731 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -39,6 +39,8 @@ typedef enum { K_OPT, K_BANDWIDTH, K_PORTS, + K_DIRCACHEPORT, + K_CONTACT, _UNRECOGNIZED, _ERR, _EOF, @@ -109,7 +111,8 @@ static struct { { "platform", K_PLATFORM, CONCAT_ARGS, NO_OBJ, RTR_ONLY }, { "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ, ANY }, { "opt", K_OPT, CONCAT_ARGS, OBJ_OK, ANY }, - + { "dircacheport", K_DIRCACHEPORT, ARGS, NO_OBJ, RTR_ONLY }, + { "contact", K_CONTACT, CONCAT_ARGS, NO_OBJ, ANY }, { NULL, -1 } }; @@ -587,6 +590,17 @@ routerinfo_t *router_parse_entry_from_string(const char *s, ports_set = 1; } + tok = find_first_by_keyword(tokens, K_DIRCACHEPORT); + if (tok) { + if (router->dir_port) + log_fn(LOG_WARN,"Redundant dircacheport line"); + if (tok->n_args != 1) { + log_fn(LOG_WARN,"Wrong # of arguments to \"dircacheport\""); + goto err; + } + router->dir_port = atoi(tok->args[0]); + } + tok = find_first_by_keyword(tokens, K_BANDWIDTH); if (tok && bw_set) { log_fn(LOG_WARN,"Redundant bandwidth line"); @@ -898,7 +912,7 @@ token_free(directory_token_t *tok) static directory_token_t * get_next_token(const char **s, where_syntax where) { const char *next, *obstart; - int i, done, allocated; + int i, done, allocated, is_opt; directory_token_t *tok; arg_syntax a_syn; obj_syntax o_syn = NO_OBJ; @@ -923,7 +937,17 @@ get_next_token(const char **s, where_syntax where) { tok->error = "Unexpected EOF"; return tok; } /* It's a keyword... but which one? */ - for (i = 0 ; token_table[i].t ; ++i) { + is_opt = !strncmp("opt", *s, next-*s); + if (is_opt) { + *s = eat_whitespace(next); + next = NULL; + if (**s) + next = find_whitespace(*s); + if (!**s || !next) { + RET_ERR("opt without keyword"); + } + } + for (i = 0; token_table[i].t ; ++i) { if (!strncmp(token_table[i].t, *s, next-*s)) { /* We've found the keyword. */ tok->tp = token_table[i].v; @@ -979,16 +1003,29 @@ get_next_token(const char **s, where_syntax where) { } } if (tok->tp == _ERR) { - tok->tp = _UNRECOGNIZED; - next = strchr(*s, '\n'); - if (!next) { - RET_ERR("Unexpected EOF"); + if (is_opt) { + tok->tp = K_OPT; + *s = eat_whitespace_no_nl(next); + next = strchr(*s,'\n'); + if (!next) + RET_ERR("Unexpected EOF"); + tok->args = tor_malloc(sizeof(char*)); + tok->args[0] = tor_strndup(*s,next-*s); + tok->n_args = 1; + *s = eat_whitespace_no_nl(next+1); + a_syn = OBJ_OK; + } else { + tok->tp = _UNRECOGNIZED; + next = strchr(*s, '\n'); + if (!next) { + RET_ERR("Unexpected EOF"); + } + tok->args = tor_malloc(sizeof(char*)); + tok->args[0] = tor_strndup(*s,next-*s); + tok->n_args = 1; + *s = next+1; + o_syn = OBJ_OK; } - tok->args = tor_malloc(sizeof(char*)); - tok->args[0] = tor_strndup(*s,next-*s); - tok->n_args = 1; - *s = next+1; - o_syn = OBJ_OK; } *s = eat_whitespace(*s); if (strncmp(*s, "-----BEGIN ", 11)) { diff --git a/src/or/test.c b/src/or/test.c index caf081476..5ee586611 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -666,6 +666,7 @@ test_dir_format() r1.or_port = 9000; r1.socks_port = 9002; r1.dir_port = 9003; + r1.is_trusted_dir = 1; r1.onion_pkey = pk1; r1.identity_pkey = pk2; r1.bandwidthrate = 1000; |