mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 15:23:27 +01:00
implement first piece of hibernation
still need to track bandwidth, and make decisions based on bandwidth svn:r2630
This commit is contained in:
parent
ae7495dd55
commit
984ffec105
@ -7,7 +7,7 @@ bin_PROGRAMS = tor
|
|||||||
tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
|
tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
|
||||||
circuituse.c command.c config.c \
|
circuituse.c command.c config.c \
|
||||||
connection.c connection_edge.c connection_or.c \
|
connection.c connection_edge.c connection_or.c \
|
||||||
cpuworker.c directory.c dirserv.c dns.c main.c \
|
cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \
|
||||||
onion.c relay.c rendcommon.c rendclient.c rendmid.c \
|
onion.c relay.c rendcommon.c rendclient.c rendmid.c \
|
||||||
rendservice.c rephist.c router.c routerlist.c routerparse.c \
|
rendservice.c rephist.c router.c routerlist.c routerparse.c \
|
||||||
tor_main.c
|
tor_main.c
|
||||||
@ -17,7 +17,7 @@ tor_LDADD = ../common/libor.a ../common/libor-crypto.a -lz -lssl -lcrypto
|
|||||||
test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
|
test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
|
||||||
circuituse.c command.c config.c \
|
circuituse.c command.c config.c \
|
||||||
connection.c connection_edge.c connection_or.c \
|
connection.c connection_edge.c connection_or.c \
|
||||||
cpuworker.c directory.c dirserv.c dns.c main.c \
|
cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \
|
||||||
onion.c relay.c rendcommon.c rendclient.c rendmid.c \
|
onion.c relay.c rendcommon.c rendclient.c rendmid.c \
|
||||||
rendservice.c rephist.c router.c routerlist.c routerparse.c \
|
rendservice.c rephist.c router.c routerlist.c routerparse.c \
|
||||||
test.c
|
test.c
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "or.h"
|
#include "or.h"
|
||||||
|
|
||||||
extern or_options_t options; /* command-line and config-file options */
|
extern or_options_t options; /* command-line and config-file options */
|
||||||
extern int shutting_down; /* whether we should refuse create cells */
|
|
||||||
|
|
||||||
/** Keep statistics about how many of each type of cell we've received. */
|
/** Keep statistics about how many of each type of cell we've received. */
|
||||||
unsigned long stats_n_padding_cells_processed = 0;
|
unsigned long stats_n_padding_cells_processed = 0;
|
||||||
@ -127,7 +126,7 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
|
|||||||
static void command_process_create_cell(cell_t *cell, connection_t *conn) {
|
static void command_process_create_cell(cell_t *cell, connection_t *conn) {
|
||||||
circuit_t *circ;
|
circuit_t *circ;
|
||||||
|
|
||||||
if(shutting_down) {
|
if(we_are_hibernating()) {
|
||||||
log_fn(LOG_INFO,"Received create cell but we're shutting down. Sending back destroy.");
|
log_fn(LOG_INFO,"Received create cell but we're shutting down. Sending back destroy.");
|
||||||
connection_send_destroy(cell->circ_id, conn);
|
connection_send_destroy(cell->circ_id, conn);
|
||||||
return;
|
return;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
/********* START VARIABLES **********/
|
/********* START VARIABLES **********/
|
||||||
|
|
||||||
extern or_options_t options; /* command-line and config-file options */
|
extern or_options_t options; /* command-line and config-file options */
|
||||||
extern int shutting_down; /* whether we should refuse new connections */
|
|
||||||
|
|
||||||
/** Array of strings to make conn-\>type human-readable. */
|
/** Array of strings to make conn-\>type human-readable. */
|
||||||
const char *conn_type_to_string[] = {
|
const char *conn_type_to_string[] = {
|
||||||
@ -401,13 +400,6 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
|
|||||||
}
|
}
|
||||||
log(LOG_INFO,"Connection accepted on socket %d (child of fd %d).",news, conn->s);
|
log(LOG_INFO,"Connection accepted on socket %d (child of fd %d).",news, conn->s);
|
||||||
|
|
||||||
if(shutting_down && new_type != CONN_TYPE_DIR) {
|
|
||||||
/* allow directory connections even while we're shutting down */
|
|
||||||
log(LOG_INFO,"But we're shutting down, so closing (type %d).", new_type);
|
|
||||||
tor_close_socket(news);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_socket_nonblocking(news);
|
set_socket_nonblocking(news);
|
||||||
|
|
||||||
/* process entrance policies here, before we even create the connection */
|
/* process entrance policies here, before we even create the connection */
|
||||||
|
@ -804,6 +804,11 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
|
|||||||
n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
|
n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
|
||||||
/* default to failed, change in dns_resolve if it turns out not to fail */
|
/* default to failed, change in dns_resolve if it turns out not to fail */
|
||||||
|
|
||||||
|
if(we_are_hibernating()) {
|
||||||
|
connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer);
|
||||||
|
connection_free(n_stream);
|
||||||
|
}
|
||||||
|
|
||||||
/* send it off to the gethostbyname farm */
|
/* send it off to the gethostbyname farm */
|
||||||
switch(dns_resolve(n_stream)) {
|
switch(dns_resolve(n_stream)) {
|
||||||
case 1: /* resolve worked */
|
case 1: /* resolve worked */
|
||||||
|
@ -53,13 +53,6 @@ static int please_sigpipe=0; /**< Whether we've caught a sigpipe lately. */
|
|||||||
static int please_shutdown=0; /**< Whether we should shut down Tor. */
|
static int please_shutdown=0; /**< Whether we should shut down Tor. */
|
||||||
#endif /* signal stuff */
|
#endif /* signal stuff */
|
||||||
|
|
||||||
/** We should exit if shutting_down != 0 and now <= shutting_down.
|
|
||||||
* If it's non-zero, don't accept any new circuits or connections.
|
|
||||||
* This gets assigned when we receive a sig_int, and if we receive a
|
|
||||||
* second one we exit immediately. */
|
|
||||||
int shutting_down=0;
|
|
||||||
#define SHUTDOWN_WAIT_LENGTH 30 /* seconds */
|
|
||||||
|
|
||||||
/** We set this to 1 when we've fetched a dir, to know whether to complain
|
/** We set this to 1 when we've fetched a dir, to know whether to complain
|
||||||
* yet about unrecognized nicknames in entrynodes, exitnodes, etc.
|
* yet about unrecognized nicknames in entrynodes, exitnodes, etc.
|
||||||
* Also, we don't try building circuits unless this is 1. */
|
* Also, we don't try building circuits unless this is 1. */
|
||||||
@ -373,7 +366,8 @@ void directory_has_arrived(time_t now) {
|
|||||||
if (!time_to_fetch_directory)
|
if (!time_to_fetch_directory)
|
||||||
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
||||||
|
|
||||||
if(server_mode()) { /* connect to the appropriate routers */
|
if (server_mode() &&
|
||||||
|
!we_are_hibernating()) { /* connect to the appropriate routers */
|
||||||
router_retry_connections();
|
router_retry_connections();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,9 +394,10 @@ static void run_connection_housekeeping(int i, time_t now) {
|
|||||||
now >= conn->timestamp_lastwritten + options.KeepalivePeriod) {
|
now >= conn->timestamp_lastwritten + options.KeepalivePeriod) {
|
||||||
routerinfo_t *router = router_get_by_digest(conn->identity_digest);
|
routerinfo_t *router = router_get_by_digest(conn->identity_digest);
|
||||||
if((!connection_state_is_open(conn)) ||
|
if((!connection_state_is_open(conn)) ||
|
||||||
|
(we_are_hibernating() && !circuit_get_by_conn(conn)) ||
|
||||||
(!clique_mode() && !circuit_get_by_conn(conn) &&
|
(!clique_mode() && !circuit_get_by_conn(conn) &&
|
||||||
(!router || !server_mode() || !router_is_clique_mode(router)))) {
|
(!router || !server_mode() || !router_is_clique_mode(router)))) {
|
||||||
/* our handshake has expired;
|
/* our handshake has expired; we're hibernating;
|
||||||
* or we have no circuits and we're both either OPs or normal ORs,
|
* or we have no circuits and we're both either OPs or normal ORs,
|
||||||
* then kill it. */
|
* then kill it. */
|
||||||
log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).",
|
log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).",
|
||||||
@ -510,13 +505,10 @@ static void run_scheduled_events(time_t now) {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/** 0. See if we've been asked to shut down and our timeout has
|
/** 0. See if we've been asked to shut down and our timeout has
|
||||||
* expired. If so, exit now.
|
* expired; or if our bandwidth limits are exhausted and we
|
||||||
|
* should hibernate; or if it's time to wake up from hibernation.
|
||||||
*/
|
*/
|
||||||
if(shutting_down && shutting_down <= now) {
|
consider_hibernation(now);
|
||||||
log(LOG_NOTICE,"Clean shutdown finished. Exiting.");
|
|
||||||
tor_cleanup();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
|
/** 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
|
||||||
* shut down and restart all cpuworkers, and update the directory if
|
* shut down and restart all cpuworkers, and update the directory if
|
||||||
@ -566,7 +558,7 @@ static void run_scheduled_events(time_t now) {
|
|||||||
/* We're a directory; dump any old descriptors. */
|
/* We're a directory; dump any old descriptors. */
|
||||||
dirserv_remove_old_servers(ROUTER_MAX_AGE);
|
dirserv_remove_old_servers(ROUTER_MAX_AGE);
|
||||||
}
|
}
|
||||||
if(server_mode()) {
|
if(server_mode() && !we_are_hibernating()) {
|
||||||
/* dirservers try to reconnect, in case connections have failed;
|
/* dirservers try to reconnect, in case connections have failed;
|
||||||
* and normal servers try to reconnect to dirservers */
|
* and normal servers try to reconnect to dirservers */
|
||||||
router_retry_connections();
|
router_retry_connections();
|
||||||
@ -574,9 +566,11 @@ static void run_scheduled_events(time_t now) {
|
|||||||
|
|
||||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 0);
|
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 0);
|
||||||
|
|
||||||
/* Force an upload of our rend descriptors every DirFetchPostPeriod seconds. */
|
if(!we_are_hibernating()) {
|
||||||
rend_services_upload(1);
|
/* Force an upload of our rend descriptors every DirFetchPostPeriod seconds. */
|
||||||
last_uploaded_services = now;
|
rend_services_upload(1);
|
||||||
|
last_uploaded_services = now;
|
||||||
|
}
|
||||||
rend_cache_clean(); /* should this go elsewhere? */
|
rend_cache_clean(); /* should this go elsewhere? */
|
||||||
|
|
||||||
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
time_to_fetch_directory = now + options.DirFetchPostPeriod;
|
||||||
@ -601,8 +595,8 @@ static void run_scheduled_events(time_t now) {
|
|||||||
*/
|
*/
|
||||||
connection_expire_held_open();
|
connection_expire_held_open();
|
||||||
|
|
||||||
/** 3d. And every 60 secionds, we relaunch listeners if any died. */
|
/** 3d. And every 60 seconds, we relaunch listeners if any died. */
|
||||||
if (time_to_check_listeners < now) {
|
if (!we_are_hibernating() && time_to_check_listeners < now) {
|
||||||
retry_all_listeners(0); /* 0 means "only if some died." */
|
retry_all_listeners(0); /* 0 means "only if some died." */
|
||||||
time_to_check_listeners = now+60;
|
time_to_check_listeners = now+60;
|
||||||
}
|
}
|
||||||
@ -612,7 +606,7 @@ static void run_scheduled_events(time_t now) {
|
|||||||
* that became dirty more than NewCircuitPeriod seconds ago,
|
* that became dirty more than NewCircuitPeriod seconds ago,
|
||||||
* and we make a new circ if there are no clean circuits.
|
* and we make a new circ if there are no clean circuits.
|
||||||
*/
|
*/
|
||||||
if(has_fetched_directory)
|
if(has_fetched_directory && !we_are_hibernating())
|
||||||
circuit_build_needed_circs(now);
|
circuit_build_needed_circs(now);
|
||||||
|
|
||||||
/** 5. We do housekeeping for each connection... */
|
/** 5. We do housekeeping for each connection... */
|
||||||
@ -842,14 +836,7 @@ static int do_main_loop(void) {
|
|||||||
tor_cleanup();
|
tor_cleanup();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if(shutting_down) { /* we've already been asked. do it now. */
|
hibernate_begin_shutdown();
|
||||||
log(LOG_NOTICE,"Second sigint received; exiting now.");
|
|
||||||
tor_cleanup();
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
log(LOG_NOTICE,"Interrupt: will shut down in %d seconds. Interrupt again to exit now.", SHUTDOWN_WAIT_LENGTH);
|
|
||||||
shutting_down = time(NULL) + SHUTDOWN_WAIT_LENGTH;
|
|
||||||
}
|
|
||||||
please_shutdown = 0;
|
please_shutdown = 0;
|
||||||
}
|
}
|
||||||
if(please_sigpipe) {
|
if(please_sigpipe) {
|
||||||
|
@ -1236,6 +1236,12 @@ void assert_all_pending_dns_resolves_ok(void);
|
|||||||
void dns_cancel_pending_resolve(char *question);
|
void dns_cancel_pending_resolve(char *question);
|
||||||
int dns_resolve(connection_t *exitconn);
|
int dns_resolve(connection_t *exitconn);
|
||||||
|
|
||||||
|
/********************************* hibernate.c **********************/
|
||||||
|
|
||||||
|
void hibernate_begin_shutdown(void);
|
||||||
|
int we_are_hibernating(void);
|
||||||
|
void consider_hibernation(time_t now);
|
||||||
|
|
||||||
/********************************* main.c ***************************/
|
/********************************* main.c ***************************/
|
||||||
|
|
||||||
int connection_add(connection_t *conn);
|
int connection_add(connection_t *conn);
|
||||||
|
Loading…
Reference in New Issue
Block a user