]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Write automatically-chosen control ports to a file.
authorNick Mathewson <nickm@torproject.org>
Mon, 9 May 2011 16:13:37 +0000 (12:13 -0400)
committerNick Mathewson <nickm@torproject.org>
Fri, 13 May 2011 14:41:28 +0000 (10:41 -0400)
changes/feature3076
doc/tor.1.txt
src/or/config.c
src/or/connection.c
src/or/control.c
src/or/control.h
src/or/main.c
src/or/or.h

index aadd29627465aa29e818e6844456d984df89a4de..ed42e4595bbe614e622362092d43d951b8b940cf 100644 (file)
@@ -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.
+
index e48342e165d8374008e603524da8113cc45726bc..606580db55fe094fbfd7c3f3c1ee6ad19e983b46 100644 (file)
@@ -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)
 
index b06c8c95c36e10ff5963cfca4c3bdfeba7901dca..5eb62291bc5b83c068e4f534171059ee0821e69b 100644 (file)
@@ -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"),
index bc18dab1ec2363b2c149bce908159aa076fb59f9..01b533d9b5fd295ff5765404964241a5624a69e5 100644 (file)
@@ -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);
index 19e8539a201be8e7a8709988aca54fbc94bcd325..634674233c0826419fc079d761bbadbf64aabf48 100644 (file)
@@ -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)
index 2ae96b4b8a23ed357f52dc5d70252361987c8bcb..a73ed5d3c10eddac07e69af7e89ff5dba1ee35a3 100644 (file)
@@ -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:
  *
index 7bae59ce06bdb97edffa4b524b2e779bdfeb0ea2..15682d5400fbd27ec0e8e64cc1c0b8c6b8573457 100644 (file)
@@ -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. */
index 0a089f774efcfe113a1a329624a0c5ca6644ea9e..412aac98221f9ffae0c1e84655f86994f6738b35 100644 (file)
@@ -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. */