|
@@ -53,6 +53,10 @@ static int circuit_resume_edge_reading_helper(edge_connection_t *conn,
|
|
|
static int circuit_consider_stop_edge_reading(circuit_t *circ,
|
|
|
crypt_path_t *layer_hint);
|
|
|
static int circuit_queue_streams_are_blocked(circuit_t *circ);
|
|
|
+static void adjust_exit_policy_from_exitpolicy_failure(origin_circuit_t *circ,
|
|
|
+ entry_connection_t *conn,
|
|
|
+ node_t *node,
|
|
|
+ const tor_addr_t *addr);
|
|
|
|
|
|
|
|
|
* waiting on the appropriate queue. */
|
|
@@ -710,7 +714,6 @@ connection_ap_process_end_not_open(
|
|
|
relay_header_t *rh, cell_t *cell, origin_circuit_t *circ,
|
|
|
entry_connection_t *conn, crypt_path_t *layer_hint)
|
|
|
{
|
|
|
- struct in_addr in;
|
|
|
node_t *exitrouter;
|
|
|
int reason = *(cell->payload+RELAY_HEADER_SIZE);
|
|
|
int control_reason;
|
|
@@ -753,10 +756,10 @@ connection_ap_process_end_not_open(
|
|
|
stream_end_reason_to_string(reason));
|
|
|
exitrouter = node_get_mutable_by_id(chosen_exit_digest);
|
|
|
switch (reason) {
|
|
|
- case END_STREAM_REASON_EXITPOLICY:
|
|
|
+ case END_STREAM_REASON_EXITPOLICY: {
|
|
|
+ tor_addr_t addr;
|
|
|
+ tor_addr_make_unspec(&addr);
|
|
|
if (rh->length >= 5) {
|
|
|
- tor_addr_t addr;
|
|
|
-
|
|
|
int ttl = -1;
|
|
|
tor_addr_make_unspec(&addr);
|
|
|
if (rh->length == 5 || rh->length == 9) {
|
|
@@ -808,16 +811,11 @@ connection_ap_process_end_not_open(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (exitrouter &&
|
|
|
- (rh->length < 5 ||
|
|
|
- (tor_inet_aton(conn->socks_request->address, &in) &&
|
|
|
- !conn->chosen_exit_name))) {
|
|
|
- log_info(LD_APP,
|
|
|
- "Exitrouter %s seems to be more restrictive than its exit "
|
|
|
- "policy. Not using this router as exit for now.",
|
|
|
- node_describe(exitrouter));
|
|
|
- policies_set_node_exitpolicy_to_reject_all(exitrouter);
|
|
|
- }
|
|
|
+
|
|
|
+ adjust_exit_policy_from_exitpolicy_failure(circ,
|
|
|
+ conn,
|
|
|
+ exitrouter,
|
|
|
+ &addr);
|
|
|
|
|
|
if (conn->chosen_exit_optional ||
|
|
|
conn->chosen_exit_retries) {
|
|
@@ -837,6 +835,7 @@ connection_ap_process_end_not_open(
|
|
|
return 0;
|
|
|
|
|
|
break;
|
|
|
+ }
|
|
|
case END_STREAM_REASON_CONNECTREFUSED:
|
|
|
if (!conn->chosen_exit_optional)
|
|
|
break;
|
|
@@ -901,6 +900,47 @@ connection_ap_process_end_not_open(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * for <b>conn</b>, while attempting to connect via <b>node</b>. If the node
|
|
|
+ * told us which address it rejected, then <b>addr</b> is that address;
|
|
|
+ * otherwise it is AF_UNSPEC.
|
|
|
+ *
|
|
|
+ * If we are sure the node should have allowed this address, mark the node as
|
|
|
+ * having a reject *:* exit policy. Otherwise, mark the circuit as unusable
|
|
|
+ * for this particular address.
|
|
|
+ **/
|
|
|
+static void
|
|
|
+adjust_exit_policy_from_exitpolicy_failure(origin_circuit_t *circ,
|
|
|
+ entry_connection_t *conn,
|
|
|
+ node_t *node,
|
|
|
+ const tor_addr_t *addr)
|
|
|
+{
|
|
|
+ int make_reject_all = 0;
|
|
|
+ const sa_family_t family = tor_addr_family(addr);
|
|
|
+
|
|
|
+ if (node) {
|
|
|
+ tor_addr_t tmp;
|
|
|
+ int asked_for_family = tor_addr_parse(&tmp, conn->socks_request->address);
|
|
|
+ if (family == AF_UNSPEC) {
|
|
|
+ make_reject_all = 1;
|
|
|
+ } else if (node_exit_policy_is_exact(node, family) &&
|
|
|
+ asked_for_family != -1 && !conn->chosen_exit_name) {
|
|
|
+ make_reject_all = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (make_reject_all) {
|
|
|
+ log_info(LD_APP,
|
|
|
+ "Exitrouter %s seems to be more restrictive than its exit "
|
|
|
+ "policy. Not using this router as exit for now.",
|
|
|
+ node_describe(node));
|
|
|
+ policies_set_node_exitpolicy_to_reject_all(node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (family != AF_UNSPEC)
|
|
|
+ addr_policy_append_reject_addr(&circ->prepend_policy, addr);
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* dotted-quad representation of <b>new_addr</b>,
|
|
|
* and send an appropriate REMAP event. */
|