mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-03 17:13:33 +01:00
Merge remote-tracking branch 'public/bug7708_023_v3_squashed'
This commit is contained in:
commit
c93f66b103
5
changes/bug7708
Normal file
5
changes/bug7708
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
o Major bugfixes:
|
||||||
|
- When a TLS write is partially successful but incomplete, remember
|
||||||
|
that the flushed part has been flushed, and notice that bytes were
|
||||||
|
actually written. Reported and fixed pseudonymously. Fixes bug
|
||||||
|
7708; bugfix on Tor 0.1.0.5-rc.
|
@ -3276,6 +3276,7 @@ connection_handle_write_impl(connection_t *conn, int force)
|
|||||||
ssize_t max_to_write;
|
ssize_t max_to_write;
|
||||||
time_t now = approx_time();
|
time_t now = approx_time();
|
||||||
size_t n_read = 0, n_written = 0;
|
size_t n_read = 0, n_written = 0;
|
||||||
|
int dont_stop_writing = 0;
|
||||||
|
|
||||||
tor_assert(!connection_is_listener(conn));
|
tor_assert(!connection_is_listener(conn));
|
||||||
|
|
||||||
@ -3332,6 +3333,7 @@ connection_handle_write_impl(connection_t *conn, int force)
|
|||||||
if (connection_speaks_cells(conn) &&
|
if (connection_speaks_cells(conn) &&
|
||||||
conn->state > OR_CONN_STATE_PROXY_HANDSHAKING) {
|
conn->state > OR_CONN_STATE_PROXY_HANDSHAKING) {
|
||||||
or_connection_t *or_conn = TO_OR_CONN(conn);
|
or_connection_t *or_conn = TO_OR_CONN(conn);
|
||||||
|
size_t initial_size;
|
||||||
if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
|
if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
|
||||||
conn->state == OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING) {
|
conn->state == OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING) {
|
||||||
connection_stop_writing(conn);
|
connection_stop_writing(conn);
|
||||||
@ -3355,6 +3357,7 @@ connection_handle_write_impl(connection_t *conn, int force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* else open, or closing */
|
/* else open, or closing */
|
||||||
|
initial_size = buf_datalen(conn->outbuf);
|
||||||
result = flush_buf_tls(or_conn->tls, conn->outbuf,
|
result = flush_buf_tls(or_conn->tls, conn->outbuf,
|
||||||
max_to_write, &conn->outbuf_flushlen);
|
max_to_write, &conn->outbuf_flushlen);
|
||||||
|
|
||||||
@ -3385,7 +3388,8 @@ connection_handle_write_impl(connection_t *conn, int force)
|
|||||||
case TOR_TLS_WANTWRITE:
|
case TOR_TLS_WANTWRITE:
|
||||||
log_debug(LD_NET,"wanted write.");
|
log_debug(LD_NET,"wanted write.");
|
||||||
/* we're already writing */
|
/* we're already writing */
|
||||||
return 0;
|
dont_stop_writing = 1;
|
||||||
|
break;
|
||||||
case TOR_TLS_WANTREAD:
|
case TOR_TLS_WANTREAD:
|
||||||
/* Make sure to avoid a loop if the receive buckets are empty. */
|
/* Make sure to avoid a loop if the receive buckets are empty. */
|
||||||
log_debug(LD_NET,"wanted read.");
|
log_debug(LD_NET,"wanted read.");
|
||||||
@ -3407,6 +3411,12 @@ connection_handle_write_impl(connection_t *conn, int force)
|
|||||||
tor_tls_get_n_raw_bytes(or_conn->tls, &n_read, &n_written);
|
tor_tls_get_n_raw_bytes(or_conn->tls, &n_read, &n_written);
|
||||||
log_debug(LD_GENERAL, "After TLS write of %d: %ld read, %ld written",
|
log_debug(LD_GENERAL, "After TLS write of %d: %ld read, %ld written",
|
||||||
result, (long)n_read, (long)n_written);
|
result, (long)n_read, (long)n_written);
|
||||||
|
/* So we notice bytes were written even on error */
|
||||||
|
/* XXXX024 This cast is safe since we can never write INT_MAX bytes in a
|
||||||
|
* single set of TLS operations. But it looks kinda ugly. If we refactor
|
||||||
|
* the *_buf_tls functions, we should make them return ssize_t or size_t
|
||||||
|
* or something. */
|
||||||
|
result = (int)(initial_size-buf_datalen(conn->outbuf));
|
||||||
} else {
|
} else {
|
||||||
CONN_LOG_PROTECT(conn,
|
CONN_LOG_PROTECT(conn,
|
||||||
result = flush_buf(conn->s, conn->outbuf,
|
result = flush_buf(conn->s, conn->outbuf,
|
||||||
@ -3453,7 +3463,8 @@ connection_handle_write_impl(connection_t *conn, int force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connection_wants_to_flush(conn)) { /* it's done flushing */
|
if (!connection_wants_to_flush(conn) &&
|
||||||
|
!dont_stop_writing) { /* it's done flushing */
|
||||||
if (connection_finished_flushing(conn) < 0) {
|
if (connection_finished_flushing(conn) < 0) {
|
||||||
/* already marked */
|
/* already marked */
|
||||||
return -1;
|
return -1;
|
||||||
@ -3981,8 +3992,9 @@ connection_flushed_some(connection_t *conn)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** We just finished flushing bytes from conn-\>outbuf, and there
|
/** We just finished flushing bytes to the appropriately low network layer,
|
||||||
* are no more bytes remaining.
|
* and there are no more bytes remaining in conn-\>outbuf, conn-\>bev, or
|
||||||
|
* conn-\>tls to be flushed.
|
||||||
*
|
*
|
||||||
* This function just passes conn to the connection-specific
|
* This function just passes conn to the connection-specific
|
||||||
* connection_*_finished_flushing() function.
|
* connection_*_finished_flushing() function.
|
||||||
|
Loading…
Reference in New Issue
Block a user