mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
start allowing clients to give up on trackhostexits targets if
five circuit attempts fail for a given stream. part of the fix for bug 437. still an XXX020rc remaining. svn:r13648
This commit is contained in:
parent
18a209ffe6
commit
a60f7caa54
@ -2876,7 +2876,7 @@ assert_connection_ok(connection_t *conn, time_t now)
|
|||||||
assert_buf_ok(conn->outbuf);
|
assert_buf_ok(conn->outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->chosen_exit_optional) {
|
if (conn->chosen_exit_optional || conn->chosen_exit_retries) {
|
||||||
tor_assert(conn->type == CONN_TYPE_AP);
|
tor_assert(conn->type == CONN_TYPE_AP);
|
||||||
tor_assert((TO_EDGE_CONN(conn))->chosen_exit_name);
|
tor_assert((TO_EDGE_CONN(conn))->chosen_exit_name);
|
||||||
}
|
}
|
||||||
|
@ -472,13 +472,16 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
|
|||||||
if (conn->marked_for_close ||
|
if (conn->marked_for_close ||
|
||||||
conn->type != CONN_TYPE_AP ||
|
conn->type != CONN_TYPE_AP ||
|
||||||
conn->state != AP_CONN_STATE_CIRCUIT_WAIT ||
|
conn->state != AP_CONN_STATE_CIRCUIT_WAIT ||
|
||||||
!conn->chosen_exit_optional)
|
(!conn->chosen_exit_optional &&
|
||||||
|
!conn->chosen_exit_retries))
|
||||||
continue;
|
continue;
|
||||||
edge_conn = TO_EDGE_CONN(conn);
|
edge_conn = TO_EDGE_CONN(conn);
|
||||||
r1 = router_get_by_nickname(edge_conn->chosen_exit_name, 0);
|
r1 = router_get_by_nickname(edge_conn->chosen_exit_name, 0);
|
||||||
r2 = router_get_by_nickname(info->nickname, 0);
|
r2 = router_get_by_nickname(info->nickname, 0);
|
||||||
if (r1 && r2 && r1==r2) {
|
if (!r1 || !r2 || r1 != r2)
|
||||||
tor_assert(edge_conn->socks_request);
|
continue;
|
||||||
|
tor_assert(edge_conn->socks_request);
|
||||||
|
if (conn->chosen_exit_optional) {
|
||||||
log_info(LD_APP, "Giving up on enclave exit '%s' for destination %s.",
|
log_info(LD_APP, "Giving up on enclave exit '%s' for destination %s.",
|
||||||
safe_str(edge_conn->chosen_exit_name),
|
safe_str(edge_conn->chosen_exit_name),
|
||||||
escaped_safe_str(edge_conn->socks_request->address));
|
escaped_safe_str(edge_conn->socks_request->address));
|
||||||
@ -488,6 +491,16 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
|
|||||||
* think it'll be using an enclave. */
|
* think it'll be using an enclave. */
|
||||||
consider_plaintext_ports(edge_conn, edge_conn->socks_request->port);
|
consider_plaintext_ports(edge_conn, edge_conn->socks_request->port);
|
||||||
}
|
}
|
||||||
|
if (conn->chosen_exit_retries) {
|
||||||
|
if (--conn->chosen_exit_retries == 0) { /* give up! */
|
||||||
|
/* XXX020rc unregister maps from foo to
|
||||||
|
* foo.chosen_exit_name.exit \forall foo. -RD */
|
||||||
|
tor_free(edge_conn->chosen_exit_name); /* clears it */
|
||||||
|
/* if this port is dangerous, warn or reject it now that we don't
|
||||||
|
* think it'll be using an enclave. */
|
||||||
|
consider_plaintext_ports(edge_conn, edge_conn->socks_request->port);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,6 +1257,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
|||||||
int automap = 0;
|
int automap = 0;
|
||||||
char orig_address[MAX_SOCKS_ADDR_LEN];
|
char orig_address[MAX_SOCKS_ADDR_LEN];
|
||||||
time_t map_expires = TIME_MAX;
|
time_t map_expires = TIME_MAX;
|
||||||
|
int remapped_to_exit = 0;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
tor_strlower(socks->address); /* normalize it */
|
tor_strlower(socks->address); /* normalize it */
|
||||||
@ -1299,11 +1313,16 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!automap) {
|
} else if (!automap) {
|
||||||
|
int started_without_chosen_exit = strcasecmpend(socks->address, ".exit");
|
||||||
/* For address map controls, remap the address. */
|
/* For address map controls, remap the address. */
|
||||||
if (addressmap_rewrite(socks->address, sizeof(socks->address),
|
if (addressmap_rewrite(socks->address, sizeof(socks->address),
|
||||||
&map_expires)) {
|
&map_expires)) {
|
||||||
control_event_stream_status(conn, STREAM_EVENT_REMAP,
|
control_event_stream_status(conn, STREAM_EVENT_REMAP,
|
||||||
REMAP_STREAM_SOURCE_CACHE);
|
REMAP_STREAM_SOURCE_CACHE);
|
||||||
|
if (started_without_chosen_exit &&
|
||||||
|
!strcasecmpend(socks->address, ".exit") &&
|
||||||
|
map_expires < TIME_MAX)
|
||||||
|
remapped_to_exit = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1340,6 +1359,10 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
|||||||
if (s) {
|
if (s) {
|
||||||
if (s[1] != '\0') {
|
if (s[1] != '\0') {
|
||||||
conn->chosen_exit_name = tor_strdup(s+1);
|
conn->chosen_exit_name = tor_strdup(s+1);
|
||||||
|
/* DOCDOC */
|
||||||
|
#define TRACKHOSTEXITS_RETRIES 5
|
||||||
|
if (remapped_to_exit) /* 5 tries before it expires the addressmap */
|
||||||
|
TO_CONN(conn)->chosen_exit_retries = TRACKHOSTEXITS_RETRIES;
|
||||||
*s = 0;
|
*s = 0;
|
||||||
} else {
|
} else {
|
||||||
log_warn(LD_APP,"Malformed exit address '%s.exit'. Refusing.",
|
log_warn(LD_APP,"Malformed exit address '%s.exit'. Refusing.",
|
||||||
|
@ -811,6 +811,11 @@ typedef struct connection_t {
|
|||||||
/** For AP connections only. If 1, and we fail to reach the chosen exit,
|
/** For AP connections only. If 1, and we fail to reach the chosen exit,
|
||||||
* stop requiring it. */
|
* stop requiring it. */
|
||||||
unsigned int chosen_exit_optional:1;
|
unsigned int chosen_exit_optional:1;
|
||||||
|
/** For AP connections only. If non-zero, this exit node was picked as
|
||||||
|
* a result of the TrackHostExit, and the value decrements every time
|
||||||
|
* we fail to complete a circuit to our chosen exit -- if it reaches
|
||||||
|
* zero, abandon the associated mapaddress. */
|
||||||
|
unsigned int chosen_exit_retries:3;
|
||||||
/** Set to 1 when we're inside connection_flushed_some to keep us from
|
/** Set to 1 when we're inside connection_flushed_some to keep us from
|
||||||
* calling connection_handle_write() recursively. */
|
* calling connection_handle_write() recursively. */
|
||||||
unsigned int in_flushed_some:1;
|
unsigned int in_flushed_some:1;
|
||||||
@ -861,7 +866,7 @@ typedef struct connection_t {
|
|||||||
* we marked for close? */
|
* we marked for close? */
|
||||||
char *address; /**< FQDN (or IP) of the guy on the other end.
|
char *address; /**< FQDN (or IP) of the guy on the other end.
|
||||||
* strdup into this, because free_connection frees it. */
|
* strdup into this, because free_connection frees it. */
|
||||||
/** Annother connection that's connected to this one in lieu of a socket. */
|
/** Another connection that's connected to this one in lieu of a socket. */
|
||||||
struct connection_t *linked_conn;
|
struct connection_t *linked_conn;
|
||||||
|
|
||||||
/* XXXX021 move this into a subtype. */
|
/* XXXX021 move this into a subtype. */
|
||||||
|
@ -771,9 +771,18 @@ connection_edge_process_end_not_open(
|
|||||||
NULL)) {
|
NULL)) {
|
||||||
control_event_stream_status(conn, STREAM_EVENT_REMAP, 0);
|
control_event_stream_status(conn, STREAM_EVENT_REMAP, 0);
|
||||||
}
|
}
|
||||||
if (conn->_base.chosen_exit_optional) {
|
if (conn->_base.chosen_exit_optional ||
|
||||||
|
conn->_base.chosen_exit_retries) {
|
||||||
/* stop wanting a specific exit */
|
/* stop wanting a specific exit */
|
||||||
conn->_base.chosen_exit_optional = 0;
|
conn->_base.chosen_exit_optional = 0;
|
||||||
|
/* A non-zero chosen_exit_retries can happen if we set a
|
||||||
|
* TrackHostExits for this address under a port that the exit
|
||||||
|
* relay allows, but then try the same address with a different
|
||||||
|
* port that it doesn't allow to exit. We shouldn't unregister
|
||||||
|
* the mapping, since it is probably still wanted on the
|
||||||
|
* original port. But now we give away to the exit relay that
|
||||||
|
* we probably have a TrackHostExits on it. So be it. */
|
||||||
|
conn->_base.chosen_exit_retries = 0;
|
||||||
tor_free(conn->chosen_exit_name); /* clears it */
|
tor_free(conn->chosen_exit_name); /* clears it */
|
||||||
}
|
}
|
||||||
if (connection_ap_detach_retriable(conn, circ, control_reason) >= 0)
|
if (connection_ap_detach_retriable(conn, circ, control_reason) >= 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user