diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 2fba046c38..a1aa3d716e 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -331,17 +331,9 @@ circuit_predict_and_launch_new(void) int num=0, num_internal=0, num_uptime_internal=0; int hidserv_needs_uptime=0, hidserv_needs_capacity=1; int port_needs_uptime=0, port_needs_capacity=1; - int need_ports, need_hidserv; time_t now = time(NULL); - /* check if we know of a port that's been requested recently - * and no circuit is currently available that can handle it. */ - need_ports = !circuit_all_predicted_ports_handled(now, &port_needs_uptime, - &port_needs_capacity); - - need_hidserv = rep_hist_get_predicted_hidserv(now, &hidserv_needs_uptime, - &hidserv_needs_capacity); - + /* First, count how many of each type of circuit we have already. */ for (circ=global_circuitlist;circ;circ = circ->next) { if (!CIRCUIT_IS_ORIGIN(circ)) continue; @@ -358,21 +350,41 @@ circuit_predict_and_launch_new(void) num_uptime_internal++; } - if (num < MAX_UNUSED_OPEN_CIRCUITS) { - /* perhaps we want another */ - if (need_ports) { - log_fn(LOG_INFO,"Have %d clean circs (%d internal), need another exit circ.", - num, num_internal); - circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, - port_needs_uptime, port_needs_capacity, 0); - } else if (need_hidserv && - ((num_uptime_internal<2 && hidserv_needs_uptime) || - num_internal<2)) { - log_fn(LOG_INFO,"Have %d clean circs (%d uptime-internal, %d internal)," - " need another hidserv circ.", num, num_uptime_internal, num_internal); - circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, - hidserv_needs_uptime, hidserv_needs_capacity, 1); - } + /* If that's enough, then stop now. */ + if (num >= MAX_UNUSED_OPEN_CIRCUITS) + return; /* we already have many, making more probably will hurt */ + + /* Second, see if we need any more exit circuits. */ + /* check if we know of a port that's been requested recently + * and no circuit is currently available that can handle it. */ + if (!circuit_all_predicted_ports_handled(now, &port_needs_uptime, + &port_needs_capacity)) { + log_fn(LOG_INFO,"Have %d clean circs (%d internal), need another exit circ.", + num, num_internal); + circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, + port_needs_uptime, port_needs_capacity, 0); + return; + } + + /* Third, see if we need any more hidden service (server) circuits. */ + if (num_rend_services() && num_uptime_internal < 3) { + log_fn(LOG_INFO,"Have %d clean circs (%d internal), need another internal circ for my hidden service.", + num, num_internal); + circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, + 1, 1, 1); + return; + } + + /* Fourth, see if we need any more hidden service (client) circuits. */ + if (rep_hist_get_predicted_hidserv(now, &hidserv_needs_uptime, + &hidserv_needs_capacity) && + ((num_uptime_internal<2 && hidserv_needs_uptime) || + num_internal<2)) { + log_fn(LOG_INFO,"Have %d clean circs (%d uptime-internal, %d internal)," + " need another hidserv circ.", num, num_uptime_internal, num_internal); + circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, + hidserv_needs_uptime, hidserv_needs_capacity, 1); + return; } } diff --git a/src/or/dns.c b/src/or/dns.c index 91ba74d094..db54054ffb 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -904,7 +904,7 @@ spawn_enough_dnsworkers(void) while (num_dnsworkers < num_dnsworkers_needed) { if (spawn_dnsworker() < 0) { - log(LOG_WARN,"spawn_enough_dnsworkers(): spawn failed!"); + log_fn(LOG_WARN,"spawn failed!"); return; } num_dnsworkers++; diff --git a/src/or/or.h b/src/or/or.h index 53c2cd042a..8844d37170 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1846,6 +1846,7 @@ int rend_cache_store(const char *desc, size_t desc_len); /********************************* rendservice.c ***************************/ +int num_rend_services(void); int rend_config_services(or_options_t *options, int validate_only); int rend_service_load_keys(void); void rend_services_init(void); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 2ed1584e02..5511f46ab8 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -61,6 +61,13 @@ typedef struct rend_service_t { */ static smartlist_t *rend_service_list = NULL; +/** Return the number of rendezvous services we have configured. */ +int num_rend_services(void) { + if (!rend_service_list) + return 0; + return smartlist_len(rend_service_list); +} + /** Release the storage held by service. */ static void diff --git a/src/or/rephist.c b/src/or/rephist.c index f208bf95f6..e561675b98 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -748,8 +748,11 @@ rep_hist_note_used_hidserv(time_t now, int need_uptime, int need_capacity) int rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capacity) { - if (!predicted_hidserv_time) /* initialize it */ + if (!predicted_hidserv_time) { /* initialize it */ predicted_hidserv_time = now; + predicted_hidserv_uptime_time = now; + predicted_hidserv_capacity_time = now; + } if (predicted_hidserv_time + PREDICTED_CIRCS_RELEVANCE_TIME < now) return 0; /* too long ago */ if (predicted_hidserv_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)