|
@@ -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,
|