|
@@ -129,6 +129,9 @@ typedef struct rend_service_t {
|
|
|
* when they do, this keeps us from launching multiple simultaneous attempts
|
|
|
* to connect to the same rend point. */
|
|
|
replaycache_t *accepted_intro_dh_parts;
|
|
|
+ /** If true, we don't close circuits for making requests to unsupported
|
|
|
+ * ports. */
|
|
|
+ int allow_unknown_ports;
|
|
|
} rend_service_t;
|
|
|
|
|
|
/** A list of rend_service_t's for services run on this OP.
|
|
@@ -397,6 +400,19 @@ rend_config_services(const or_options_t *options, int validate_only)
|
|
|
return -1;
|
|
|
}
|
|
|
smartlist_add(service->ports, portcfg);
|
|
|
+ } else if (!strcasecmp(line->key, "HiddenServiceAllowUnknownPorts")) {
|
|
|
+ service->allow_unknown_ports = (int)tor_parse_long(line->value,
|
|
|
+ 10, 0, 1, &ok, NULL);
|
|
|
+ if (!ok) {
|
|
|
+ log_warn(LD_CONFIG,
|
|
|
+ "HiddenServiceAllowUnknownPorts should be 0 or 1, not %s",
|
|
|
+ line->value);
|
|
|
+ rend_service_free(service);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ log_info(LD_CONFIG,
|
|
|
+ "HiddenServiceAllowUnknownPorts=%d for %s",
|
|
|
+ (int)service->allow_unknown_ports, service->directory);
|
|
|
} else if (!strcasecmp(line->key,
|
|
|
"HiddenServiceDirGroupReadable")) {
|
|
|
service->dir_group_readable = (int)tor_parse_long(line->value,
|
|
@@ -3388,7 +3404,8 @@ rend_service_dump_stats(int severity)
|
|
|
|
|
|
/** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
|
|
|
* 'circ', and look up the port and address based on conn-\>port.
|
|
|
- * Assign the actual conn-\>addr and conn-\>port. Return -1 if failure,
|
|
|
+ * Assign the actual conn-\>addr and conn-\>port. Return -2 on failure
|
|
|
+ * for which the circuit should be closed, -1 on other failure,
|
|
|
* or 0 for success.
|
|
|
*/
|
|
|
int
|
|
@@ -3411,7 +3428,7 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
|
|
|
log_warn(LD_REND, "Couldn't find any service associated with pk %s on "
|
|
|
"rendezvous circuit %u; closing.",
|
|
|
serviceid, (unsigned)circ->base_.n_circ_id);
|
|
|
- return -1;
|
|
|
+ return -2;
|
|
|
}
|
|
|
matching_ports = smartlist_new();
|
|
|
SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p,
|
|
@@ -3429,6 +3446,9 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
|
|
|
}
|
|
|
log_info(LD_REND, "No virtual port mapping exists for port %d on service %s",
|
|
|
conn->base_.port,serviceid);
|
|
|
- return -1;
|
|
|
+ if (service->allow_unknown_ports)
|
|
|
+ return -1;
|
|
|
+ else
|
|
|
+ return -2;
|
|
|
}
|
|
|
|