commit bb860cedb29be0d95740bcf50577ae96bf666a18 Author: Robert Ransom rransom.8774@gmail.com Date: Thu May 19 16:34:40 2011 -0700
Implement TAKEOWNERSHIP command --- src/or/control.c | 44 +++++++++++++++++++++++++++++++++++++++++++- src/or/or.h | 3 +++ 2 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/src/or/control.c b/src/or/control.c index 0ddbee9..b6f802d 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1230,6 +1230,26 @@ handle_control_signal(control_connection_t *conn, uint32_t len, return 0; }
+/** Called when we get a TAKEOWNERSHIP command. Mark this connection + * as an owning connection, so that we will exit if the connection + * closes. */ +static int +handle_control_takeownership(control_connection_t *conn, uint32_t len, + const char *body) +{ + (void)len; + (void)body; + + conn->is_owning_control_connection = 1; + + log_info(LD_CONTROL, "Control connection %d has taken ownership of this " + "Tor instance.", + (int)(conn->_base.s)); + + send_control_done(conn); + return 0; +} + /** Called when we get a MAPADDRESS command; try to bind all listed addresses, * and report success or failure. */ static int @@ -2747,6 +2767,25 @@ connection_control_closed(control_connection_t *conn)
conn->event_mask = 0; control_update_global_event_mask(); + + if (conn->is_owning_control_connection) { + int shutdown_slowly = server_mode(get_options()); + + log_notice(LD_CONTROL, "Owning controller connection has closed -- %s.", + shutdown_slowly ? "shutting down" : "exiting now"); + + /* XXXX This chunk of code should be a separate function, called + * here, in owning_controller_procmon_cb, and by + * process_signal(SIGINT). */ + + if (!shutdown_slowly) { + tor_cleanup(); + exit(0); + } + /* XXXX This will close all listening sockets except control-port + * listeners. Perhaps we should close those too. */ + hibernate_begin_shutdown(); + } }
/** Return true iff <b>cmd</b> is allowable (or at least forgivable) at this @@ -2932,6 +2971,9 @@ connection_control_process_inbuf(control_connection_t *conn) } else if (!strcasecmp(conn->incoming_cmd, "SIGNAL")) { if (handle_control_signal(conn, cmd_data_len, args)) return -1; + } else if (!strcasecmp(conn->incoming_cmd, "TAKEOWNERSHIP")) { + if (handle_control_takeownership(conn, cmd_data_len, args)) + return -1; } else if (!strcasecmp(conn->incoming_cmd, "MAPADDRESS")) { if (handle_control_mapaddress(conn, cmd_data_len, args)) return -1; @@ -3816,7 +3858,7 @@ owning_controller_procmon_cb(void *unused) shutdown_slowly ? "shutting down" : "exiting now");
/* XXXX This chunk of code should be a separate function, called - * here and by process_signal(SIGINT). */ + * here, in connection_control_closed, and by process_signal(SIGINT). */
if (!shutdown_slowly) { tor_cleanup(); diff --git a/src/or/or.h b/src/or/or.h index 52da63a..cbfe362 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1242,6 +1242,9 @@ typedef struct control_connection_t {
/** True if we have sent a protocolinfo reply on this connection. */ unsigned int have_sent_protocolinfo:1; + /** True if we have received a takeownership command on this + * connection. */ + unsigned int is_owning_control_connection:1;
/** Amount of space allocated in incoming_cmd. */ uint32_t incoming_cmd_len;