Mercurial > dovecot > core-2.2
changeset 13527:b97c53c54f72
lib-ssl-iostream: Don't require SSL ostream to always have unlimited buffer size.
It's important when reading/handshaking wants to write to output buffer, but
writing itself can safely have zero sized buffer (e.g. while sending a
large input stream).
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 21 Sep 2011 12:34:02 +0300 |
parents | d174fa047d56 |
children | 1d8009c7b67e |
files | src/lib-ssl-iostream/iostream-openssl.c src/lib-ssl-iostream/iostream-openssl.h src/lib-ssl-iostream/ostream-openssl.c |
diffstat | 3 files changed, 27 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-ssl-iostream/iostream-openssl.c Tue Sep 20 16:44:32 2011 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Wed Sep 21 12:34:02 2011 +0300 @@ -372,8 +372,9 @@ ssl_io->last_error = i_strdup(str); } -int ssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, - const char *func_name) +static int +ssl_iostream_handle_error_full(struct ssl_iostream *ssl_io, int ret, + const char *func_name, bool write_error) { const char *errstr = NULL; int err; @@ -382,7 +383,8 @@ switch (err) { case SSL_ERROR_WANT_WRITE: if (!ssl_iostream_bio_sync(ssl_io)) { - i_panic("SSL ostream buffer size not unlimited"); + if (!write_error) + i_panic("SSL ostream buffer size not unlimited"); return 0; } if (ssl_io->closed) { @@ -435,6 +437,18 @@ return -1; } +int ssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, + const char *func_name) +{ + return ssl_iostream_handle_error_full(ssl_io, ret, func_name, FALSE); +} + +int ssl_iostream_handle_write_error(struct ssl_iostream *ssl_io, int ret, + const char *func_name) +{ + return ssl_iostream_handle_error_full(ssl_io, ret, func_name, TRUE); +} + static const char *asn1_string_to_c(ASN1_STRING *asn_str) { const char *cstr;
--- a/src/lib-ssl-iostream/iostream-openssl.h Tue Sep 20 16:44:32 2011 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.h Wed Sep 21 12:34:02 2011 +0300 @@ -74,6 +74,8 @@ read/written, -1 if a fatal error occurred (errno is set). */ int ssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, const char *func_name); +int ssl_iostream_handle_write_error(struct ssl_iostream *ssl_io, int ret, + const char *func_name); const char *ssl_iostream_error(void); const char *ssl_iostream_key_load_error(void);
--- a/src/lib-ssl-iostream/ostream-openssl.c Tue Sep 20 16:44:32 2011 +0300 +++ b/src/lib-ssl-iostream/ostream-openssl.c Wed Sep 21 12:34:02 2011 +0300 @@ -56,6 +56,9 @@ if (size != iov[i].iov_len) i = iov_count; } + if (avail > 0) + o_stream_set_flush_pending(sstream->ssl_io->plain_output, TRUE); + for (; i < iov_count; i++) { size = I_MIN(iov[i].iov_len, avail); buffer_append(sstream->buffer, iov[i].iov_base, size); @@ -83,16 +86,14 @@ CONST_PTR_OFFSET(sstream->buffer->data, pos), sstream->buffer->used - pos); if (ret <= 0) { - ret = ssl_iostream_handle_error(sstream->ssl_io, ret, - "SSL_write"); + ret = ssl_iostream_handle_write_error(sstream->ssl_io, + ret, "SSL_write"); if (ret < 0) { sstream->ostream.ostream.stream_errno = errno; break; } - if (ret == 0) { - /* bio_int's buffer is full */ + if (ret == 0) break; - } } else { pos += ret; (void)ssl_iostream_bio_sync(sstream->ssl_io); @@ -139,8 +140,8 @@ CONST_PTR_OFFSET(iov[i].iov_base, pos), iov[i].iov_len - pos); if (ret <= 0) { - ret = ssl_iostream_handle_error(sstream->ssl_io, ret, - "SSL_write"); + ret = ssl_iostream_handle_write_error(sstream->ssl_io, + ret, "SSL_write"); if (ret < 0) { sstream->ostream.ostream.stream_errno = errno; break;