diff options
author | Roger Dingledine <arma@torproject.org> | 2004-11-09 04:28:18 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-11-09 04:28:18 +0000 |
commit | 90b47172bd3644704aa961862dc7a79e5f10a069 (patch) | |
tree | 0871be52adea1ca75439dc23d343ce50857872e3 /src | |
parent | 3805221262c92802dfe57eff4cc8652ee62b8537 (diff) | |
download | tor-90b47172bd3644704aa961862dc7a79e5f10a069.tar.gz tor-90b47172bd3644704aa961862dc7a79e5f10a069.zip |
Make an options_act() where we do all the things a new options set
needs.
Still needs more work.
svn:r2716
Diffstat (limited to 'src')
-rw-r--r-- | src/or/config.c | 97 | ||||
-rw-r--r-- | src/or/control.c | 6 | ||||
-rw-r--r-- | src/or/main.c | 104 | ||||
-rw-r--r-- | src/or/or.h | 3 |
4 files changed, 106 insertions, 104 deletions
diff --git a/src/or/config.c b/src/or/config.c index 6ca23e8371..3e250a5208 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -204,26 +204,95 @@ get_options(void) { */ void set_options(or_options_t *new_val) { - struct config_line_t *cl; - if (global_options) options_free(global_options); global_options = new_val; +} + +/** Fetch the active option list, and take actions based on it. All + * of the things we do should survive being done repeatedly. + * Return 0 if all goes well, return -1 if it's time to die. + */ +int +options_act(void) { + struct config_line_t *cl; + or_options_t *options = get_options(); clear_trusted_dir_servers(); - for (cl = new_val->DirServers; cl; cl = cl->next) { + for (cl = options->DirServers; cl; cl = cl->next) { if (parse_dir_server_line(cl->value, 0)<0) { log_fn(LOG_ERR, "Previously validated DirServer line could not be added!"); - tor_assert(0); + return -1; } } - if (rend_config_services(new_val, 0)<0) { + if (rend_config_services(options, 0)<0) { log_fn(LOG_ERR, "Previously validated hidden services line could not be added!"); - tor_assert(0); + return -1; + } + + /* Setuid/setgid as appropriate */ + if(options->User || options->Group) { + if(switch_id(options->User, options->Group) != 0) { + return -1; + } } + +/*XXX in options_validate, we should check if this is going to fail */ + /* Ensure data directory is private; create if possible. */ + if (get_data_directory() && + check_private_dir(get_data_directory(), 1) != 0) { + log_fn(LOG_ERR, "Couldn't access/create private data directory %s", + get_data_directory()); + return -1; + } + + /* Bail out at this point if we're not going to be a server: we want + * to not fork, and to log stuff to stderr. */ + if (options->command != CMD_RUN_TOR) + return 0; + + if (set_max_file_descriptors(get_options()->MaxConn) < 0) + return -1; + + /* Configure the log(s) */ + if (config_init_logs(options)<0) + return -1; + /* Close the temporary log we used while starting up, if it isn't already + * gone. */ + close_temp_logs(); + add_callback_log(LOG_WARN, LOG_ERR, control_event_logmsg); + + /* Start backgrounding the process, if requested. */ + if (options->RunAsDaemon) { + start_daemon(get_data_directory()); + } + + /* Finish backgrounding the process */ + if(options->RunAsDaemon) { + /* XXXX Can we delay this any more? */ + finish_daemon(); + } + + /* Write our pid to the pid file. If we do not have write permissions we + * will log a warning */ + if(options->PidFile) + write_pidfile(options->PidFile); + + /* reload keys as needed for rendezvous services. */ + if (rend_service_load_keys()<0) { + log_fn(LOG_ERR,"Error reloading rendezvous service keys"); + return -1; + } + + if(retry_all_listeners(1) < 0) { + log_fn(LOG_ERR,"Failed to bind one of the listener ports."); + return -1; + } + + return 0; } /* @@ -612,7 +681,6 @@ config_trial_assign(or_options_t **options, struct config_line_t *list, int rese return -3; } - set_options(trial_options); return 0; } @@ -1219,9 +1287,10 @@ static int check_nickname_list(const char *lst, const char *name) /** Read a configuration file into <b>options</b>, finding the configuration * file location based on the command line. After loading the options, - * validate them for consistency. Return 0 if success, <0 if failure. */ + * validate them for consistency, then take actions based on them. + * Return 0 if success, -1 if failure. */ int -getconfig(int argc, char **argv) +init_from_config(int argc, char **argv) { or_options_t *oldoptions, *newoptions; struct config_line_t *cl; @@ -1318,21 +1387,25 @@ getconfig(int argc, char **argv) goto err; } -/* go through command-line variables too */ + /* Go through command-line variables too */ cl = config_get_commandlines(argc,argv); retval = config_assign(newoptions,cl,0); config_free_lines(cl); if (retval < 0) goto err; -/* Validate newoptions */ + /* Validate newoptions */ if (options_validate(newoptions) < 0) goto err; if (options_transition_allowed(oldoptions, newoptions) < 0) goto err; - set_options(newoptions); + set_options(newoptions); /* frees and replaces old options */ + if (options_act() < 0) { /* acting on them failed. die. */ + log_fn(LOG_ERR,"Acting on config options left us in a broken state. Dying."); + exit(1); + } return 0; err: options_free(newoptions); diff --git a/src/or/control.c b/src/or/control.c index e0d0360d05..bc5cfeea82 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -222,8 +222,12 @@ handle_control_setconf(connection_t *conn, uint16_t len, char *body) return 0; } - set_options(options); /* put the new one into place */ config_free_lines(lines); + set_options(options); /* put the new one into place */ + if (options_act() < 0) { /* acting on them failed. die. */ + log_fn(LOG_ERR,"Acting on config options left us in a broken state. Dying."); + exit(1); + } send_control_done(conn); return 0; } diff --git a/src/or/main.c b/src/or/main.c index 29b6216bfb..3af6adb99b 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -14,7 +14,6 @@ /********* PROTOTYPES **********/ static void dumpstats(int severity); /* log stats */ -static int init_from_config(int argc, char **argv); /********* START VARIABLES **********/ @@ -689,72 +688,6 @@ static int prepare_for_poll(void) { return (1000 - (now.tv_usec / 1000)); /* how many milliseconds til the next second? */ } -/** Configure the Tor process from the command line arguments and from the - * configuration file. - */ -static int init_from_config(int argc, char **argv) { - or_options_t *options; - - /* read the configuration file. init and assign options. */ - if(getconfig(argc,argv) < 0) { - log_fn(LOG_ERR,"Reading config failed--see warnings above. For usage, try -h."); - return -1; - } - - options = get_options(); - - /* Setuid/setgid as appropriate */ - if(options->User || options->Group) { - if(switch_id(options->User, options->Group) != 0) { - return -1; - } - } - - /* Ensure data directory is private; create if possible. */ - if (get_data_directory() && - check_private_dir(get_data_directory(), 1) != 0) { - log_fn(LOG_ERR, "Couldn't access/create private data directory %s", - get_data_directory()); - return -1; - } - - /* Bail out at this point if we're not going to be a server: we want - * to not fork, and to log stuff to stderr. */ - if (options->command != CMD_RUN_TOR) - return 0; - - /* Configure the log(s) */ - if (config_init_logs(options)<0) - return -1; - /* Close the temporary log we used while starting up, if it isn't already - * gone. */ - close_temp_logs(); - add_callback_log(LOG_WARN, LOG_ERR, control_event_logmsg); - - /* Start backgrounding the process, if requested. */ - if (options->RunAsDaemon) { - start_daemon(get_data_directory()); - } - - /* Set up our buckets */ - connection_bucket_init(); - stats_prev_global_read_bucket = global_read_bucket; - stats_prev_global_write_bucket = global_write_bucket; - - /* Finish backgrounding the process */ - if(options->RunAsDaemon) { - /* XXXX Can we delay this any more? */ - finish_daemon(); - } - - /* Write our pid to the pid file. If we do not have write permissions we - * will log a warning */ - if(options->PidFile) - write_pidfile(options->PidFile); - - return 0; -} - /** Called when we get a SIGHUP: reload configuration files and keys, * retry all connections, re-upload all descriptors, and so on. */ static int do_hup(void) { @@ -766,17 +699,11 @@ static int do_hup(void) { /* first, reload config variables, in case they've changed */ /* no need to provide argc/v, they've been cached inside init_from_config */ if (init_from_config(0, NULL) < 0) { + log_fn(LOG_ERR,"Reading config failed--see warnings above. For usage, try -h."); return -1; } - /* reload keys as needed for rendezvous services. */ - if (rend_service_load_keys()<0) { - log_fn(LOG_ERR,"Error reloading rendezvous service keys"); - return -1; - } - if(retry_all_listeners(1) < 0) { - log_fn(LOG_ERR,"Failed to bind one of the listener ports."); - return -1; - } +/*XXX this should move to options_act, but only once it's been + * removed from init_keys() */ if(authdir_mode(get_options())) { /* reload the approved-routers file */ tor_snprintf(keydir,sizeof(keydir),"%s/approved-routers", get_data_directory()); @@ -816,11 +743,17 @@ static int do_main_loop(void) { /* load the private keys, if we're supposed to have them, and set up the * TLS context. */ - if (init_keys() < 0 || rend_service_load_keys() < 0) { + if (init_keys() < 0) { log_fn(LOG_ERR,"Error initializing keys; exiting"); return -1; } + /* Set up our buckets */ + connection_bucket_init(); + stats_prev_global_read_bucket = global_read_bucket; + stats_prev_global_write_bucket = global_write_bucket; + +/*XXX move to options_act? */ /* Set up accounting */ if (get_options()->AccountingMaxKB) configure_accounting(time(NULL)); @@ -840,12 +773,6 @@ static int do_main_loop(void) { cpu_init(); } - /* start up the necessary listeners based on which ports are non-zero. */ - if(retry_all_listeners(1) < 0) { - log_fn(LOG_ERR,"Failed to bind one of the listener ports."); - return -1; - } - for(;;) { #ifdef MS_WINDOWS_SERVICE /* Do service stuff only on windows. */ if (service_status.dwCurrentState != SERVICE_RUNNING) { @@ -1079,8 +1006,10 @@ static int tor_init(int argc, char *argv[]) { } atexit(exit_function); - if (init_from_config(argc,argv) < 0) + if (init_from_config(argc,argv) < 0) { + log_fn(LOG_ERR,"Reading config failed--see warnings above. For usage, try -h."); return -1; + } #ifndef MS_WINDOWS if(geteuid()==0) @@ -1090,15 +1019,10 @@ static int tor_init(int argc, char *argv[]) { if(server_mode(get_options())) { /* only spawn dns handlers if we're a router */ dns_init(); /* initialize the dns resolve tree, and spawn workers */ } - if(proxy_mode(get_options())) { - client_dns_init(); /* init the client dns cache */ - } + client_dns_init(); /* Init the client dns cache. Do it always, since it's cheap. */ handle_signals(1); - if (set_max_file_descriptors(get_options()->MaxConn) < 0) - return -1; - crypto_global_init(); crypto_seed_rng(); return 0; diff --git a/src/or/or.h b/src/or/or.h index fdebbeaaeb..79094c5de5 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1093,13 +1093,14 @@ struct config_line_t { or_options_t *get_options(void); void set_options(or_options_t *new_val); +int options_act(void); int config_get_lines(char *string, struct config_line_t **result); void config_free_lines(struct config_line_t *front); int config_trial_assign(or_options_t **options, struct config_line_t *list, int reset); int resolve_my_address(const char *address, uint32_t *addr); void options_init(or_options_t *options); -int getconfig(int argc, char **argv); +int init_from_config(int argc, char **argv); int config_init_logs(or_options_t *options); void config_parse_exit_policy(struct config_line_t *cfg, struct exit_policy_t **dest); |