config_compare(list, "RouterFile", CONFIG_TYPE_STRING, &options->RouterFile) ||
config_compare(list, "RunAsDaemon", CONFIG_TYPE_BOOL, &options->RunAsDaemon) ||
+ config_compare(list, "RecommendedVersions", CONFIG_TYPE_STRING, &options->RecommendedVersions) ||
config_compare(list, "SocksPort", CONFIG_TYPE_INT, &options->SocksPort) ||
config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) ||
tor_free(options->SocksBindAddress);
tor_free(options->ORBindAddress);
tor_free(options->DirBindAddress);
+ tor_free(options->RecommendedVersions);
tor_free(options->User);
tor_free(options->Group);
}
options->SocksBindAddress = tor_strdup("127.0.0.1");
options->ORBindAddress = tor_strdup("0.0.0.0");
options->DirBindAddress = tor_strdup("0.0.0.0");
+ options->RecommendedVersions = tor_strdup("none");
options->loglevel = LOG_INFO;
options->PidFile = tor_strdup("tor.pid");
options->DataDirectory = NULL;
char *fname;
int i;
int result = 0;
-
+ static int first_load = 1;
+ static char **backup_argv;
+ static int backup_argc;
+ char *previous_pidfile = NULL;
+ int previous_runasdaemon = 0;
+ int previous_onionrouter = -1;
+
+ if(first_load) { /* first time we're called. save commandline args */
+ backup_argv = argv;
+ backup_argc = argc;
+ first_load = 0;
+ } else { /* we're reloading. need to clean up old ones first. */
+ argv = backup_argv;
+ argc = backup_argc;
+
+ /* record some previous values, so we can fail if they change */
+ previous_pidfile = tor_strdup(options->PidFile);
+ previous_runasdaemon = options->RunAsDaemon;
+ previous_onionrouter = options->OnionRouter;
+ free_options(options);
+ }
init_options(options);
if(argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
/* Validate options */
+ /* first check if some of the previous options have changed but aren't allowed to */
+ if(previous_pidfile && strcmp(previous_pidfile,options->PidFile)) {
+ log_fn(LOG_WARN,"During reload, PidFile changed from %s to %s. Failing.",
+ previous_pidfile, options->PidFile);
+ return -1;
+ }
+ tor_free(previous_pidfile);
+
+ if(previous_runasdaemon && !options->RunAsDaemon) {
+ log_fn(LOG_WARN,"During reload, change from RunAsDaemon=1 to =0 not allowed. Failing.");
+ return -1;
+ }
+ if(previous_onionrouter >= 0 && previous_onionrouter != options->OnionRouter) {
+ log_fn(LOG_WARN,"During reload, OnionRouter changed from %d to %d. Failing.",
+ previous_onionrouter, options->OnionRouter);
+ return -1;
+ }
+
if(options->LogLevel) {
if(!strcmp(options->LogLevel,"err"))
options->loglevel = LOG_ERR;
}
(*desc_ent_ptr) = tor_malloc(sizeof(descriptor_entry_t));
- (*desc_ent_ptr)->nickname = strdup(ri->nickname);
+ (*desc_ent_ptr)->nickname = tor_strdup(ri->nickname);
(*desc_ent_ptr)->published = ri->published_on;
(*desc_ent_ptr)->desc_len = desc_len;
(*desc_ent_ptr)->descriptor = tor_malloc(desc_len+1);
snprintf(s, maxlen,
"signed-directory\n"
"published %s\n"
- "recommended-software "RECOMMENDED_SOFTWARE_VERSIONS"\n"
- "running-routers %s\n\n", published, cp);
+ "recommended-software %s\n"
+ "running-routers %s\n\n", published, options.RecommendedVersions, cp);
free(cp);
i = strlen(s);
cp = s+i;
dns_found_answer(conn->address, answer);
free(conn->address);
- conn->address = strdup("<idle>");
+ conn->address = tor_strdup("<idle>");
conn->state = DNSWORKER_STATE_IDLE;
num_dnsworkers_busy--;
/********* START PROTOTYPES **********/
static void dumpstats(int severity); /* log stats */
+static int init_from_config(int argc, char **argv);
/********* START VARIABLES **********/
#ifndef MS_WINDOWS /* do signal stuff only on unix */
static int please_dumpstats=0; /* whether we should dump stats during the loop */
-static int please_reset =0; /* whether we just got a sighup */
-static int please_reap_children=0; /* whether we should waitpid for exited children*/
+static int please_reset=0; /* whether we just got a sighup */
+static int please_reap_children=0; /* whether we should waitpid for exited children */
#endif /* signal stuff */
/* private keys */
return 0;
}
+static int init_from_config(int argc, char **argv) {
+ static int have_daemonized=0;
+
+ if(getconfig(argc,argv,&options)) {
+ log_fn(LOG_ERR,"Reading config failed. For usage, try -h.");
+ return -1;
+ }
+ log_set_severity(options.loglevel); /* assign logging severity level from options */
+ close_logs(); /* we'll close, then open with correct loglevel if necessary */
+ if(!options.LogFile && !options.RunAsDaemon)
+ add_stream_log(options.loglevel, "<stdout>", stdout);
+ if(options.DebugLogFile)
+ add_file_log(LOG_DEBUG, options.DebugLogFile);
+ if(options.LogFile)
+ add_file_log(options.loglevel, options.LogFile);
+
+ global_read_bucket = options.TotalBandwidth; /* start it at 1 second of traffic */
+ stats_prev_global_read_bucket = global_read_bucket;
+
+ /* write our pid to the pid file */
+ write_pidfile(options.PidFile);
+ /* XXX Is overwriting the pidfile ok? I think it is. -RD */
+
+ /* now that we've written the pid file, we can switch the user and group. */
+ if(options.User || options.Group) {
+ if(switch_id(options.User, options.Group) != 0) {
+ return -1;
+ }
+ }
+
+ if(options.RunAsDaemon && !have_daemonized) {
+ daemonize();
+ have_daemonized = 1;
+ }
+
+ return 0;
+}
+
static int do_main_loop(void) {
int i;
int timeout;
please_dumpstats = 0;
}
if(please_reset) {
+ log_fn(LOG_INFO,"Hupped. Reloading config.");
+ /* first, reload config variables, in case they've changed */
+ if (init_from_config(0, NULL) < 0) {
+ /* no need to provide argc/v, they've been cached inside init_from_config */
+ exit(1);
+ }
+
/* fetch a new directory */
if(options.DirPort) {
directory_initiate_command(router_pick_directory_server(), DIR_CONN_STATE_CONNECTING_FETCH);
}
- /* close and reopen the log files */
- reset_logs();
-
please_reset = 0;
}
if(please_reap_children) {
add_stream_log(LOG_INFO, "<stdout>", stdout);
log_fn(LOG_WARN,"Tor v%s. This is experimental software. Do not use it if you need anonymity.",VERSION);
- if(getconfig(argc,argv,&options)) {
- log_fn(LOG_ERR,"Reading config failed. For usage, try -h.");
+ if (init_from_config(argc,argv) < 0)
return -1;
- }
- log_set_severity(options.loglevel); /* assign logging severity level from options */
- close_logs(); /* close stdout, then open with correct loglevel if necessary */
- if(!options.LogFile && !options.RunAsDaemon)
- add_stream_log(options.loglevel, "<stdout>", stdout);
- if(options.DebugLogFile)
- add_file_log(LOG_DEBUG, options.DebugLogFile);
- if(options.LogFile)
- add_file_log(options.loglevel, options.LogFile);
-
- global_read_bucket = options.TotalBandwidth; /* start it at 1 second of traffic */
- stats_prev_global_read_bucket = global_read_bucket;
-
- /* write our pid to the pid file */
- write_pidfile(options.PidFile);
-
- /* now that we've written the pid file, we can switch the user and group. */
- if(options.User || options.Group) {
- if(switch_id(options.User, options.Group) != 0) {
- return -1;
- }
- }
-
- if(options.RunAsDaemon)
- daemonize();
if(options.OnionRouter) { /* only spawn dns handlers if we're a router */
dns_init(); /* initialize the dns resolve tree, and spawn workers */
#include "../common/log.h"
#include "../common/util.h"
-#define RECOMMENDED_SOFTWARE_VERSIONS "0.0.2pre13,0.0.2pre14"
-
#define MAXCONNECTIONS 1000 /* upper bound on max connections.
can be lowered by config file */
char *SocksBindAddress;
char *ORBindAddress;
char *DirBindAddress;
+ char *RecommendedVersions;
char *User;
char *Group;
double CoinWeight;
int NewCircuitPeriod;
int TotalBandwidth;
int NumCpus;
- int Role;
int loglevel;
} or_options_t;
test_eq(-1, compare_recommended_versions("a", "ab,abd,abde,abc,abcde"));
test_eq(-1, compare_recommended_versions("abb", "ab,abd,abde,abc,abcde"));
test_eq(-1, compare_recommended_versions("a", ""));
- test_eq(0, compare_recommended_versions(VERSION, RECOMMENDED_SOFTWARE_VERSIONS));
}
int