commit 5d89ea1e6c148ce584dc2059c4d353d12d01e8d1 Author: George Kadianakis desnacked@riseup.net Date: Thu Jun 1 13:24:28 2017 +0300
prop224: Decouple the HS part of connection_ap_handshake_rewrite_and_attach().
We will need to edit this function, and it's already pretty huge. Let's make it a bit smaller.
This commit moves code, fixes a 80 char line and add two lines at the start to make it compile. Trivial change.
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/connection_edge.c | 226 +++++++++++++++++++++++++---------------------- 1 file changed, 119 insertions(+), 107 deletions(-)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 941b273cc..a0aa7c195 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1392,6 +1392,124 @@ connection_ap_handshake_rewrite(entry_connection_t *conn, } }
+static int +connection_ap_handle_onion(entry_connection_t *conn, + socks_request_t *socks, + origin_circuit_t *circ) +{ + time_t now = approx_time(); + connection_t *base_conn = ENTRY_TO_CONN(conn); + + /* If .onion address requests are disabled, refuse the request */ + if (!conn->entry_cfg.onion_traffic) { + log_warn(LD_APP, "Onion address %s requested from a port with .onion " + "disabled", safe_str_client(socks->address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); + return -1; + } + + /* Check whether it's RESOLVE or RESOLVE_PTR. We don't handle those + * for hidden service addresses. */ + if (SOCKS_COMMAND_IS_RESOLVE(socks->command)) { + /* if it's a resolve request, fail it right now, rather than + * building all the circuits and then realizing it won't work. */ + log_warn(LD_APP, + "Resolve requests to hidden services not allowed. Failing."); + connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR, + 0,NULL,-1,TIME_MAX); + connection_mark_unattached_ap(conn, + END_STREAM_REASON_SOCKSPROTOCOL | + END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); + return -1; + } + + /* If we were passed a circuit, then we need to fail. .onion addresses + * only work when we launch our own circuits for now. */ + if (circ) { + log_warn(LD_CONTROL, "Attachstream to a circuit is not " + "supported for .onion addresses currently. Failing."); + connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); + return -1; + } + + /* Look up if we have client authorization configured for this hidden + * service. If we do, associate it with the rend_data. */ + rend_service_authorization_t *client_auth = + rend_client_lookup_service_authorization(socks->address); + + const uint8_t *cookie = NULL; + rend_auth_type_t auth_type = REND_NO_AUTH; + if (client_auth) { + log_info(LD_REND, "Using previously configured client authorization " + "for hidden service request."); + auth_type = client_auth->auth_type; + cookie = client_auth->descriptor_cookie; + } + + /* Fill in the rend_data field so we can start doing a connection to + * a hidden service. */ + rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data = + rend_data_client_create(socks->address, NULL, (char *) cookie, + auth_type); + if (rend_data == NULL) { + return -1; + } + const char *onion_address = rend_data_get_address(rend_data); + log_info(LD_REND,"Got a hidden service request for ID '%s'", + safe_str_client(onion_address)); + + /* Lookup the given onion address. If invalid, stop right now. + * Otherwise, we might have it in the cache or not. */ + unsigned int refetch_desc = 0; + rend_cache_entry_t *entry = NULL; + const int rend_cache_lookup_result = + rend_cache_lookup_entry(onion_address, -1, &entry); + if (rend_cache_lookup_result < 0) { + switch (-rend_cache_lookup_result) { + case EINVAL: + /* We should already have rejected this address! */ + log_warn(LD_BUG,"Invalid service name '%s'", + safe_str_client(onion_address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); + return -1; + case ENOENT: + /* We didn't have this; we should look it up. */ + refetch_desc = 1; + break; + default: + log_warn(LD_BUG, "Unknown cache lookup error %d", + rend_cache_lookup_result); + return -1; + } + } + + /* Help predict that we'll want to do hidden service circuits in the + * future. We're not sure if it will need a stable circuit yet, but + * we know we'll need *something*. */ + rep_hist_note_used_internal(now, 0, 1); + + /* Now we have a descriptor but is it usable or not? If not, refetch. + * Also, a fetch could have been requested if the onion address was not + * found in the cache previously. */ + if (refetch_desc || !rend_client_any_intro_points_usable(entry)) { + connection_ap_mark_as_non_pending_circuit(conn); + base_conn->state = AP_CONN_STATE_RENDDESC_WAIT; + log_info(LD_REND, "Unknown descriptor %s. Fetching.", + safe_str_client(onion_address)); + rend_client_refetch_v2_renddesc(rend_data); + return 0; + } + + /* We have the descriptor! So launch a connection to the HS. */ + base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT; + log_info(LD_REND, "Descriptor is here. Great."); + + /* We'll try to attach it at the next event loop, or whenever + * we call connection_ap_attach_pending() */ + connection_ap_mark_as_pending_circuit(conn); + return 0; +} + /** Connection <b>conn</b> just finished its socks handshake, or the * controller asked us to take care of it. If <b>circ</b> is defined, * then that's where we'll want to attach it. Otherwise we have to @@ -1837,115 +1955,9 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, } else { /* If we get here, it's a request for a .onion address! */ tor_assert(!automap); - - /* If .onion address requests are disabled, refuse the request */ - if (!conn->entry_cfg.onion_traffic) { - log_warn(LD_APP, "Onion address %s requested from a port with .onion " - "disabled", safe_str_client(socks->address)); - connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); - return -1; - } - - /* Check whether it's RESOLVE or RESOLVE_PTR. We don't handle those - * for hidden service addresses. */ - if (SOCKS_COMMAND_IS_RESOLVE(socks->command)) { - /* if it's a resolve request, fail it right now, rather than - * building all the circuits and then realizing it won't work. */ - log_warn(LD_APP, - "Resolve requests to hidden services not allowed. Failing."); - connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR, - 0,NULL,-1,TIME_MAX); - connection_mark_unattached_ap(conn, - END_STREAM_REASON_SOCKSPROTOCOL | - END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); - return -1; - } - - /* If we were passed a circuit, then we need to fail. .onion addresses - * only work when we launch our own circuits for now. */ - if (circ) { - log_warn(LD_CONTROL, "Attachstream to a circuit is not " - "supported for .onion addresses currently. Failing."); - connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); - return -1; - } - - /* Look up if we have client authorization configured for this hidden - * service. If we do, associate it with the rend_data. */ - rend_service_authorization_t *client_auth = - rend_client_lookup_service_authorization(socks->address); - - const uint8_t *cookie = NULL; - rend_auth_type_t auth_type = REND_NO_AUTH; - if (client_auth) { - log_info(LD_REND, "Using previously configured client authorization " - "for hidden service request."); - auth_type = client_auth->auth_type; - cookie = client_auth->descriptor_cookie; - } - - /* Fill in the rend_data field so we can start doing a connection to - * a hidden service. */ - rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data = - rend_data_client_create(socks->address, NULL, (char *) cookie, - auth_type); - if (rend_data == NULL) { + if (connection_ap_handle_onion(conn, socks, circ) < 0) { return -1; } - const char *onion_address = rend_data_get_address(rend_data); - log_info(LD_REND,"Got a hidden service request for ID '%s'", - safe_str_client(onion_address)); - - /* Lookup the given onion address. If invalid, stop right now. - * Otherwise, we might have it in the cache or not. */ - unsigned int refetch_desc = 0; - rend_cache_entry_t *entry = NULL; - const int rend_cache_lookup_result = - rend_cache_lookup_entry(onion_address, -1, &entry); - if (rend_cache_lookup_result < 0) { - switch (-rend_cache_lookup_result) { - case EINVAL: - /* We should already have rejected this address! */ - log_warn(LD_BUG,"Invalid service name '%s'", - safe_str_client(onion_address)); - connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); - return -1; - case ENOENT: - /* We didn't have this; we should look it up. */ - refetch_desc = 1; - break; - default: - log_warn(LD_BUG, "Unknown cache lookup error %d", - rend_cache_lookup_result); - return -1; - } - } - - /* Help predict that we'll want to do hidden service circuits in the - * future. We're not sure if it will need a stable circuit yet, but - * we know we'll need *something*. */ - rep_hist_note_used_internal(now, 0, 1); - - /* Now we have a descriptor but is it usable or not? If not, refetch. - * Also, a fetch could have been requested if the onion address was not - * found in the cache previously. */ - if (refetch_desc || !rend_client_any_intro_points_usable(entry)) { - connection_ap_mark_as_non_pending_circuit(conn); - base_conn->state = AP_CONN_STATE_RENDDESC_WAIT; - log_info(LD_REND, "Unknown descriptor %s. Fetching.", - safe_str_client(onion_address)); - rend_client_refetch_v2_renddesc(rend_data); - return 0; - } - - /* We have the descriptor! So launch a connection to the HS. */ - base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT; - log_info(LD_REND, "Descriptor is here. Great."); - - /* We'll try to attach it at the next event loop, or whenever - * we call connection_ap_attach_pending() */ - connection_ap_mark_as_pending_circuit(conn); - return 0; }
return 0; /* unreached but keeps the compiler happy */
tor-commits@lists.torproject.org