diff options
author | Roger Dingledine <arma@torproject.org> | 2004-11-15 09:05:54 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-11-15 09:05:54 +0000 |
commit | 4b76fe8036b700d5101b356273d21af7ecc33f8b (patch) | |
tree | c0aadb885753cf23473ba50e537d7bd6272c1d7e /src/or | |
parent | 67aa3b66c520183f7b195f9cdc63ffa19670688e (diff) | |
download | tor-4b76fe8036b700d5101b356273d21af7ecc33f8b.tar tor-4b76fe8036b700d5101b356273d21af7ecc33f8b.tar.gz |
Break DirFetchPostPeriod into:
- DirFetchPeriod for fetching full directory,
- StatusFetchPeriod for fetching running-routers,
- DirPostPeriod for posting server descriptor,
- RendPostPeriod for posting hidden service descriptors.
Also make sure the hidden service descriptors are at a random
offset from each other, to hinder linkability.
svn:r2889
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 28 | ||||
-rw-r--r-- | src/or/main.c | 57 | ||||
-rw-r--r-- | src/or/or.h | 11 | ||||
-rw-r--r-- | src/or/rendservice.c | 34 |
4 files changed, 78 insertions, 52 deletions
diff --git a/src/or/config.c b/src/or/config.c index 5961acd10..cf22ad1f0 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -57,6 +57,7 @@ static config_abbrev_t config_abbrevs[] = { { "l", "Log", 1}, { "BandwidthRate", "BandwidthRateBytes", 0}, { "BandwidthBurst", "BandwidthBurstBytes", 0}, + { "DirFetchPostPeriod", "DirFetchPeriod", 0}, { NULL, NULL , 0}, }; #undef PLURAL @@ -98,7 +99,9 @@ static config_var_t config_vars[] = { VAR("DataDirectory", STRING, DataDirectory, NULL), VAR("DirPort", UINT, DirPort, "0"), VAR("DirBindAddress", LINELIST, DirBindAddress, NULL), - VAR("DirFetchPostPeriod", UINT, DirFetchPostPeriod, "600"), + VAR("DirFetchPeriod", UINT, DirFetchPeriod, "3600"), + VAR("DirPostPeriod", UINT, DirPostPeriod, "600"), + VAR("RendPostPeriod", UINT, RendPostPeriod, "600"), VAR("DirPolicy", LINELIST, DirPolicy, NULL), VAR("DirServer", LINELIST, DirServers, NULL), VAR("ExitNodes", STRING, ExitNodes, NULL), @@ -147,6 +150,7 @@ static config_var_t config_vars[] = { VAR("SocksPort", UINT, SocksPort, "9050"), VAR("SocksBindAddress", LINELIST, SocksBindAddress, NULL), VAR("SocksPolicy", LINELIST, SocksPolicy, NULL), + VAR("StatusFetchPeriod", UINT, StatusFetchPeriod, "1200"), VAR("SysLog", LINELIST_S, OldLogOptions, NULL), OBSOLETE("TrafficShaping"), VAR("User", STRING, User, NULL), @@ -1227,13 +1231,25 @@ options_validate(or_options_t *options) } #define MIN_DIRFETCHPOSTPERIOD 60 - if (options->DirFetchPostPeriod < MIN_DIRFETCHPOSTPERIOD) { - log(LOG_WARN, "DirFetchPostPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD); + if (options->DirFetchPeriod < MIN_DIRFETCHPOSTPERIOD) { + log(LOG_WARN, "DirFetchPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD); result = -1; } - if (options->DirFetchPostPeriod > MIN_ONION_KEY_LIFETIME / 2) { - log(LOG_WARN, "DirFetchPostPeriod is too large; clipping."); - options->DirFetchPostPeriod = MIN_ONION_KEY_LIFETIME / 2; + if (options->StatusFetchPeriod < MIN_DIRFETCHPOSTPERIOD) { + log(LOG_WARN, "StatusFetchPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD); + result = -1; + } + if (options->DirPostPeriod < MIN_DIRFETCHPOSTPERIOD) { + log(LOG_WARN, "DirPostPeriod option must be at least %d.", MIN_DIRFETCHPOSTPERIOD); + result = -1; + } + if (options->DirFetchPeriod > MIN_ONION_KEY_LIFETIME / 2) { + log(LOG_WARN, "DirFetchPeriod is too large; clipping."); + options->DirFetchPeriod = MIN_ONION_KEY_LIFETIME / 2; + } + if (options->DirPostPeriod > MIN_ONION_KEY_LIFETIME / 2) { + log(LOG_WARN, "DirPostPeriod is too large; clipping."); + options->DirPostPeriod = MIN_ONION_KEY_LIFETIME / 2; } if (options->KeepalivePeriod < 1) { diff --git a/src/or/main.c b/src/or/main.c index ab3849c73..c3de91c88 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -33,6 +33,10 @@ static uint64_t stats_n_bytes_written = 0; long stats_n_seconds_uptime = 0; /** When do we next download a directory? */ static time_t time_to_fetch_directory = 0; +/** When do we next upload our descriptor? */ +static time_t time_to_force_upload_descriptor = 0; +/** When do we next download a running-routers summary? */ +static time_t time_to_fetch_running_routers = 0; /** Array of all open connections; each element corresponds to the element of * poll_array in the same position. The first nfds elements are valid. */ @@ -372,12 +376,17 @@ void directory_has_arrived(time_t now) { log_fn(LOG_INFO, "A directory has arrived."); has_fetched_directory=1; - /* Don't try to upload or download anything for DirFetchPostPeriod - * seconds after the directory we had when we started. + /* Don't try to upload or download anything for a while + * after the directory we had when we started. */ if (!time_to_fetch_directory) - /*XXX *5 is unreasonable. We should have separate options for these cases.*/ - time_to_fetch_directory = now + options->DirFetchPostPeriod*5; + time_to_fetch_directory = now + options->DirFetchPeriod; + + if(!time_to_force_upload_descriptor) + time_to_force_upload_descriptor = now + options->DirPostPeriod; + + if(!time_to_fetch_running_routers) + time_to_fetch_running_routers = now + options->StatusFetchPeriod; if (server_mode(options) && !we_are_hibernating()) { /* connect to the appropriate routers */ @@ -509,12 +518,9 @@ int proxy_mode(or_options_t *options) { * second by prepare_for_poll. */ static void run_scheduled_events(time_t now) { - static time_t last_uploaded_services = 0; static time_t last_rotated_certificate = 0; static time_t time_to_check_listeners = 0; static time_t time_to_check_descriptor = 0; - static time_t time_to_force_upload_descriptor = 0; - static time_t time_to_fetch_running_routers = 0; or_options_t *options = get_options(); int i; @@ -559,9 +565,9 @@ static void run_scheduled_events(time_t now) { if (accounting_is_enabled(options)) accounting_run_housekeeping(now); - /** 2. Every DirFetchPostPeriod seconds, we get a new directory and - * force-upload our descriptor (if we've passed our internal - * checks). */ + /** 2. Periodically, we consider getting a new directory, getting a + * new running-routers list, and/or force-uploading our descriptor + * (if we've passed our internal checks). */ if(time_to_fetch_directory < now) { /* purge obsolete entries */ routerlist_remove_old_routers(ROUTER_MAX_AGE); @@ -577,21 +583,20 @@ static void run_scheduled_events(time_t now) { } directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL); - /*XXX *5 is unreasonable. We should have separate options for these cases.*/ - time_to_fetch_directory = now + options->DirFetchPostPeriod*5; - time_to_fetch_running_routers = now + options->DirFetchPostPeriod; + time_to_fetch_directory = now + options->DirFetchPeriod; + if (time_to_fetch_running_routers < now + options->StatusFetchPeriod) { + time_to_fetch_running_routers = now + options->StatusFetchPeriod; + } } if (time_to_fetch_running_routers < now) { if (!authdir_mode(options)) { directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, NULL); } - time_to_fetch_running_routers = now + options->DirFetchPostPeriod; + time_to_fetch_running_routers = now + options->StatusFetchPeriod; } if (time_to_force_upload_descriptor < now) { - /*XXX Separate option for this, too. */ - time_to_force_upload_descriptor = now + options->DirFetchPostPeriod; if(decide_if_publishable_server(now)) { server_is_advertised = 1; router_rebuild_descriptor(1); @@ -600,14 +605,9 @@ static void run_scheduled_events(time_t now) { server_is_advertised = 0; } - if(!we_are_hibernating()) { - /* Force an upload of our rend descriptors every DirFetchPostPeriod seconds. */ - rend_services_upload(1); - last_uploaded_services = now; - } rend_cache_clean(); /* this should go elsewhere? */ - time_to_force_upload_descriptor = now + options->DirFetchPostPeriod; + time_to_force_upload_descriptor = now + options->DirPostPeriod; } /* 2b. Once per minute, regenerate and upload the descriptor if the old @@ -625,14 +625,14 @@ static void run_scheduled_events(time_t now) { /** 3a. Every second, we examine pending circuits and prune the * ones which have been pending for more than a few seconds. - * We do this before step 3, so it can try building more if + * We do this before step 4, so it can try building more if * it's not comfortable with the number of available circuits. */ circuit_expire_building(now); /** 3b. Also look at pending streams and prune the ones that 'began' * a long time ago but haven't gotten a 'connected' yet. - * Do this before step 3, so we can put them back into pending + * Do this before step 4, so we can put them back into pending * state to be picked up by the new circuit. */ connection_ap_expire_beginning(); @@ -663,12 +663,9 @@ static void run_scheduled_events(time_t now) { /** 6. And remove any marked circuits... */ circuit_close_all_marked(); - /** 7. And upload service descriptors for any services whose intro points - * have changed in the last second. */ - if (last_uploaded_services < now-5) { - rend_services_upload(0); - last_uploaded_services = now; - } + /** 7. And upload service descriptors if necessary. */ + if(!we_are_hibernating()) + rend_consider_services_upload(now); /** 8. and blow away any connections that need to die. have to do this now, * because if we marked a conn for close and left its socket -1, then diff --git a/src/or/or.h b/src/or/or.h index 8ce9e901c..223ea4a84 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -924,9 +924,12 @@ typedef struct { int RunAsDaemon; /**< If true, run in the background. (Unix only) */ int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */ smartlist_t *FirewallPorts; /** Which ports our firewall allows. */ - int DirFetchPostPeriod; /**< How often do we fetch new directories - * and post server descriptros to the directory - * server? */ + int DirFetchPeriod; /**< How often do we fetch new directories? */ + int DirPostPeriod; /**< How often do we post our server descriptor to the + * authoritative directory servers? */ + int RendPostPeriod; /**< How often do we post each rendezvous service + * descriptor? Remember to publish them independently. */ + int StatusFetchPeriod; /**< How often do we fetch running-routers lists? */ int KeepalivePeriod; /**< How often do we send padding cells to keep * connections alive? */ int MaxOnionsPending; /**< How many circuit CREATE requests do we allow @@ -1480,7 +1483,7 @@ int rend_config_services(or_options_t *options, int validate_only); int rend_service_load_keys(void); void rend_services_init(void); void rend_services_introduce(void); -void rend_services_upload(int force); +void rend_consider_services_upload(time_t now); void rend_service_intro_has_opened(circuit_t *circuit); int rend_service_intro_established(circuit_t *circuit, const char *request, size_t request_len); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 3bc1238d3..a38b53660 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -50,6 +50,7 @@ typedef struct rend_service_t { * established in this period. */ rend_service_descriptor_t *desc; int desc_is_dirty; + time_t next_upload_time; } rend_service_t; /** A list of rend_service_t's for services run on this OP. @@ -759,8 +760,7 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest) return NULL; } -/** If the directory servers don't have an up-to-date descriptor for - * <b>service</b>, encode and sign the service descriptor for <b>service</b>, +/** Encode and sign an up-to-date service descriptor for <b>service</b>, * and upload it to all the dirservers. */ static void @@ -768,8 +768,6 @@ upload_service_descriptor(rend_service_t *service) { char *desc; size_t desc_len; - if (!service->desc_is_dirty) - return; /* Update the descriptor. */ rend_service_update_descriptor(service); @@ -893,22 +891,34 @@ void rend_services_introduce(void) { } /** Regenerate and upload rendezvous service descriptors for all - * services. If <b>force</b> is false, skip services where we've already - * uploaded an up-to-date copy; if <b>force</b> is true, regenerate and - * upload everything. + * services, if necessary. If the descriptor has been dirty enough + * for long enough, definitely upload; else only upload when the + * periodic timeout has expired. + * + * For the first upload, pick a random time between now and two periods + * from now, and pick it independently for each service. */ void -rend_services_upload(int force) -{ +rend_consider_services_upload(time_t now) { int i; rend_service_t *service; + int rendpostperiod = get_options()->RendPostPeriod; for (i=0; i< smartlist_len(rend_service_list); ++i) { service = smartlist_get(rend_service_list, i); - if (force) - service->desc_is_dirty = 1; - if (service->desc_is_dirty) + if (!service->next_upload_time) { /* never been uploaded yet */ + service->next_upload_time = + now + crypto_pseudo_rand_int(2*rendpostperiod); + } + if (service->next_upload_time < now || + (service->desc_is_dirty && + service->next_upload_time < now-5)) { + /* if it's time, or if the directory servers have a wrong service + * descriptor and this has been the case for 5 seconds, upload a + * new one. */ upload_service_descriptor(service); + service->next_upload_time = now + rendpostperiod; + } } } |