diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/tortls.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c index 6773639e21..e4e7f7ae67 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -759,6 +759,12 @@ tor_tls_new(int sock, int isServer) result->state = TOR_TLS_ST_HANDSHAKE; result->isServer = isServer; result->wantwrite_n = 0; + result->last_write_count = BIO_number_written(bio); + result->last_read_count = BIO_number_read(bio); + if (result->last_write_count || result->last_read_count) { + log_warn(LD_NET, "Newly created BIO has read count %lu, write count %lu", + result->last_read_count, result->last_write_count); + } #ifdef V2_HANDSHAKE_SERVER if (isServer) { SSL_set_info_callback(result->ssl, tor_tls_server_info_callback); @@ -1278,18 +1284,33 @@ tor_tls_get_forced_write_size(tor_tls_t *tls) void tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written) { + BIO *wbio, *tmpbio; unsigned long r, w; r = BIO_number_read(SSL_get_rbio(tls->ssl)); - w = BIO_number_written(SSL_get_wbio(tls->ssl)); + /* We want the number of bytes actually for real written. Unfortunately, + * sometimes OpenSSL replaces the wbio on tls->ssl with a buffering bio, + * which makes the answer turn out wrong. Let's cope with that. Note + * that this approach will fail if we ever replace tls->ssl's BIOs with + * buffering bios for reasons of our own. As an alternative, we could + * save the original BIO for tls->ssl in the tor_tls_t structure, but + * that would be tempting fate. */ + wbio = SSL_get_wbio(tls->ssl); + if (wbio->method == BIO_f_buffer() && (tmpbio = BIO_next(wbio)) != NULL) + wbio = tmpbio; + w = BIO_number_written(wbio); /* We are ok with letting these unsigned ints go "negative" here: * If we wrapped around, this should still give us the right answer, unless * we wrapped around by more than ULONG_MAX since the last time we called * this function. */ - *n_read = (size_t)(r - tls->last_read_count); *n_written = (size_t)(w - tls->last_write_count); + if (*n_read > INT_MAX || *n_written > INT_MAX) { + log_warn(LD_BUG, "Preposterously large value in tor_tls_get_n_raw_bytes. " + "r=%lu, last_read=%lu, w=%lu, last_written=%lu", + r, tls->last_read_count, w, tls->last_write_count); + } tls->last_read_count = r; tls->last_write_count = w; } |