diff --git a/src/ssl.c b/src/ssl.c index 4ff98f6..b64ceeb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -429,7 +429,7 @@ static int ssl_splicetls(struct clientparam *param, SOCKET s){ struct SSLsock *sslq = searchSSL(param->sostate, s); if(!sslq) return 0; - return ssl_pending(sslq->conn)? SPLICE_TLSPENDING : SPLICE_TLS; + return ssl_buffered(sslq->conn)? SPLICE_TLSPENDING : SPLICE_TLS; } #endif diff --git a/src/ssl.h b/src/ssl.h index 4df3679..32cd19c 100644 --- a/src/ssl.h +++ b/src/ssl.h @@ -78,6 +78,9 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, int ssl_read(SSL_CONN connection, void * buf, int bufsize); int ssl_write(SSL_CONN connection, void * buf, int bufsize); int ssl_pending(SSL_CONN connection); +/* any data read from the socket and not handed out, a part of a record + too */ +int ssl_buffered(SSL_CONN connection); /* TLS records are read ahead, a buffer at a time rather than two reads for each record, where what is read ahead and not yet decrypted shows as diff --git a/src/ssllib.c b/src/ssllib.c index a6be34e..e8e1bae 100644 --- a/src/ssllib.c +++ b/src/ssllib.c @@ -259,6 +259,30 @@ int ssl_write(SSL_CONN connection, void * buf, int bufsize) return SSL_write(conn->ssl, buf, bufsize); } int ssl_pending(SSL_CONN connection) +{ + ssl_conn *conn = (ssl_conn *) connection; +#if SSL_READAHEAD + char c; + int res; + + if(SSL_pending(conn->ssl) > 0) return 1; + if(!SSL_has_pending(conn->ssl)) return 0; + /* Read ahead and not decrypted: a record, or only a part of one. A + part is no data, and saying so would have poll() return at once, + again and again, without its timeout, until the rest came: it is + pending only once the record is whole (or the connection ended), + the socket polled for the rest otherwise. The sockets are not + blocking, so this does not wait. */ + res = SSL_peek(conn->ssl, &c, 1); + if(res > 0) return 1; + res = SSL_get_error(conn->ssl, res); + return res != SSL_ERROR_WANT_READ && res != SSL_ERROR_WANT_WRITE; +#else + return SSL_pending(conn->ssl); +#endif +} + +int ssl_buffered(SSL_CONN connection) { ssl_conn *conn = (ssl_conn *) connection;