mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Implement exit enclaves: if we know an IP address for the destination,
and there's a running Tor server at that address which allows exit to the destination, then extend the circuit to that exit first. Also, if the user asks for a .exit node, cannibalize general circs for it. svn:r4779
This commit is contained in:
@@ -1168,7 +1168,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
|
||||
router = smartlist_get(dir->routers, i);
|
||||
if (n_supported[i] != -1 &&
|
||||
(try || router_handles_some_port(router, needed_ports))) {
|
||||
log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.", try, router->nickname);
|
||||
// log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.", try, router->nickname);
|
||||
smartlist_add(sl, router);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -749,7 +749,7 @@ circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *info,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (purpose != CIRCUIT_PURPOSE_C_GENERAL &&
|
||||
if ((info || purpose != CIRCUIT_PURPOSE_C_GENERAL) &&
|
||||
purpose != CIRCUIT_PURPOSE_TESTING) {
|
||||
/* see if there are appropriate circs available to cannibalize. */
|
||||
if ((circ = circuit_get_clean_open(CIRCUIT_PURPOSE_C_GENERAL, need_uptime,
|
||||
@@ -768,6 +768,7 @@ circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *info,
|
||||
break;
|
||||
case CIRCUIT_PURPOSE_C_INTRODUCING:
|
||||
case CIRCUIT_PURPOSE_S_CONNECT_REND:
|
||||
case CIRCUIT_PURPOSE_C_GENERAL:
|
||||
/* need to add a new hop */
|
||||
tor_assert(info);
|
||||
if (circuit_extend_to_new_exit(circ, info) < 0)
|
||||
|
||||
@@ -1009,7 +1009,7 @@ connection_ap_handshake_process_socks(connection_t *conn)
|
||||
return -1;
|
||||
}
|
||||
if (tor_inet_aton(socks->address, &in)) { /* see if it's an IP already */
|
||||
answer = in.s_addr;
|
||||
answer = in.s_addr; /* leave it in network order */
|
||||
connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
|
||||
(char*)&answer);
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
|
||||
@@ -1023,20 +1023,34 @@ connection_ap_handshake_process_socks(connection_t *conn)
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!conn->chosen_exit_name) {
|
||||
/* see if we can find a suitable enclave exit */
|
||||
routerinfo_t *r =
|
||||
router_find_exact_exit_enclave(socks->address, socks->port);
|
||||
if (r) {
|
||||
log_fn(LOG_INFO,"Redirecting address %s to exit at enclave router %s",
|
||||
safe_str(socks->address), r->nickname);
|
||||
/* use the hex digest, not nickname, in case there are two
|
||||
routers with this nickname */
|
||||
conn->chosen_exit_name =
|
||||
tor_strdup(hex_str(r->identity_digest, DIGEST_LEN));
|
||||
}
|
||||
}
|
||||
|
||||
rep_hist_note_used_port(socks->port, time(NULL)); /* help predict this next time */
|
||||
control_event_stream_status(conn, STREAM_EVENT_NEW);
|
||||
}
|
||||
if (! get_options()->LeaveStreamsUnattached) {
|
||||
if (get_options()->LeaveStreamsUnattached) {
|
||||
conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
|
||||
} else {
|
||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
if (connection_ap_handshake_attach_circuit(conn) < 0) {
|
||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
/* it's a hidden-service request */
|
||||
rend_cache_entry_t *entry;
|
||||
|
||||
@@ -2300,6 +2300,7 @@ control_event_stream_status(connection_t *conn, stream_status_event_t tp)
|
||||
(unsigned long)conn->global_identifier, status,
|
||||
circ?(unsigned long)circ->global_identifier : 0ul,
|
||||
buf);
|
||||
/* XXX need to specify its intended exit, etc? */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-1
@@ -626,7 +626,7 @@ struct connection_t {
|
||||
char identity_digest[DIGEST_LEN]; /**< Hash of identity_pkey */
|
||||
char *nickname; /**< Nickname of OR on other side (if any). */
|
||||
|
||||
/** Nickname of planned exit node -- to be used with .exit support. */
|
||||
/** Nickname of planned exit node -- used with .exit support. */
|
||||
char *chosen_exit_name;
|
||||
|
||||
/* Used only by OR connections: */
|
||||
@@ -1952,6 +1952,7 @@ int exit_policy_implicitly_allows_local_networks(addr_policy_t *policy,
|
||||
#define ROUTER_REQUIRED_MIN_UPTIME (24*3600) /* a day */
|
||||
#define ROUTER_REQUIRED_MIN_BANDWIDTH 10000
|
||||
|
||||
routerinfo_t *router_find_exact_exit_enclave(const char *address, uint16_t port);
|
||||
int router_is_unreliable(routerinfo_t *router, int need_uptime, int need_capacity);
|
||||
routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl);
|
||||
routerinfo_t *router_choose_random_node(const char *preferred,
|
||||
|
||||
@@ -433,6 +433,37 @@ routerlist_find_my_routerinfo(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Find a router that's up, that has this IP address, and
|
||||
* that allows exit to this address:port, or return NULL if there
|
||||
* isn't a good one.
|
||||
*/
|
||||
routerinfo_t *
|
||||
router_find_exact_exit_enclave(const char *address, uint16_t port) {
|
||||
int i;
|
||||
routerinfo_t *router;
|
||||
uint32_t addr;
|
||||
struct in_addr in;
|
||||
|
||||
if (!tor_inet_aton(address, &in))
|
||||
return NULL; /* it's not an IP already */
|
||||
addr = ntohl(in.s_addr);
|
||||
|
||||
for (i=0;i < smartlist_len(routerlist->routers); i++) {
|
||||
router = smartlist_get(routerlist->routers, i);
|
||||
log_fn(LOG_DEBUG,"Considering %s: %d, %u==%u, %d.",
|
||||
router->nickname,
|
||||
router->is_running,
|
||||
router->addr, addr,
|
||||
router_compare_addr_to_addr_policy(addr, port, router->exit_policy));
|
||||
if (router->is_running &&
|
||||
router->addr == addr &&
|
||||
router_compare_addr_to_addr_policy(addr, port, router->exit_policy) ==
|
||||
ADDR_POLICY_ACCEPTED)
|
||||
return router;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return 1 if <b>router</b> is not suitable for these parameters, else 0.
|
||||
* If <b>need_uptime</b> is non-zero, we require a minimum uptime.
|
||||
* If <b>need_capacity</b> is non-zero, we require a minimum advertised
|
||||
|
||||
Reference in New Issue
Block a user