From d1b5ae903f330c03c32baa60fcc6679d148ad8ac Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 16 Jan 2013 12:08:10 -0500 Subject: [PATCH 1/2] When we get an END cell before CONNECTED, don't report SOCKS success Bug 7902; fix on 0.1.0.1-rc. --- changes/bug7902 | 7 +++++++ src/or/reasons.c | 7 ++++++- src/or/relay.c | 6 +++++- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 changes/bug7902 diff --git a/changes/bug7902 b/changes/bug7902 new file mode 100644 index 0000000000..051759dc0a --- /dev/null +++ b/changes/bug7902 @@ -0,0 +1,7 @@ + o Minor bugfixes: + - When we receive a RELAY_END cell with the reason DONE, or with no + reason, before receiving a RELAY_CONNECTED cell, report the SOCKS + status as "connection refused." Previously we reporting these + cases as success but then immediately closing the connection. + Fixes bug 7902; bugfix on 0.1.0.1-rc. Reported by "oftc_must_ + be_destroyed." diff --git a/src/or/reasons.c b/src/or/reasons.c index 26ad12e8fd..637f8cdc7d 100644 --- a/src/or/reasons.c +++ b/src/or/reasons.c @@ -105,7 +105,12 @@ stream_end_reason_to_socks5_response(int reason) case END_STREAM_REASON_DESTROY: return SOCKS5_GENERAL_ERROR; case END_STREAM_REASON_DONE: - return SOCKS5_SUCCEEDED; + /* Note that 'DONE' usually indicates a successful close from the other + * side of the stream... but if we receive it before a connected cell -- + * that is, before we have sent a SOCKS reply -- that means that the + * other side of the circuit closed the connection before telling us it + * was complete. */ + return SOCKS5_CONNECTION_REFUSED; case END_STREAM_REASON_TIMEOUT: return SOCKS5_TTL_EXPIRED; case END_STREAM_REASON_NOROUTE: diff --git a/src/or/relay.c b/src/or/relay.c index bb3a835442..2701263e5b 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -734,7 +734,11 @@ connection_ap_process_end_not_open( } } - if (rh->length > 0 && edge_reason_is_retriable(reason) && + if (rh->length == 0) { + reason = END_STREAM_REASON_MISC; + } + + if (edge_reason_is_retriable(reason) && /* avoid retry if rend */ !connection_edge_is_rendezvous_stream(edge_conn)) { const char *chosen_exit_digest = From e53e6caac533006245c28657f44e5c929e753336 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 16 Jan 2013 12:52:15 -0500 Subject: [PATCH 2/2] Adjust control_reason when adjusting reason (related to 7902) --- src/or/relay.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/or/relay.c b/src/or/relay.c index 2701263e5b..5ac4fbfeb1 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -710,7 +710,7 @@ connection_ap_process_end_not_open( struct in_addr in; node_t *exitrouter; int reason = *(cell->payload+RELAY_HEADER_SIZE); - int control_reason = reason | END_STREAM_REASON_FLAG_REMOTE; + int control_reason; edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn); (void) layer_hint; /* unused */ @@ -738,6 +738,8 @@ connection_ap_process_end_not_open( reason = END_STREAM_REASON_MISC; } + control_reason = reason | END_STREAM_REASON_FLAG_REMOTE; + if (edge_reason_is_retriable(reason) && /* avoid retry if rend */ !connection_edge_is_rendezvous_stream(edge_conn)) {