diff options
-rw-r--r-- | changes/feature3076 | 3 | ||||
-rw-r--r-- | doc/tor.1.txt | 5 | ||||
-rw-r--r-- | src/or/config.c | 1 | ||||
-rw-r--r-- | src/or/connection.c | 3 | ||||
-rw-r--r-- | src/or/control.c | 39 | ||||
-rw-r--r-- | src/or/control.h | 2 | ||||
-rw-r--r-- | src/or/main.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 3 |
8 files changed, 60 insertions, 2 deletions
diff --git a/changes/feature3076 b/changes/feature3076 index aadd29627..ed42e4595 100644 --- a/changes/feature3076 +++ b/changes/feature3076 @@ -6,3 +6,6 @@ and ports that are bound for listeners for a given connection type. This is useful for if the user has selected SocksPort "auto", and you need to know which port got chosen. + - There is a ControlPortWriteToFile option that tells Tor to write + its actual control port or ports to a chosen file. + diff --git a/doc/tor.1.txt b/doc/tor.1.txt index e48342e16..606580db5 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -191,6 +191,11 @@ Other options can be specified either on the command-line (--option the default GID. [Making the file readable by other groups is not yet implemented; let us know if you need this for some reason.] (Default: 0). +**ControlPortWriteToFile** __Path__:: + If set, Tor writes the address and port of any control port it opens to + this address. Usable by controllers to learn the actual control port + when ControlPort is set to "auto". + **DataDirectory** __DIR__:: Store working data in DIR (Default: @LOCALSTATEDIR@/lib/tor) diff --git a/src/or/config.c b/src/or/config.c index b06c8c95c..5eb62291b 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -206,6 +206,7 @@ static config_var_t _option_vars[] = { V(ContactInfo, STRING, NULL), V(ControlListenAddress, LINELIST, NULL), V(ControlPort, PORT, "0"), + V(ControlPortWriteToFile, FILENAME, NULL), V(ControlSocket, LINELIST, NULL), V(CookieAuthentication, BOOL, "0"), V(CookieAuthFileGroupReadable, BOOL, "0"), diff --git a/src/or/connection.c b/src/or/connection.c index bc18dab1e..01b533d9b 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -998,6 +998,9 @@ connection_create_listener(const struct sockaddr *listensockaddr, "%s listening on port %u.", conn_type_to_string(type), gotPort); + if (type == CONN_TYPE_CONTROL_LISTENER) + control_ports_write_to_file(); + conn->state = LISTENER_STATE_READY; if (start_reading) { connection_start_reading(conn); diff --git a/src/or/control.c b/src/or/control.c index 19e8539a2..634674233 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -508,6 +508,45 @@ connection_printf_to_buf(control_connection_t *conn, const char *format, ...) connection_write_to_buf(buf, len, TO_CONN(conn)); } +/** Write all of the open control ports to ControlPortWriteToFile */ +void +control_ports_write_to_file(void) +{ + smartlist_t *lines; + char *joined = NULL; + or_options_t *options = get_options(); + + if (!options->ControlPortWriteToFile) + return; + + lines = smartlist_create(); + + SMARTLIST_FOREACH_BEGIN(get_connection_array(), const connection_t *, conn) { + char *port_str = NULL; + if (conn->type != CONN_TYPE_CONTROL_LISTENER || conn->marked_for_close) + continue; +#ifdef AF_UNIX + if (conn->socket_family == AF_UNIX) { + tor_asprintf(&port_str, "UNIX_PORT=%s\n", conn->address); + smartlist_add(lines, port_str); + continue; + } +#endif + tor_asprintf(&port_str, "PORT=%s:%d\n", conn->address, conn->port); + smartlist_add(lines, port_str); + } SMARTLIST_FOREACH_END(conn); + + joined = smartlist_join_strings(lines, "", 0, NULL); + + if (write_str_to_file(options->ControlPortWriteToFile, joined, 0) < 0) { + log_warn(LD_CONTROL, "Writing %s failed: %s", + options->ControlPortWriteToFile, strerror(errno)); + } + tor_free(joined); + SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp)); + smartlist_free(lines); +} + /** Send a "DONE" message down the control connection <b>conn</b>. */ static void send_control_done(control_connection_t *conn) diff --git a/src/or/control.h b/src/or/control.h index 2ae96b4b8..a73ed5d3c 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -15,6 +15,8 @@ void control_update_global_event_mask(void); void control_adjust_event_log_severity(void); +void control_ports_write_to_file(void); + /** Log information about the connection <b>conn</b>, protecting it as with * CONN_LOG_PROTECT. Example: * diff --git a/src/or/main.c b/src/or/main.c index 7bae59ce0..15682d540 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2046,12 +2046,14 @@ void tor_cleanup(void) { or_options_t *options = get_options(); - /* Remove our pid file. We don't care if there was an error when we - * unlink, nothing we could do about it anyways. */ if (options->command == CMD_RUN_TOR) { time_t now = time(NULL); + /* Remove our pid file. We don't care if there was an error when we + * unlink, nothing we could do about it anyways. */ if (options->PidFile) unlink(options->PidFile); + if (options->ControlPortWriteToFile) + unlink(options->ControlPortWriteToFile); if (accounting_is_enabled(options)) accounting_record_bandwidth_usage(now, get_or_state()); or_state_mark_dirty(get_or_state(), 0); /* force an immediate save. */ diff --git a/src/or/or.h b/src/or/or.h index 0a089f774..412aac982 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2874,6 +2874,9 @@ typedef struct { * the defaults have changed. */ int _UsingTestNetworkDefaults; + /** File where we should write the ControlPort. */ + char *ControlPortWriteToFile; + } or_options_t; /** Persistent state for an onion router, as saved to disk. */ |