diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-20 09:50:53 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-20 09:50:53 -0400 |
commit | eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb (patch) | |
tree | b304aaca9b8d5364517d4ab23ffd232cf420858d /src/or/connection_edge.c | |
parent | 195bcb6150eeaebab31a44998e2c567d78f9b936 (diff) | |
parent | 9a7c16fb00c6ffc32ef7d6cc7fbede5258fe4390 (diff) | |
download | tor-eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb.tar.gz tor-eaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb.zip |
Merge branch 'optimistic-client'
The conflicts are with the proposal 171 circuit isolation code, and
they're all trivial: they're just a matter of both branches adding
some unrelated code in the same places.
Conflicts:
src/or/circuituse.c
src/or/connection.c
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r-- | src/or/connection_edge.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 4bbb080124..72394e8777 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -57,6 +57,7 @@ static int connection_exit_connect_dir(edge_connection_t *exitconn); static int address_is_in_virtual_range(const char *addr); static int consider_plaintext_ports(edge_connection_t *conn, uint16_t port); static void clear_trackexithost_mappings(const char *exitname); +static int connection_ap_supports_optimistic_data(const edge_connection_t *); /** An AP stream has failed/finished. If it hasn't already sent back * a socks reply, send one now (based on endreason). Also set @@ -154,10 +155,25 @@ connection_edge_process_inbuf(edge_connection_t *conn, int package_partial) return -1; } return 0; + case AP_CONN_STATE_CONNECT_WAIT: + if (connection_ap_supports_optimistic_data(conn)) { + log_info(LD_EDGE, + "data from edge while in '%s' state. Sending it anyway. " + "package_partial=%d, buflen=%ld", + conn_state_to_string(conn->_base.type, conn->_base.state), + package_partial, connection_get_inbuf_len(TO_CONN(conn))); + if (connection_edge_package_raw_inbuf(conn, package_partial, NULL)<0) { + /* (We already sent an end cell if possible) */ + connection_mark_for_close(TO_CONN(conn)); + return -1; + } + return 0; + } + /* Fall through if the connection is on a circuit without optimistic + * data support. */ case EXIT_CONN_STATE_CONNECTING: case AP_CONN_STATE_RENDDESC_WAIT: case AP_CONN_STATE_CIRCUIT_WAIT: - case AP_CONN_STATE_CONNECT_WAIT: case AP_CONN_STATE_RESOLVE_WAIT: case AP_CONN_STATE_CONTROLLER_WAIT: log_info(LD_EDGE, @@ -722,6 +738,12 @@ connection_ap_detach_retriable(edge_connection_t *conn, origin_circuit_t *circ, { control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE, reason); conn->_base.timestamp_lastread = time(NULL); + + if (conn->pending_optimistic_data) { + generic_buffer_set_to_copy(&conn->sending_optimistic_data, + conn->pending_optimistic_data); + } + if (!get_options()->LeaveStreamsUnattached || conn->use_begindir) { /* If we're attaching streams ourself, or if this connection is * a tunneled directory connection, then just attach it. */ @@ -2337,6 +2359,22 @@ get_unique_stream_id_by_circ(origin_circuit_t *circ) return test_stream_id; } +/** Return true iff <b>conn</b> is linked to a circuit and configured to use + * an exit that supports optimistic data. */ +static int +connection_ap_supports_optimistic_data(const edge_connection_t *conn) +{ + tor_assert(conn->_base.type == CONN_TYPE_AP); + /* We can only send optimistic data if we're connected to an open + general circuit. */ + if (conn->on_circuit == NULL || + conn->on_circuit->state != CIRCUIT_STATE_OPEN || + conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_GENERAL) + return 0; + + return conn->exit_allows_optimistic_data; +} + /** Write a relay begin cell, using destaddr and destport from ap_conn's * socks_request field, and send it down circ. * @@ -2398,6 +2436,18 @@ connection_ap_handshake_send_begin(edge_connection_t *ap_conn) log_info(LD_APP,"Address/port sent, ap socket %d, n_circ_id %d", ap_conn->_base.s, circ->_base.n_circ_id); control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT, 0); + + /* If there's queued-up data, send it now */ + if ((connection_get_inbuf_len(TO_CONN(ap_conn)) || + ap_conn->sending_optimistic_data) && + connection_ap_supports_optimistic_data(ap_conn)) { + log_info(LD_APP, "Sending up to %ld bytes of queued-up data", + connection_get_inbuf_len(TO_CONN(ap_conn))); + if (connection_edge_package_raw_inbuf(ap_conn, 1, NULL) < 0) { + connection_mark_for_close(TO_CONN(ap_conn)); + } + } + return 0; } |