summaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-07-20 09:50:53 -0400
committerNick Mathewson <nickm@torproject.org>2011-07-20 09:50:53 -0400
commiteaa1c05397c1a6cf2f58b7c41e388311d5aa8ffb (patch)
treeb304aaca9b8d5364517d4ab23ffd232cf420858d /src/or/connection_edge.c
parent195bcb6150eeaebab31a44998e2c567d78f9b936 (diff)
parent9a7c16fb00c6ffc32ef7d6cc7fbede5258fe4390 (diff)
downloadtor-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.c52
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;
}