aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-05-02 16:44:37 -0400
committerNick Mathewson <nickm@torproject.org>2011-05-13 10:41:19 -0400
commitc55c8f0d4926481ea2cf49e14915688de2eb4938 (patch)
tree82ad60b9c7d681d141f9a4225067b818be2ca274
parent28cc7b01800e3e2a46a995b2ca18b0d2d5cdc804 (diff)
downloadtor-c55c8f0d4926481ea2cf49e14915688de2eb4938.tar
tor-c55c8f0d4926481ea2cf49e14915688de2eb4938.tar.gz
new GETINFO command to return list of listeners of a given type
-rw-r--r--changes/feature30767
-rw-r--r--src/or/control.c58
2 files changed, 63 insertions, 2 deletions
diff --git a/changes/feature3076 b/changes/feature3076
index 582285070..aadd29627 100644
--- a/changes/feature3076
+++ b/changes/feature3076
@@ -1,5 +1,8 @@
o Minor features
- The options SocksPort, ControlPort, and so on now all accept an
optional value "auto" that opens a socket on an OS-selected port.
-
-
+ o Minor features (controller)
+ - GETINFO net/listeners/(type) now returns a list of the addresses
+ 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.
diff --git a/src/or/control.c b/src/or/control.c
index c5362424a..19e8539a2 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1407,6 +1407,63 @@ munge_extrainfo_into_routerinfo(const char *ri_body, signed_descriptor_t *ri,
return tor_strndup(ri_body, ri->signed_descriptor_len);
}
+/** Implementation helper for GETINFO: answers requests for information about
+ * which ports are bound. */
+static int
+getinfo_helper_listeners(control_connection_t *control_conn,
+ const char *question,
+ char **answer, const char **errmsg)
+{
+ int type;
+ smartlist_t *res;
+
+ (void)control_conn;
+ (void)errmsg;
+
+ if (!strcmp(question, "net/listeners/or"))
+ type = CONN_TYPE_OR_LISTENER;
+ else if (!strcmp(question, "net/listeners/dir"))
+ type = CONN_TYPE_DIR_LISTENER;
+ else if (!strcmp(question, "net/listeners/socks"))
+ type = CONN_TYPE_AP_LISTENER;
+ else if (!strcmp(question, "net/listeners/trans"))
+ type = CONN_TYPE_AP_TRANS_LISTENER;
+ else if (!strcmp(question, "net/listeners/natd"))
+ type = CONN_TYPE_AP_NATD_LISTENER;
+ else if (!strcmp(question, "net/listeners/dns"))
+ type = CONN_TYPE_AP_DNS_LISTENER;
+ else if (!strcmp(question, "net/listeners/control"))
+ type = CONN_TYPE_CONTROL_LISTENER;
+ else
+ return 0; /* unknown key */
+
+ res = smartlist_create();
+ SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
+ char *addr;
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+
+ if (conn->type != type || conn->marked_for_close || conn->s < 0)
+ continue;
+
+ if (getsockname(conn->s, (struct sockaddr *)&ss, &ss_len) < 0) {
+ tor_asprintf(&addr, "%s:%d", conn->address, (int)conn->port);
+ } else {
+ char *tmp = tor_sockaddr_to_str((struct sockaddr *)&ss);
+ addr = esc_for_log(tmp);
+ tor_free(tmp);
+ }
+ if (addr)
+ smartlist_add(res, addr);
+ } SMARTLIST_FOREACH_END(conn);
+
+ *answer = smartlist_join_strings(res, " ", 0, NULL);
+
+ SMARTLIST_FOREACH(res, char *, cp, tor_free(cp));
+ smartlist_free(res);
+ return 0;
+}
+
/** Implementation helper for GETINFO: knows the answers for questions about
* directory information. */
static int
@@ -1861,6 +1918,7 @@ static const getinfo_item_t getinfo_items[] = {
"All non-expired, non-superseded router descriptors."),
ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */
PREFIX("extra-info/digest/", dir, "Extra-info documents by digest."),
+ PREFIX("net/listeners/", listeners, "Bound addresses by type"),
ITEM("ns/all", networkstatus,
"Brief summary of router status (v2 directory format)"),
PREFIX("ns/id/", networkstatus,