diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-03-27 19:58:06 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-04-01 23:30:41 -0400 |
commit | 4fb3ae69a6f81d45843998bd1fb6cecf541ef5b8 (patch) | |
tree | e716cddec48efe61818af5677b95477e4ee4d851 | |
parent | 17d5734df47bc4b9bd40f878e492eb676ca47ae8 (diff) | |
download | tor-4fb3ae69a6f81d45843998bd1fb6cecf541ef5b8.tar tor-4fb3ae69a6f81d45843998bd1fb6cecf541ef5b8.tar.gz |
Extract code to handle RESOLVED cells
No other changes have been made; only code has been moved.
-rw-r--r-- | src/or/relay.c | 131 |
1 files changed, 71 insertions, 60 deletions
diff --git a/src/or/relay.c b/src/or/relay.c index 8c009b556..3e28077e1 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1009,6 +1009,76 @@ connected_cell_parse(const relay_header_t *rh, const cell_t *cell, return 0; } +/** DOCDOC */ +static void +connection_edge_process_resolved_cell(edge_connection_t *conn, + const cell_t *cell, + const relay_header_t *rh) +{ + int ttl; + int answer_len; + uint8_t answer_type; + entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn); + if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) { + log_fn(LOG_PROTOCOL_WARN, LD_APP, "Got a 'resolved' cell while " + "not in state resolve_wait. Dropping."); + return; + } + tor_assert(SOCKS_COMMAND_IS_RESOLVE(entry_conn->socks_request->command)); + answer_len = cell->payload[RELAY_HEADER_SIZE+1]; + if (rh->length < 2 || answer_len+2>rh->length) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Dropping malformed 'resolved' cell"); + connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TORPROTOCOL); + return; + } + + answer_type = cell->payload[RELAY_HEADER_SIZE]; + if (rh->length >= answer_len+6) + ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+ + 2+answer_len)); + else + ttl = -1; + if (answer_type == RESOLVED_TYPE_IPV4 || + answer_type == RESOLVED_TYPE_IPV6) { + tor_addr_t addr; + if (decode_address_from_payload(&addr, cell->payload+RELAY_HEADER_SIZE, + rh->length) && + tor_addr_is_internal(&addr, 0) && + get_options()->ClientDNSRejectInternalAddresses) { + log_info(LD_APP,"Got a resolve with answer %s. Rejecting.", + fmt_addr(&addr)); + connection_ap_handshake_socks_resolved(entry_conn, + RESOLVED_TYPE_ERROR_TRANSIENT, + 0, NULL, 0, TIME_MAX); + connection_mark_unattached_ap(entry_conn, + END_STREAM_REASON_TORPROTOCOL); + return; + } + } + connection_ap_handshake_socks_resolved(entry_conn, + answer_type, + cell->payload[RELAY_HEADER_SIZE+1], /*answer_len*/ + cell->payload+RELAY_HEADER_SIZE+2, /*answer*/ + ttl, + -1); + if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) { + tor_addr_t addr; + tor_addr_from_ipv4n(&addr, + get_uint32(cell->payload+RELAY_HEADER_SIZE+2)); + remap_event_helper(entry_conn, &addr); + } else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) { + tor_addr_t addr; + tor_addr_from_ipv6_bytes(&addr, + (char*)(cell->payload+RELAY_HEADER_SIZE+2)); + remap_event_helper(entry_conn, &addr); + } + connection_mark_unattached_ap(entry_conn, + END_STREAM_REASON_DONE | + END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); + +} + /** An incoming relay cell has arrived from circuit <b>circ</b> to * stream <b>conn</b>. * @@ -1133,66 +1203,7 @@ connection_edge_process_relay_cell_not_open( } if (conn->base_.type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_RESOLVED) { - int ttl; - int answer_len; - uint8_t answer_type; - entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn); - if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) { - log_fn(LOG_PROTOCOL_WARN, LD_APP, "Got a 'resolved' cell while " - "not in state resolve_wait. Dropping."); - return 0; - } - tor_assert(SOCKS_COMMAND_IS_RESOLVE(entry_conn->socks_request->command)); - answer_len = cell->payload[RELAY_HEADER_SIZE+1]; - if (rh->length < 2 || answer_len+2>rh->length) { - log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, - "Dropping malformed 'resolved' cell"); - connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TORPROTOCOL); - return 0; - } - answer_type = cell->payload[RELAY_HEADER_SIZE]; - if (rh->length >= answer_len+6) - ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+ - 2+answer_len)); - else - ttl = -1; - if (answer_type == RESOLVED_TYPE_IPV4 || - answer_type == RESOLVED_TYPE_IPV6) { - tor_addr_t addr; - if (decode_address_from_payload(&addr, cell->payload+RELAY_HEADER_SIZE, - rh->length) && - tor_addr_is_internal(&addr, 0) && - get_options()->ClientDNSRejectInternalAddresses) { - log_info(LD_APP,"Got a resolve with answer %s. Rejecting.", - fmt_addr(&addr)); - connection_ap_handshake_socks_resolved(entry_conn, - RESOLVED_TYPE_ERROR_TRANSIENT, - 0, NULL, 0, TIME_MAX); - connection_mark_unattached_ap(entry_conn, - END_STREAM_REASON_TORPROTOCOL); - return 0; - } - } - connection_ap_handshake_socks_resolved(entry_conn, - answer_type, - cell->payload[RELAY_HEADER_SIZE+1], /*answer_len*/ - cell->payload+RELAY_HEADER_SIZE+2, /*answer*/ - ttl, - -1); - if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) { - tor_addr_t addr; - tor_addr_from_ipv4n(&addr, - get_uint32(cell->payload+RELAY_HEADER_SIZE+2)); - remap_event_helper(entry_conn, &addr); - } else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) { - tor_addr_t addr; - tor_addr_from_ipv6_bytes(&addr, - (char*)(cell->payload+RELAY_HEADER_SIZE+2)); - remap_event_helper(entry_conn, &addr); - } - connection_mark_unattached_ap(entry_conn, - END_STREAM_REASON_DONE | - END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); + connection_edge_process_resolved_cell(conn, cell, rh); return 0; } |