mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
a whole swath of fixes
introduce an authdir_mode() macro to match the others. don't initialize uptime to the number of seconds since 1970. non-authoritative dirservers don't cache their directory on disk. make only authdirservers use clique_mode. only read approved-routers file if you're an authdirserver. even authdirservers fetch a new directory in do_hup. retry_all_connections() is now called retry_all_listeners(). router_parse_list_from_string() correctly reports the router number it's working on. only call dirserv_add_own_fingerprint() and dirserv_add_descriptor() on startup if we're an authdirserver. if AuthDir and !ORPort then fail. if AuthDir and ClientOnly then fail. svn:r2061
This commit is contained in:
+8
-2
@@ -726,9 +726,15 @@ int getconfig(int argc, char **argv, or_options_t *options) {
|
||||
result = -1;
|
||||
}
|
||||
|
||||
/* XXX008 if AuthDir and !ORPort then fail */
|
||||
if(options->AuthoritativeDir && !options->ORPort) {
|
||||
log(LOG_WARN,"Running as authoritative directory, but no ORPort set.");
|
||||
result = -1;
|
||||
}
|
||||
|
||||
/* XXX008 if AuthDir and ClientOnly then fail */
|
||||
if(options->AuthoritativeDir && options->ClientOnly) {
|
||||
log(LOG_WARN,"Running as authoritative directory, but ClientOnly also set.");
|
||||
result = -1;
|
||||
}
|
||||
|
||||
if(options->SocksPort >= 1 &&
|
||||
(options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) {
|
||||
|
||||
+2
-7
@@ -540,14 +540,9 @@ static int retry_listeners(int type, struct config_line_t *cfg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Start all connections that should be up but aren't.
|
||||
* - Connect to all ORs if you're an OR.
|
||||
* - Relaunch listeners for each port you have open.
|
||||
/** (Re)launch listeners for each port you should have open.
|
||||
*/
|
||||
int retry_all_connections(void) {
|
||||
if(clique_mode()) {
|
||||
router_retry_connections();
|
||||
}
|
||||
int retry_all_listeners(void) {
|
||||
|
||||
if (retry_listeners(CONN_TYPE_OR_LISTENER, options.ORBindAddress,
|
||||
options.ORPort, "0.0.0.0")<0)
|
||||
|
||||
@@ -619,7 +619,6 @@ static int cached_directory_len = -1;
|
||||
void dirserv_set_cached_directory(const char *directory, time_t when)
|
||||
{
|
||||
time_t now;
|
||||
char filename[512];
|
||||
tor_assert(!options.AuthoritativeDir);
|
||||
now = time(NULL);
|
||||
if (when>cached_directory_published &&
|
||||
@@ -628,10 +627,6 @@ void dirserv_set_cached_directory(const char *directory, time_t when)
|
||||
cached_directory = tor_strdup(directory);
|
||||
cached_directory_len = strlen(cached_directory);
|
||||
cached_directory_published = when;
|
||||
sprintf(filename,"%s/cached-directory", get_data_directory(&options));
|
||||
if(write_str_to_file(filename,cached_directory) < 0) {
|
||||
log_fn(LOG_WARN, "Couldn't write cached directory to disk. Ignoring.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+44
-25
@@ -361,7 +361,7 @@ static void run_connection_housekeeping(int i, time_t now) {
|
||||
if(conn->type == CONN_TYPE_DIR &&
|
||||
!conn->marked_for_close &&
|
||||
conn->timestamp_lastwritten + 5*60 < now) {
|
||||
log_fn(LOG_WARN,"Expiring wedged directory conn (fd %d, purpose %d)", conn->s, conn->purpose);
|
||||
log_fn(LOG_INFO,"Expiring wedged directory conn (fd %d, purpose %d)", conn->s, conn->purpose);
|
||||
connection_mark_for_close(conn);
|
||||
return;
|
||||
}
|
||||
@@ -403,28 +403,49 @@ static void run_connection_housekeeping(int i, time_t now) {
|
||||
* - We believe we are reachable from the outside.
|
||||
*/
|
||||
static int decide_if_publishable_server(time_t now) {
|
||||
int r;
|
||||
|
||||
if(options.AuthoritativeDir)
|
||||
return 1;
|
||||
if(options.ClientOnly)
|
||||
return 0;
|
||||
if(!options.ORPort)
|
||||
return 0;
|
||||
|
||||
/* here, determine if we're reachable */
|
||||
|
||||
/* XXX008 for now, you're only a server if you're a server */
|
||||
return server_mode();
|
||||
|
||||
|
||||
/* here, determine if we're reachable */
|
||||
if(0) { /* we've recently failed to reach our IP/ORPort from the outside */
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = rep_hist_bandwidth_assess(now);
|
||||
|
||||
|
||||
// set_advertised_bandwidth(r);
|
||||
|
||||
if(r < MIN_BW_TO_PUBLISH_DESC)
|
||||
return 0;
|
||||
if(options.AuthoritativeDir)
|
||||
return 1;
|
||||
if(stats_n_seconds_uptime < MIN_UPTIME_TO_PUBLISH_DESC)
|
||||
return 0;
|
||||
if(rep_hist_bandwidth_assess(now) < MIN_BW_TO_PUBLISH_DESC)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Return true iff we try to stay connected to all ORs at once. This
|
||||
* option should go away as Tor becomes more P2P.
|
||||
/** Return true iff we believe ourselves to be an authoritative
|
||||
* directory server.
|
||||
*/
|
||||
int authdir_mode(void) {
|
||||
return (options.AuthoritativeDir != 0);
|
||||
}
|
||||
|
||||
/** Return true iff we try to stay connected to all ORs at once.
|
||||
*/
|
||||
int clique_mode(void) {
|
||||
return (options.ORPort != 0);
|
||||
return authdir_mode();
|
||||
}
|
||||
|
||||
/** Return true iff we are trying to be a server.
|
||||
@@ -495,10 +516,10 @@ static void run_scheduled_events(time_t now) {
|
||||
|
||||
routerlist_remove_old_routers(); /* purge obsolete entries */
|
||||
|
||||
if(options.AuthoritativeDir) {
|
||||
if(authdir_mode()) {
|
||||
/* We're a directory; dump any old descriptors. */
|
||||
dirserv_remove_old_servers();
|
||||
/* dirservers try to reconnect too, in case connections have failed */
|
||||
/* dirservers try to reconnect, in case connections have failed */
|
||||
router_retry_connections();
|
||||
}
|
||||
|
||||
@@ -582,7 +603,8 @@ static int prepare_for_poll(void) {
|
||||
|
||||
if(now.tv_sec > current_second) { /* the second has rolled over. check more stuff. */
|
||||
|
||||
stats_n_seconds_uptime += (now.tv_sec - current_second);
|
||||
if(current_second)
|
||||
stats_n_seconds_uptime += (now.tv_sec - current_second);
|
||||
assert_all_pending_dns_resolves_ok();
|
||||
run_scheduled_events(now.tv_sec);
|
||||
assert_all_pending_dns_resolves_ok();
|
||||
@@ -674,11 +696,11 @@ static int do_hup(void) {
|
||||
log_fn(LOG_ERR,"Error reloading rendezvous service keys");
|
||||
exit(1);
|
||||
}
|
||||
if(retry_all_connections() < 0) {
|
||||
if(retry_all_listeners() < 0) {
|
||||
log_fn(LOG_ERR,"Failed to bind one of the listener ports.");
|
||||
return -1;
|
||||
}
|
||||
if(options.DirPort) {
|
||||
if(authdir_mode()) {
|
||||
/* reload the approved-routers file */
|
||||
sprintf(keydir,"%s/approved-routers", get_data_directory(&options));
|
||||
log_fn(LOG_INFO,"Reloading approved fingerprints from %s...",keydir);
|
||||
@@ -688,10 +710,9 @@ static int do_hup(void) {
|
||||
/* Since we aren't fetching a directory, we won't retry rendezvous points
|
||||
* when it gets in. Try again now. */
|
||||
rend_services_introduce();
|
||||
} else {
|
||||
/* fetch a new directory */
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 0);
|
||||
}
|
||||
/* Fetch a new directory. Even authdirservers do this. */
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 0);
|
||||
if(server_mode()) {
|
||||
/* Restart cpuworker and dnsworker processes, so they get up-to-date
|
||||
* configuration options. */
|
||||
@@ -736,20 +757,18 @@ static int do_main_loop(void) {
|
||||
}
|
||||
}
|
||||
|
||||
if(options.DirPort) { /* the directory is already here, run startup things */
|
||||
has_fetched_directory = 1;
|
||||
if(authdir_mode()) {
|
||||
/* the directory is already here, run startup things */
|
||||
directory_has_arrived();
|
||||
}
|
||||
|
||||
if(server_mode()) {
|
||||
cpu_init(); /* launch cpuworkers. Need to do this *after* we've read the onion key. */
|
||||
/* launch cpuworkers. Need to do this *after* we've read the onion key. */
|
||||
cpu_init();
|
||||
}
|
||||
|
||||
/* start up the necessary connections based on which ports are
|
||||
* non-zero. This is where we try to connect to all the other ORs,
|
||||
* and start the listeners.
|
||||
*/
|
||||
if(retry_all_connections() < 0) {
|
||||
/* start up the necessary listeners based on which ports are non-zero. */
|
||||
if(retry_all_listeners() < 0) {
|
||||
log_fn(LOG_ERR,"Failed to bind one of the listener ports.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1043,7 +1043,7 @@ int _connection_mark_for_close(connection_t *conn);
|
||||
void connection_expire_held_open(void);
|
||||
|
||||
int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port);
|
||||
int retry_all_connections(void);
|
||||
int retry_all_listeners(void);
|
||||
|
||||
void connection_bucket_init(void);
|
||||
void connection_bucket_refill(struct timeval *now);
|
||||
@@ -1194,6 +1194,7 @@ void connection_stop_writing(connection_t *conn);
|
||||
void connection_start_writing(connection_t *conn);
|
||||
|
||||
void directory_has_arrived(void);
|
||||
int authdir_mode(void);
|
||||
int clique_mode(void);
|
||||
int server_mode(void);
|
||||
int exit_server_mode(void);
|
||||
|
||||
+24
-22
@@ -280,20 +280,23 @@ int init_keys(void) {
|
||||
}
|
||||
/* 4. Dump router descriptor to 'router.desc' */
|
||||
/* Must be called after keys are initialized. */
|
||||
if (!(router_get_my_descriptor())) {
|
||||
tmp = mydesc = router_get_my_descriptor();
|
||||
if (!mydesc) {
|
||||
log_fn(LOG_ERR, "Error initializing descriptor.");
|
||||
return -1;
|
||||
}
|
||||
/* We need to add our own fingerprint so it gets recognized. */
|
||||
if (dirserv_add_own_fingerprint(options.Nickname, get_identity_key())) {
|
||||
log_fn(LOG_ERR, "Error adding own fingerprint to approved set");
|
||||
return -1;
|
||||
}
|
||||
tmp = mydesc = router_get_my_descriptor();
|
||||
if (dirserv_add_descriptor(&tmp) != 1) {
|
||||
log(LOG_ERR, "Unable to add own descriptor to directory.");
|
||||
return -1;
|
||||
if(authdir_mode()) {
|
||||
/* We need to add our own fingerprint so it gets recognized. */
|
||||
if (dirserv_add_own_fingerprint(options.Nickname, get_identity_key())) {
|
||||
log_fn(LOG_ERR, "Error adding own fingerprint to approved set");
|
||||
return -1;
|
||||
}
|
||||
if (dirserv_add_descriptor(&tmp) != 1) {
|
||||
log(LOG_ERR, "Unable to add own descriptor to directory.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(keydir,"%s/router.desc", datadir);
|
||||
log_fn(LOG_INFO,"Dumping descriptor to %s...",keydir);
|
||||
if (write_str_to_file(keydir, mydesc)) {
|
||||
@@ -313,31 +316,26 @@ int init_keys(void) {
|
||||
strcat(fingerprint, "\n");
|
||||
if (write_str_to_file(keydir, fingerprint))
|
||||
return -1;
|
||||
if(!options.DirPort)
|
||||
if(!authdir_mode())
|
||||
return 0;
|
||||
/* 6. [dirserver only] load approved-routers file */
|
||||
/* 6. [authdirserver only] load approved-routers file */
|
||||
sprintf(keydir,"%s/approved-routers", datadir);
|
||||
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 */
|
||||
/* 7. [authdirserver only] load old directory, if it's there */
|
||||
sprintf(keydir,"%s/cached-directory", datadir);
|
||||
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(options.AuthoritativeDir) {
|
||||
if(dirserv_load_from_directory_string(cp) < 0){
|
||||
log_fn(LOG_ERR, "Cached directory %s is corrupt", keydir);
|
||||
tor_free(cp);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* set time to 1 so it will be replaced on first download. */
|
||||
dirserv_set_cached_directory(cp, 1);
|
||||
if(dirserv_load_from_directory_string(cp) < 0){
|
||||
log_fn(LOG_ERR, "Cached directory %s is corrupt", keydir);
|
||||
tor_free(cp);
|
||||
return -1;
|
||||
}
|
||||
tor_free(cp);
|
||||
}
|
||||
@@ -510,6 +508,10 @@ int router_rebuild_descriptor(void) {
|
||||
log_fn(LOG_WARN, "Couldn't dump router to string.");
|
||||
return -1;
|
||||
}
|
||||
/* XXX008 NM: no, we shouldn't just blindly assume we're an
|
||||
* authdirserver just because our dir_port is set. We should
|
||||
* take these next two lines out, and then set our is_trusted_dir
|
||||
* variable if we find ourselves in the dirservers file. Yes/no? */
|
||||
if (ri->dir_port)
|
||||
ri->is_trusted_dir = 1;
|
||||
return 0;
|
||||
|
||||
@@ -330,7 +330,7 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
log_fn(LOG_WARN, "Unable to compute digest of directory");
|
||||
goto err;
|
||||
}
|
||||
log(LOG_DEBUG,"Received directory hashes to %s",hex_str(digest,4));
|
||||
log_fn(LOG_DEBUG,"Received directory hashes to %s",hex_str(digest,4));
|
||||
|
||||
if ((end = strstr(str,"\nrouter "))) {
|
||||
++end;
|
||||
@@ -573,7 +573,6 @@ router_parse_list_from_string(const char **s, routerlist_t **dest,
|
||||
{
|
||||
routerinfo_t *router;
|
||||
smartlist_t *routers;
|
||||
int rarray_len = 0;
|
||||
const char *end;
|
||||
|
||||
tor_assert(s && *s);
|
||||
@@ -609,7 +608,7 @@ router_parse_list_from_string(const char **s, routerlist_t **dest,
|
||||
router->status_set_at = time(NULL);
|
||||
}
|
||||
smartlist_add(routers, router);
|
||||
log_fn(LOG_DEBUG,"just added router #%d.",rarray_len);
|
||||
log_fn(LOG_DEBUG,"just added router #%d.",smartlist_len(routers));
|
||||
}
|
||||
|
||||
if (*dest)
|
||||
|
||||
Reference in New Issue
Block a user