summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-05-29 18:58:16 +0000
committerNick Mathewson <nickm@torproject.org>2007-05-29 18:58:16 +0000
commit3f9afa06250febe954c8bcebbea3a21c398e89a1 (patch)
treed9dbc7a85e0fa5fe80dcc3bc819dad818d1ec694
parente11a92bd54926cfa8fd75c3a73d93ab2e1fbc007 (diff)
downloadtor-3f9afa06250febe954c8bcebbea3a21c398e89a1.tar.gz
tor-3f9afa06250febe954c8bcebbea3a21c398e89a1.zip
r13068@catbus: nickm | 2007-05-29 14:58:13 -0400
Add some code to mitigate bug 393: Choose at random from multiple hidden service ports with the same virtport. This allows limited ad-hoc round-robining. svn:r10398
-rw-r--r--ChangeLog6
-rw-r--r--doc/tor.1.in4
-rw-r--r--src/or/rendservice.c20
3 files changed, 22 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 83c3b7ade0..320c48f299 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -103,6 +103,12 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
to the AutomapHostsOnResolve option, this is no longer a completely
silly thing to do.
+ o Minor features (hidden services):
+ - Allow multiple HiddenServeicePort directives with the same virtual
+ port; when they occur, the user is sent round-robin to one
+ of the target ports chosen at random. Partially fixes bug 393 by
+ adding limited ad-hoc round-robining.
+
o Minor features (other):
- More unit tests.
- Add a new AutomapHostsOnResolve option: when it is enabled, any
diff --git a/doc/tor.1.in b/doc/tor.1.in
index 0e9a694161..93dd90f989 100644
--- a/doc/tor.1.in
+++ b/doc/tor.1.in
@@ -981,7 +981,9 @@ Configure a virtual port VIRTPORT for a hidden service. You may use this
option multiple times; each time applies to the service using the most recent
hiddenservicedir. By default, this option maps the virtual port to the
same port on 127.0.0.1. You may override the target port, address, or both
-by specifying a target of addr, port, or addr:port.
+by specifying a target of addr, port, or addr:port. You may also have
+multiple lines with the same VIRTPORT: when a user connects to that VIRTPORT,
+one of the TARGETs from those lines will be chosen at random.
.LP
.TP
\fBHiddenServiceNodes \fR\fInickname\fR,\fInickname\fR,\fI...\fP
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index e20804438d..937d40b5c1 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1157,9 +1157,9 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
origin_circuit_t *circ)
{
rend_service_t *service;
- int i;
- rend_service_port_config_t *p;
char serviceid[REND_SERVICE_ID_LEN+1];
+ smartlist_t *matching_ports;
+ rend_service_port_config_t *chosen_port;
tor_assert(circ->_base.purpose == CIRCUIT_PURPOSE_S_REND_JOINED);
log_debug(LD_REND,"beginning to hunt for addr/port");
@@ -1172,13 +1172,19 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
serviceid, circ->_base.n_circ_id);
return -1;
}
- for (i = 0; i < smartlist_len(service->ports); ++i) {
- p = smartlist_get(service->ports, i);
+ matching_ports = smartlist_create();
+ SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p,
+ {
if (conn->_base.port == p->virtual_port) {
- conn->_base.addr = p->real_addr;
- conn->_base.port = p->real_port;
- return 0;
+ smartlist_add(matching_ports, p);
}
+ });
+ chosen_port = smartlist_choose(matching_ports);
+ smartlist_free(matching_ports);
+ if (chosen_port) {
+ conn->_base.addr = chosen_port->real_addr;
+ conn->_base.port = chosen_port->real_port;
+ return 0;
}
log_info(LD_REND, "No virtual port mapping exists for port %d on service %s",
conn->_base.port,serviceid);