|
@@ -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;
|
|
|
}
|