[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Fix bug 225: now "attachstream 0" treats conn like it just ...
Update of /home2/or/cvsroot/tor/src/or
In directory moria:/home/arma/work/onion/cvs/tor/src/or
Modified Files:
connection_edge.c control.c or.h
Log Message:
Fix bug 225: now "attachstream 0" treats conn like it just connected,
doing address remapping, handling .exit and .onion idioms, and so on.
Now we are more uniform in making sure that the controller hears about
all new connections, and making sure it hears when they close.
Index: connection_edge.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.378
retrieving revision 1.379
diff -u -p -d -r1.378 -r1.379
--- connection_edge.c 17 Jan 2006 04:16:59 -0000 1.378
+++ connection_edge.c 3 Feb 2006 11:37:18 -0000 1.379
@@ -924,59 +924,20 @@ addressmap_get_mappings(smartlist_t *sl,
}
}
-/** connection_edge_process_inbuf() found a conn in state
- * socks_wait. See if conn->inbuf has the right bytes to proceed with
- * the socks handshake.
- *
- * If the handshake is complete, and it's for a general circuit, then
- * try to attach it to a circuit (or launch one as needed). If it's for
- * a rendezvous circuit, then fetch a rendezvous descriptor first (or
- * attach/launch a circuit if the rendezvous descriptor is already here
- * and fresh enough).
+/* Connection <b>conn</b> just finished its socks handshake, or the
+ * controller asked us to take care of it.
*
- * Return -1 if an unexpected error with conn (and it should be marked
- * for close), else return 0.
+ * First, parse whether it's a .exit address, remap it, and so on. Then
+ * it's for a general circuit, try to attach it to a circuit (or launch
+ * one as needed), else if it's for a rendezvous circuit, fetch a
+ * rendezvous descriptor first (or attach/launch a circuit if the
+ * rendezvous descriptor is already here and fresh enough).
*/
-static int
-connection_ap_handshake_process_socks(connection_t *conn)
+int
+connection_ap_handshake_rewrite_and_attach(connection_t *conn)
{
- socks_request_t *socks;
- int sockshere;
+ socks_request_t *socks = conn->socks_request;
hostname_type_t addresstype;
- or_options_t *options = get_options();
- int tor_should_handle_stream = !options->LeaveStreamsUnattached;
-
- tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_AP);
- tor_assert(conn->state == AP_CONN_STATE_SOCKS_WAIT);
- tor_assert(conn->socks_request);
- socks = conn->socks_request;
-
- debug(LD_APP,"entered.");
-
- sockshere = fetch_from_buf_socks(conn->inbuf, socks, options->TestSocks);
- if (sockshere == 0) {
- if (socks->replylen) {
- connection_write_to_buf(socks->reply, socks->replylen, conn);
- /* zero it out so we can do another round of negotiation */
- socks->replylen = 0;
- } else {
- debug(LD_APP,"socks handshake not all here yet.");
- }
- return 0;
- } else if (sockshere == -1) {
- if (socks->replylen) { /* we should send reply back */
- debug(LD_APP,"reply is already set for us. Using it.");
- connection_ap_handshake_socks_reply(conn, socks->reply, socks->replylen,
- SOCKS5_GENERAL_ERROR);
- } else {
- warn(LD_APP,"Fetching socks handshake failed. Closing.");
- connection_ap_handshake_socks_reply(conn, NULL, 0, SOCKS5_GENERAL_ERROR);
- }
- connection_mark_unattached_ap(conn,
- END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
- return -1;
- } /* else socks handshake is done, continue processing */
tor_strlower(socks->address); /* normalize it */
debug(LD_APP,"Client asked for %s:%d", safe_str(socks->address),
@@ -985,11 +946,10 @@ connection_ap_handshake_process_socks(co
/* For address map controls, remap the address */
addressmap_rewrite(socks->address, sizeof(socks->address));
- if (tor_should_handle_stream &&
- address_is_in_virtual_range(socks->address)) {
+ if (address_is_in_virtual_range(socks->address)) {
/* This address was probably handed out by client_dns_get_unmapped_address,
* but the mapping was discarded for some reason. We *don't* want to send
- * the address through tor; that's likely to fail, and may leak
+ * the address through Tor; that's likely to fail, and may leak
* information.
*/
warn(LD_APP,"Missing mapping for virtual address '%s'. Refusing.",
@@ -1003,7 +963,7 @@ connection_ap_handshake_process_socks(co
*/
addresstype = parse_extended_hostname(socks->address);
- if (tor_should_handle_stream && addresstype == BAD_HOSTNAME) {
+ if (addresstype == BAD_HOSTNAME) {
warn(LD_APP, "Invalid hostname %s; rejecting", socks->address);
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
return -1;
@@ -1033,7 +993,7 @@ connection_ap_handshake_process_socks(co
/* XXXX Should this use server->address instead? */
in.s_addr = htonl(r->addr);
strlcpy(socks->address, inet_ntoa(in), sizeof(socks->address));
- } else if (tor_should_handle_stream) {
+ } else {
warn(LD_APP,
"Unrecognized server in exit address '%s.exit'. Refusing.",
safe_str(socks->address));
@@ -1046,8 +1006,7 @@ connection_ap_handshake_process_socks(co
if (addresstype != ONION_HOSTNAME) {
/* not a hidden-service request (i.e. normal or .exit) */
- if (tor_should_handle_stream &&
- address_is_invalid_destination(socks->address)) {
+ if (address_is_invalid_destination(socks->address)) {
warn(LD_APP,"Destination '%s' seems to be an invalid hostname. Failing.",
safe_str(socks->address));
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
@@ -1075,7 +1034,6 @@ connection_ap_handshake_process_socks(co
return 0;
}
rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
- control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
} else { /* socks->command == SOCKS_COMMAND_CONNECT */
if (socks->port == 0) {
notice(LD_APP,"Application asked to connect to port 0. Refusing.");
@@ -1099,16 +1057,11 @@ connection_ap_handshake_process_socks(co
/* help predict this next time */
rep_hist_note_used_port(socks->port, time(NULL));
- control_event_stream_status(conn, STREAM_EVENT_NEW);
}
- if (!tor_should_handle_stream) {
- conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
- } else {
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
- if (connection_ap_handshake_attach_circuit(conn) < 0) {
- connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
- return -1;
- }
+ conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ if (connection_ap_handshake_attach_circuit(conn) < 0) {
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
+ return -1;
}
return 0;
} else {
@@ -1159,12 +1112,72 @@ connection_ap_handshake_process_socks(co
rend_client_refetch_renddesc(conn->rend_query);
}
}
- control_event_stream_status(conn, STREAM_EVENT_NEW);
return 0;
}
return 0; /* unreached but keeps the compiler happy */
}
+/** connection_edge_process_inbuf() found a conn in state
+ * socks_wait. See if conn->inbuf has the right bytes to proceed with
+ * the socks handshake.
+ *
+ * If the handshake is complete, send it to
+ * connection_ap_handshake_rewrite_and_attach().
+ *
+ * Return -1 if an unexpected error with conn (and it should be marked
+ * for close), else return 0.
+ */
+static int
+connection_ap_handshake_process_socks(connection_t *conn)
+{
+ socks_request_t *socks;
+ int sockshere;
+ or_options_t *options = get_options();
+
+ tor_assert(conn);
+ tor_assert(conn->type == CONN_TYPE_AP);
+ tor_assert(conn->state == AP_CONN_STATE_SOCKS_WAIT);
+ tor_assert(conn->socks_request);
+ socks = conn->socks_request;
+
+ debug(LD_APP,"entered.");
+
+ sockshere = fetch_from_buf_socks(conn->inbuf, socks, options->TestSocks);
+ if (sockshere == 0) {
+ if (socks->replylen) {
+ connection_write_to_buf(socks->reply, socks->replylen, conn);
+ /* zero it out so we can do another round of negotiation */
+ socks->replylen = 0;
+ } else {
+ debug(LD_APP,"socks handshake not all here yet.");
+ }
+ return 0;
+ } else if (sockshere == -1) {
+ if (socks->replylen) { /* we should send reply back */
+ debug(LD_APP,"reply is already set for us. Using it.");
+ connection_ap_handshake_socks_reply(conn, socks->reply, socks->replylen,
+ SOCKS5_GENERAL_ERROR);
+ } else {
+ warn(LD_APP,"Fetching socks handshake failed. Closing.");
+ connection_ap_handshake_socks_reply(conn, NULL, 0, SOCKS5_GENERAL_ERROR);
+ }
+ connection_mark_unattached_ap(conn,
+ END_STREAM_REASON_ALREADY_SOCKS_REPLIED);
+ return -1;
+ } /* else socks handshake is done, continue processing */
+
+ if (socks->command == SOCKS_COMMAND_CONNECT)
+ control_event_stream_status(conn, STREAM_EVENT_NEW);
+ else
+ control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
+
+ if (options->LeaveStreamsUnattached) {
+ conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+ return 0;
+ } else
+ return connection_ap_handshake_rewrite_and_attach(conn);
+}
+
/** Iterate over the two bytes of stream_id until we get one that is not
* already in use; return it. Return 0 if can't get a unique stream_id.
*/
Index: control.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.166
retrieving revision 1.167
diff -u -p -d -r1.166 -r1.167
--- control.c 19 Jan 2006 02:21:24 -0000 1.166
+++ control.c 3 Feb 2006 11:37:18 -0000 1.167
@@ -1744,9 +1744,7 @@ handle_control_attachstream(connection_t
}
if (zero_circ) {
- ap_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
- if (connection_ap_handshake_attach_circuit(ap_conn)<0)
- connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_CANT_ATTACH);
+ connection_ap_handshake_rewrite_and_attach(ap_conn);
send_control_done(conn);
return 0;
}
Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.784
retrieving revision 1.785
diff -u -p -d -r1.784 -r1.785
--- or.h 1 Feb 2006 03:53:52 -0000 1.784
+++ or.h 3 Feb 2006 11:37:19 -0000 1.785
@@ -1732,6 +1732,8 @@ int address_is_in_virtual_range(const ch
const char *addressmap_register_virtual_address(int type, char *new_address);
void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
time_t max_expires);
+int
+connection_ap_handshake_rewrite_and_attach(connection_t *conn);
void parse_socks_policy(void);
void free_socks_policy(void);