Loading changes/prop174_server 0 → 100644 +6 −0 Original line number Diff line number Diff line o Features: - Servers now accept and queue data on not-yet-connected streams. Previously, such data wasn't allowed. This forced clients to wait for a CONNECTED cell before sending their data, thus adding a round trip to stream setup. (Patch from Ian Goldberg; implements the server side of Proposal 174.) src/or/connection.c +16 −3 Original line number Diff line number Diff line Loading @@ -3259,7 +3259,13 @@ _connection_write_to_buf_impl(const char *string, size_t len, return; } /* If we receive optimistic data in the EXIT_CONN_STATE_RESOLVING * state, we don't want to try to write it right away, since * conn->write_event won't be set yet. Otherwise, write data from * this conn as the socket is available. */ if (conn->write_event) { connection_start_writing(conn); } if (zlib) { conn->outbuf_flushlen += buf_datalen(conn->outbuf) - old_datalen; } else { Loading Loading @@ -3837,8 +3843,15 @@ assert_connection_ok(connection_t *conn, time_t now) tor_assert(conn->s < 0); if (conn->outbuf_flushlen > 0) { tor_assert(connection_is_writing(conn) || conn->write_blocked_on_bw || (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->edge_blocked_on_circ)); /* With optimistic data, we may have queued data in * EXIT_CONN_STATE_RESOLVING while the conn is not yet marked to writing. * */ tor_assert((conn->type == CONN_TYPE_EXIT && conn->state == EXIT_CONN_STATE_RESOLVING) || connection_is_writing(conn) || conn->write_blocked_on_bw || (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->edge_blocked_on_circ)); } if (conn->hold_open_until_flushed) Loading src/or/relay.c +25 −4 Original line number Diff line number Diff line Loading @@ -1031,6 +1031,9 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, relay_header_t rh; unsigned domain = layer_hint?LD_APP:LD_EXIT; int reason; int optimistic_data = 0; /* Set to 1 if we receive data on a stream * that's in the EXIT_CONN_STATE_RESOLVING * or EXIT_CONN_STATE_CONNECTING states. */ tor_assert(cell); tor_assert(circ); Loading @@ -1050,9 +1053,20 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, /* either conn is NULL, in which case we've got a control cell, or else * conn points to the recognized stream. */ if (conn && !connection_state_is_open(TO_CONN(conn))) if (conn && !connection_state_is_open(TO_CONN(conn))) { if (conn->_base.type == CONN_TYPE_EXIT && (conn->_base.state == EXIT_CONN_STATE_CONNECTING || conn->_base.state == EXIT_CONN_STATE_RESOLVING) && rh.command == RELAY_COMMAND_DATA) { /* Allow DATA cells to be delivered to an exit node in state * EXIT_CONN_STATE_CONNECTING or EXIT_CONN_STATE_RESOLVING. * This speeds up HTTP, for example. */ optimistic_data = 1; } else { return connection_edge_process_relay_cell_not_open( &rh, cell, circ, conn, layer_hint); } } switch (rh.command) { case RELAY_COMMAND_DROP: Loading Loading @@ -1119,7 +1133,14 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, stats_n_data_bytes_received += rh.length; connection_write_to_buf((char*)(cell->payload + RELAY_HEADER_SIZE), rh.length, TO_CONN(conn)); if (!optimistic_data) { /* Only send a SENDME if we're not getting optimistic data; otherwise * a SENDME could arrive before the CONNECTED. */ connection_edge_consider_sending_sendme(conn); } return 0; case RELAY_COMMAND_END: reason = rh.length > 0 ? Loading Loading
changes/prop174_server 0 → 100644 +6 −0 Original line number Diff line number Diff line o Features: - Servers now accept and queue data on not-yet-connected streams. Previously, such data wasn't allowed. This forced clients to wait for a CONNECTED cell before sending their data, thus adding a round trip to stream setup. (Patch from Ian Goldberg; implements the server side of Proposal 174.)
src/or/connection.c +16 −3 Original line number Diff line number Diff line Loading @@ -3259,7 +3259,13 @@ _connection_write_to_buf_impl(const char *string, size_t len, return; } /* If we receive optimistic data in the EXIT_CONN_STATE_RESOLVING * state, we don't want to try to write it right away, since * conn->write_event won't be set yet. Otherwise, write data from * this conn as the socket is available. */ if (conn->write_event) { connection_start_writing(conn); } if (zlib) { conn->outbuf_flushlen += buf_datalen(conn->outbuf) - old_datalen; } else { Loading Loading @@ -3837,8 +3843,15 @@ assert_connection_ok(connection_t *conn, time_t now) tor_assert(conn->s < 0); if (conn->outbuf_flushlen > 0) { tor_assert(connection_is_writing(conn) || conn->write_blocked_on_bw || (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->edge_blocked_on_circ)); /* With optimistic data, we may have queued data in * EXIT_CONN_STATE_RESOLVING while the conn is not yet marked to writing. * */ tor_assert((conn->type == CONN_TYPE_EXIT && conn->state == EXIT_CONN_STATE_RESOLVING) || connection_is_writing(conn) || conn->write_blocked_on_bw || (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->edge_blocked_on_circ)); } if (conn->hold_open_until_flushed) Loading
src/or/relay.c +25 −4 Original line number Diff line number Diff line Loading @@ -1031,6 +1031,9 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, relay_header_t rh; unsigned domain = layer_hint?LD_APP:LD_EXIT; int reason; int optimistic_data = 0; /* Set to 1 if we receive data on a stream * that's in the EXIT_CONN_STATE_RESOLVING * or EXIT_CONN_STATE_CONNECTING states. */ tor_assert(cell); tor_assert(circ); Loading @@ -1050,9 +1053,20 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, /* either conn is NULL, in which case we've got a control cell, or else * conn points to the recognized stream. */ if (conn && !connection_state_is_open(TO_CONN(conn))) if (conn && !connection_state_is_open(TO_CONN(conn))) { if (conn->_base.type == CONN_TYPE_EXIT && (conn->_base.state == EXIT_CONN_STATE_CONNECTING || conn->_base.state == EXIT_CONN_STATE_RESOLVING) && rh.command == RELAY_COMMAND_DATA) { /* Allow DATA cells to be delivered to an exit node in state * EXIT_CONN_STATE_CONNECTING or EXIT_CONN_STATE_RESOLVING. * This speeds up HTTP, for example. */ optimistic_data = 1; } else { return connection_edge_process_relay_cell_not_open( &rh, cell, circ, conn, layer_hint); } } switch (rh.command) { case RELAY_COMMAND_DROP: Loading Loading @@ -1119,7 +1133,14 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, stats_n_data_bytes_received += rh.length; connection_write_to_buf((char*)(cell->payload + RELAY_HEADER_SIZE), rh.length, TO_CONN(conn)); if (!optimistic_data) { /* Only send a SENDME if we're not getting optimistic data; otherwise * a SENDME could arrive before the CONNECTED. */ connection_edge_consider_sending_sendme(conn); } return 0; case RELAY_COMMAND_END: reason = rh.length > 0 ? Loading