Commit 3f9afa06 authored by Nick Mathewson's avatar Nick Mathewson 🎨
Browse files

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.

parent e11a92bd
......@@ -103,6 +103,12 @@ Changes in version - 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
......@@ -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 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.
\fBHiddenServiceNodes \fR\fInickname\fR,\fInickname\fR,\fI...\fP
......@@ -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,14 +1172,20 @@ 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;
smartlist_add(matching_ports, p);
chosen_port = smartlist_choose(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",
return -1;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment