Merge remote-tracking branch 'origin/maint-0.2.4'

This commit is contained in:
Nick Mathewson 2013-04-12 01:14:32 -04:00
commit 63ab5f4849
3 changed files with 24 additions and 1 deletions

5
changes/bug5650 Normal file
View File

@ -0,0 +1,5 @@
o Major bugfixes:
- Avoid a bug where our response to TLS renegotation under certain
network conditions could lead to a busy-loop, with 100% CPU
consumption. Fixes bug 5650; bugfix on 0.2.0.16-alpha.

View File

@ -3065,7 +3065,20 @@ connection_read_to_buf(connection_t *conn, ssize_t *max_to_read,
case TOR_TLS_WANTWRITE: case TOR_TLS_WANTWRITE:
connection_start_writing(conn); connection_start_writing(conn);
return 0; return 0;
case TOR_TLS_WANTREAD: /* we're already reading */ case TOR_TLS_WANTREAD:
if (conn->in_connection_handle_write) {
/* We've been invoked from connection_handle_write, because we're
* waiting for a TLS renegotiation, the renegotiation started, and
* SSL_read returned WANTWRITE. But now SSL_read is saying WANTREAD
* again. Stop waiting for write events now, or else we'll
* busy-loop until data arrives for us to read. */
connection_stop_writing(conn);
if (!connection_is_reading(conn))
connection_start_reading(conn);
}
/* we're already reading, one hopes */
result = 0;
break;
case TOR_TLS_DONE: /* no data read, so nothing to process */ case TOR_TLS_DONE: /* no data read, so nothing to process */
result = 0; result = 0;
break; /* so we call bucket_decrement below */ break; /* so we call bucket_decrement below */
@ -3624,7 +3637,9 @@ connection_handle_write(connection_t *conn, int force)
{ {
int res; int res;
tor_gettimeofday_cache_clear(); tor_gettimeofday_cache_clear();
conn->in_connection_handle_write = 1;
res = connection_handle_write_impl(conn, force); res = connection_handle_write_impl(conn, force);
conn->in_connection_handle_write = 0;
return res; return res;
} }

View File

@ -1165,6 +1165,9 @@ typedef struct connection_t {
/** Set to 1 when we're inside connection_flushed_some to keep us from /** Set to 1 when we're inside connection_flushed_some to keep us from
* calling connection_handle_write() recursively. */ * calling connection_handle_write() recursively. */
unsigned int in_flushed_some:1; unsigned int in_flushed_some:1;
/** True if connection_handle_write is currently running on this connection.
*/
unsigned int in_connection_handle_write:1;
/* For linked connections: /* For linked connections:
*/ */