diff options
author | Roger Dingledine <arma@torproject.org> | 2005-08-15 03:25:40 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2005-08-15 03:25:40 +0000 |
commit | f57d062d9c4fed001bb6dcd40d122de8d1368e0a (patch) | |
tree | b06b9db856e88ec49fc62b819d1c671474b75bfa /src | |
parent | 121ea4dd933b78b77189823557a5728a736a9a2f (diff) | |
download | tor-f57d062d9c4fed001bb6dcd40d122de8d1368e0a.tar tor-f57d062d9c4fed001bb6dcd40d122de8d1368e0a.tar.gz |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitbuild.c | 2 | ||||
-rw-r--r-- | src/or/circuituse.c | 3 | ||||
-rw-r--r-- | src/or/connection_edge.c | 26 | ||||
-rw-r--r-- | src/or/control.c | 1 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routerlist.c | 31 |
6 files changed, 57 insertions, 9 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 8242a5a3e..c905e9356 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -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); } } diff --git a/src/or/circuituse.c b/src/or/circuituse.c index a1aa3d716..0fb8285ea 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -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) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index edd776b86..e2f1d43b5 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -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; diff --git a/src/or/control.c b/src/or/control.c index bd8c591ac..65568e499 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -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; } diff --git a/src/or/or.h b/src/or/or.h index 0e10fe4ff..62ac7fc2b 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -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, diff --git a/src/or/routerlist.c b/src/or/routerlist.c index c7bda044d..a616d2284 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -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 |