From: Timo Sirainen Date: Wed, 21 Sep 2011 09:34:02 +0000 (+0300) Subject: lib-ssl-iostream: Don't require SSL ostream to always have unlimited buffer size. X-Git-Tag: 2.1.beta1~152 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed41ec8aa0efaa50954fd16cb44c86c8350dadcc;p=thirdparty%2Fdovecot%2Fcore.git 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). --- diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c index 7d16299453..daf8149e57 100644 --- a/src/lib-ssl-iostream/iostream-openssl.c +++ b/src/lib-ssl-iostream/iostream-openssl.c @@ -372,8 +372,9 @@ static void ssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str) 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 @@ int ssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, 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 @@ int ssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret, 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; diff --git a/src/lib-ssl-iostream/iostream-openssl.h b/src/lib-ssl-iostream/iostream-openssl.h index a77deb4d7b..0549a2d83e 100644 --- a/src/lib-ssl-iostream/iostream-openssl.h +++ b/src/lib-ssl-iostream/iostream-openssl.h @@ -74,6 +74,8 @@ int ssl_iostream_more(struct ssl_iostream *ssl_io); 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); diff --git a/src/lib-ssl-iostream/ostream-openssl.c b/src/lib-ssl-iostream/ostream-openssl.c index 00dc614113..25d4b06cec 100644 --- a/src/lib-ssl-iostream/ostream-openssl.c +++ b/src/lib-ssl-iostream/ostream-openssl.c @@ -56,6 +56,9 @@ o_stream_ssl_buffer(struct ssl_ostream *sstream, const struct const_iovec *iov, 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 @@ static int o_stream_ssl_flush_buffer(struct ssl_ostream *sstream) 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 @@ o_stream_ssl_sendv_try(struct ssl_ostream *sstream, 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;