[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] stop most cases of hanging up on a socks connection without...
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] stop most cases of hanging up on a socks connection without...
- From: arma@xxxxxxxx (Roger Dingledine)
- Date: Sat, 26 Mar 2005 23:55:16 -0500 (EST)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Sat, 26 Mar 2005 23:55:54 -0500
- Reply-to: or-dev@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Update of /home2/or/cvsroot/tor/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/tor/src/or
Modified Files:
circuitbuild.c connection.c connection_edge.c control.c
hibernate.c main.c or.h relay.c rendclient.c
Log Message:
stop most cases of hanging up on a socks connection without sending
the socks reject. audit for remaining ones. also make things more
uniform so we always remember to hold-open-until-flushed, etc.
Index: circuitbuild.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.95
retrieving revision 1.96
diff -u -d -r1.95 -r1.96
--- circuitbuild.c 26 Mar 2005 05:54:50 -0000 1.95
+++ circuitbuild.c 27 Mar 2005 04:55:12 -0000 1.96
@@ -722,8 +722,7 @@
/* no need to send 'end' relay cells,
* because the other side's already dead
*/
- stream->has_sent_end = 1;
- connection_mark_for_close(stream);
+ connection_close_unattached_ap(stream, END_STREAM_REASON_DESTROY);
}
}
Index: connection.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.348
retrieving revision 1.349
diff -u -d -r1.348 -r1.349
--- connection.c 26 Mar 2005 01:43:39 -0000 1.348
+++ connection.c 27 Mar 2005 04:55:12 -0000 1.349
@@ -281,7 +281,8 @@
if (conn->socks_request->has_finished == 0) {
/* since conn gets removed right after this function finishes,
* there's no point trying to send back a reply at this point. */
- log_fn(LOG_WARN,"Bug: Closing stream without sending back a socks reply.");
+ log_fn(LOG_WARN,"Bug: Closing stream (marked at %s:%d) without sending back a socks reply.",
+ conn->marked_for_close_file, conn->marked_for_close);
} else {
control_event_stream_status(conn, STREAM_EVENT_CLOSED);
}
Index: connection_edge.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.307
retrieving revision 1.308
diff -u -d -r1.307 -r1.308
--- connection_edge.c 26 Mar 2005 06:27:51 -0000 1.307
+++ connection_edge.c 27 Mar 2005 04:55:12 -0000 1.308
@@ -20,6 +20,26 @@
static int connection_ap_handshake_process_socks(connection_t *conn);
static int address_is_in_virtual_range(const char *addr);
+/** An AP stream has failed/finished. If it hasn't already sent back
+ * a socks reply, send one now (based on endreason). Also set
+ * has_sent_end to 1, and mark the conn.
+ */
+void
+connection_close_unattached_ap(connection_t *conn, int endreason) {
+ tor_assert(conn->type == CONN_TYPE_AP);
+ conn->has_sent_end = 1; /* no circ yet */
+ if (!conn->socks_request->has_finished) {
+ socks5_reply_status_t socksreason =
+ connection_edge_end_reason_socks5_response(endreason);
+ if (conn->socks_request->command == SOCKS_COMMAND_CONNECT)
+ connection_ap_handshake_socks_reply(conn, NULL, 0, socksreason);
+ else
+ connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL);
+ }
+ connection_mark_for_close(conn);
+ conn->hold_open_until_flushed = 1;
+}
+
/** There was an EOF. Send an end and mark the connection for close.
*/
int connection_edge_reached_eof(connection_t *conn) {
@@ -45,9 +65,9 @@
/* only mark it if not already marked. it's possible to
* get the 'end' right around when the client hangs up on us. */
connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
+ if (conn->socks_request) /* eof, so don't send a socks reply back */
+ conn->socks_request->has_finished = 1;
connection_mark_for_close(conn);
-// conn->hold_open_until_flushed = 1; /* just because we shouldn't read
-// doesn't mean we shouldn't write */
}
return 0;
#endif
@@ -70,9 +90,7 @@
switch (conn->state) {
case AP_CONN_STATE_SOCKS_WAIT:
if (connection_ap_handshake_process_socks(conn) < 0) {
- conn->has_sent_end = 1; /* no circ yet */
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1; /* redundant but shouldn't hurt */
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
return -1;
}
return 0;
@@ -113,9 +131,13 @@
return 0; /* already marked; probably got an 'end' */
log_fn(LOG_INFO,"CircID %d: At an edge. Marking connection for close.",
circ_id);
- conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
+ if (conn->type == CONN_TYPE_AP) {
+ connection_close_unattached_ap(conn, END_STREAM_REASON_DESTROY);
+ } else {
+ conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */
+ connection_mark_for_close(conn);
+ conn->hold_open_until_flushed = 1;
+ }
conn->cpath_layer = NULL;
return 0;
}
@@ -280,7 +302,7 @@
if (conn->state == AP_CONN_STATE_CONTROLLER_WAIT) {
if (now - conn->timestamp_lastread >= 120) {
log_fn(LOG_NOTICE, "Closing unattached stream.");
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
}
continue;
}
@@ -294,8 +316,7 @@
if (!circ) { /* it's vanished? */
log_fn(LOG_INFO,"Conn is waiting (address %s), but lost its circ.",
conn->socks_request->address);
- conn->has_sent_end = 1; /* No circuit to receive end cell. */
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
continue;
}
if (circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
@@ -303,7 +324,7 @@
log_fn(LOG_NOTICE,"Rend stream is %d seconds late. Giving up on address '%s'.",
(int)(now - conn->timestamp_lastread), conn->socks_request->address);
connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
}
continue;
}
@@ -324,10 +345,7 @@
conn->timestamp_lastread += 15;
/* move it back into 'pending' state, and try to attach. */
if (connection_ap_detach_retriable(conn, circ)<0) {
- /* it will never work */
- /* Don't need to send end -- we're not connected */
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_MISC);
}
} /* end for */
}
@@ -350,10 +368,7 @@
conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
continue;
if (connection_ap_handshake_attach_circuit(conn) < 0) {
- /* -1 means it will never work */
- /* Don't send end; there is no 'other side' yet */
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_MISC);
}
}
}
@@ -911,9 +926,7 @@
answer = in.s_addr;
connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
(char*)&answer);
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
+ connection_close_unattached_ap(conn, END_STREAM_REASON_DONE);
return 0;
}
rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
@@ -1016,9 +1029,7 @@
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
if (ap_conn->stream_id==0) {
- /* Don't send end: there is no 'other side' yet */
- ap_conn->has_sent_end = 1;
- connection_mark_for_close(ap_conn);
+ connection_close_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
circuit_mark_for_close(circ);
return -1;
}
@@ -1038,7 +1049,8 @@
ap_conn->package_window = STREAMWINDOW_START;
ap_conn->deliver_window = STREAMWINDOW_START;
ap_conn->state = AP_CONN_STATE_CONNECT_WAIT;
- log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
+ log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_circ_id %d",
+ ap_conn->s, circ->n_circ_id);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT);
return 0;
}
@@ -1061,9 +1073,7 @@
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
if (ap_conn->stream_id==0) {
- /* Don't send end: there is no 'other side' yet */
- ap_conn->has_sent_end = 1;
- connection_mark_for_close(ap_conn);
+ connection_close_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
circuit_mark_for_close(circ);
return -1;
}
@@ -1079,7 +1089,8 @@
return -1; /* circuit is closed, don't continue */
ap_conn->state = AP_CONN_STATE_RESOLVE_WAIT;
- log_fn(LOG_INFO,"Address sent for resolve, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
+ log_fn(LOG_INFO,"Address sent for resolve, ap socket %d, n_circ_id %d",
+ ap_conn->s, circ->n_circ_id);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE);
return 0;
}
@@ -1133,8 +1144,7 @@
/* attaching to a dirty circuit is fine */
if (connection_ap_handshake_attach_circuit(conn) < 0) {
- conn->has_sent_end = 1; /* no circ to send to */
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_MISC);
tor_close_socket(fd[1]);
return -1;
}
@@ -1202,7 +1212,6 @@
(answer_type == RESOLVED_TYPE_IPV4 ||
answer_type == RESOLVED_TYPE_IPV6) ?
SOCKS5_SUCCEEDED : SOCKS5_HOST_UNREACHABLE);
- conn->socks_request->has_finished = 1;
}
/** Send a socks reply to stream <b>conn</b>, using the appropriate
Index: control.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- control.c 24 Mar 2005 06:28:21 -0000 1.68
+++ control.c 27 Mar 2005 04:55:12 -0000 1.69
@@ -736,7 +736,7 @@
if (!circ_id) {
ap_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
if (connection_ap_handshake_attach_circuit(ap_conn)<0)
- connection_mark_for_close(ap_conn);
+ connection_close_unattached_ap(ap_conn, END_STREAM_REASON_MISC);
send_control_done(conn);
return 0;
}
@@ -802,7 +802,6 @@
uint32_t conn_id;
connection_t *ap_conn;
uint8_t reason;
- int hold_open;
if (len < 6) {
send_control_error(conn, ERR_SYNTAX, "closestream message too short");
@@ -811,7 +810,6 @@
conn_id = ntohl(get_uint32(body));
reason = *(uint8_t*)(body+4);
- hold_open = (*(uint8_t*)(body+5)) & 1;
if (!(ap_conn = connection_get_by_global_id(conn_id))
|| ap_conn->state != CONN_TYPE_AP
@@ -820,19 +818,11 @@
"No AP connection found with given ID");
return 0;
}
-
- if (!ap_conn->socks_request->has_finished) {
- socks5_reply_status_t status =
- connection_edge_end_reason_socks5_response(reason);
- connection_ap_handshake_socks_reply(ap_conn, NULL, 0, status);
- }
- if (hold_open)
- ap_conn->hold_open_until_flushed = 1;
- connection_mark_for_close(ap_conn);
-
+ connection_close_unattached_ap(ap_conn, reason);
send_control_done(conn);
return 0;
}
+
static int
handle_control_closecircuit(connection_t *conn, uint32_t len,
const char *body)
Index: hibernate.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/hibernate.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- hibernate.c 12 Mar 2005 20:13:38 -0000 1.48
+++ hibernate.c 27 Mar 2005 04:55:12 -0000 1.49
@@ -741,7 +741,10 @@
connection_edge_end(conn, END_STREAM_REASON_HIBERNATING,
conn->cpath_layer);
log_fn(LOG_INFO,"Closing conn type %d", conn->type);
- connection_mark_for_close(conn);
+ if (conn->type == CONN_TYPE_AP) /* send socks failure if needed */
+ connection_close_unattached_ap(conn, END_STREAM_REASON_HIBERNATING);
+ else
+ connection_mark_for_close(conn);
}
accounting_record_bandwidth_usage(now);
Index: main.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.473
retrieving revision 1.474
diff -u -d -r1.473 -r1.474
--- main.c 26 Mar 2005 05:54:50 -0000 1.473
+++ main.c 27 Mar 2005 04:55:12 -0000 1.474
@@ -476,11 +476,10 @@
while ((conn = connection_get_by_type_state(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT))) {
- conn->has_sent_end = 1; /* it's not connected anywhere, so no need to end */
log_fn(LOG_NOTICE,"Network down? Failing connection to '%s:%d'.",
conn->socks_request->address, conn->socks_request->port);
- connection_ap_handshake_socks_reply(conn, NULL, 0, SOCKS5_NET_UNREACHABLE);
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
+// XXX should maybe reflect SOCKS5_NET_UNREACHABLE here. what reason is that?
}
}
@@ -589,14 +588,14 @@
conn->hold_open_until_flushed = 1;
} else if (!clique_mode(options) && !circuit_get_by_conn(conn) &&
(!router || !server_mode(options) || !router_is_clique_mode(router))) {
- log_fn(LOG_INFO,"Expiring non-used connection to %d (%s:%d) [Not in clique mode].",
+ log_fn(LOG_INFO,"Expiring non-used OR connection to %d (%s:%d) [Not in clique mode].",
i,conn->address, conn->port);
connection_mark_for_close(conn);
conn->hold_open_until_flushed = 1;
} else if (
now >= conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {
- log_fn(LOG_NOTICE,"Expiring stuck connection to %d (%s:%d). (%d bytes to flush; %d seconds since last write)",
+ log_fn(LOG_NOTICE,"Expiring stuck OR connection to %d (%s:%d). (%d bytes to flush; %d seconds since last write)",
i, conn->address, conn->port,
(int)buf_datalen(conn->outbuf),
(int)(now-conn->timestamp_lastwritten));
Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.573
retrieving revision 1.574
diff -u -d -r1.573 -r1.574
--- or.h 26 Mar 2005 01:43:39 -0000 1.573
+++ or.h 27 Mar 2005 04:55:12 -0000 1.574
@@ -1308,6 +1308,7 @@
/********************************* connection_edge.c ***************************/
+void connection_close_unattached_ap(connection_t *conn, int endreason);
int connection_edge_reached_eof(connection_t *conn);
int connection_edge_process_inbuf(connection_t *conn, int package_partial);
int connection_edge_destroy(uint16_t circ_id, connection_t *conn);
Index: relay.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/relay.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- relay.c 26 Mar 2005 06:27:04 -0000 1.56
+++ relay.c 27 Mar 2005 04:55:13 -0000 1.57
@@ -416,8 +416,12 @@
if (!circ) {
log_fn(LOG_WARN,"no circ. Closing conn.");
tor_assert(fromconn);
- fromconn->has_sent_end = 1; /* no circ to send to */
- connection_mark_for_close(fromconn);
+ if (fromconn->type == CONN_TYPE_AP) {
+ connection_close_unattached_ap(fromconn, END_STREAM_REASON_INTERNAL);
+ } else {
+ fromconn->has_sent_end = 1; /* no circ to send to */
+ connection_mark_for_close(fromconn);
+ }
return -1;
}
@@ -496,13 +500,13 @@
case END_STREAM_REASON_CONNECTREFUSED:
return SOCKS5_CONNECTION_REFUSED;
case END_STREAM_REASON_EXITPOLICY:
- return SOCKS5_CONNECTION_REFUSED;
+ return SOCKS5_CONNECTION_REFUSED; // XXX should be SOCKS5_NOT_ALLOWED ?
case END_STREAM_REASON_DESTROY:
return SOCKS5_GENERAL_ERROR;
case END_STREAM_REASON_DONE:
return SOCKS5_SUCCEEDED;
case END_STREAM_REASON_TIMEOUT:
- return SOCKS5_TTL_EXPIRED;
+ return SOCKS5_TTL_EXPIRED; // XXX is this correct?
case END_STREAM_REASON_RESOURCELIMIT:
return SOCKS5_GENERAL_ERROR;
case END_STREAM_REASON_HIBERNATING:
@@ -603,8 +607,7 @@
} else {
log_fn(LOG_INFO,"Address '%s' resolved to 0.0.0.0. Closing,",
conn->socks_request->address);
- conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return 0;
}
client_dns_set_addressmap(conn->socks_request->address, addr,
@@ -658,12 +661,13 @@
rh->length));
if (CIRCUIT_IS_ORIGIN(circ))
circuit_log_path(LOG_INFO,circ);
- conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
- if (conn->type == CONN_TYPE_AP)
- connection_ap_handshake_socks_reply(conn, NULL, 0,
- connection_edge_end_reason_socks5_response(*(char *)
- (cell->payload+RELAY_HEADER_SIZE)));
- connection_mark_for_close(conn);
+ if (conn->type == CONN_TYPE_AP) {
+ connection_close_unattached_ap(conn,
+ *(char *)(cell->payload+RELAY_HEADER_SIZE));
+ } else {
+ conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
+ connection_mark_for_close(conn);
+ }
return 0;
}
@@ -681,7 +685,7 @@
if (!addr) {
log_fn(LOG_INFO,"...but it claims the IP address was 0.0.0.0. Closing.");
connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL, conn->cpath_layer);
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return 0;
}
client_dns_set_addressmap(conn->socks_request->address, addr,
@@ -705,17 +709,14 @@
tor_assert(conn->socks_request->command == SOCKS_COMMAND_RESOLVE);
if (rh->length < 2 || cell->payload[RELAY_HEADER_SIZE+1]+2>rh->length) {
log_fn(LOG_WARN, "Dropping malformed 'resolved' cell");
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return 0;
}
connection_ap_handshake_socks_resolved(conn,
cell->payload[RELAY_HEADER_SIZE], /*answer_type*/
cell->payload[RELAY_HEADER_SIZE+1], /*answer_len*/
cell->payload+RELAY_HEADER_SIZE+2); /* answer */
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
+ connection_close_unattached_ap(conn, END_STREAM_REASON_DONE);
return 0;
}
Index: rendclient.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/rendclient.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- rendclient.c 23 Mar 2005 06:21:48 -0000 1.79
+++ rendclient.c 27 Mar 2005 04:55:13 -0000 1.80
@@ -394,14 +394,12 @@
if (connection_ap_handshake_attach_circuit(conn) < 0) {
/* it will never work */
log_fn(LOG_WARN,"attaching to a rend circ failed. Closing conn.");
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_MISC);
}
tor_assert(conn->state != AP_CONN_STATE_RENDDESC_WAIT); /* avoid loop */
} else { /* 404, or fetch didn't get that far */
log_fn(LOG_NOTICE,"Closing stream for '%s.onion': hidden service is unavailable (try again later).", query);
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
+ connection_close_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
}
}
}