aboutsummaryrefslogtreecommitdiff
path: root/src/or/relay.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-03-27 19:58:06 -0400
committerNick Mathewson <nickm@torproject.org>2014-04-01 23:30:41 -0400
commit4fb3ae69a6f81d45843998bd1fb6cecf541ef5b8 (patch)
treee716cddec48efe61818af5677b95477e4ee4d851 /src/or/relay.c
parent17d5734df47bc4b9bd40f878e492eb676ca47ae8 (diff)
downloadtor-4fb3ae69a6f81d45843998bd1fb6cecf541ef5b8.tar
tor-4fb3ae69a6f81d45843998bd1fb6cecf541ef5b8.tar.gz
Extract code to handle RESOLVED cells
No other changes have been made; only code has been moved.
Diffstat (limited to 'src/or/relay.c')
-rw-r--r--src/or/relay.c131
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;
}