]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream: Don't require SSL ostream to always have unlimited buffer size.
authorTimo Sirainen <tss@iki.fi>
Wed, 21 Sep 2011 09:34:02 +0000 (12:34 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 21 Sep 2011 09:34:02 +0000 (12:34 +0300)
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).

src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-openssl.h
src/lib-ssl-iostream/ostream-openssl.c

index 7d16299453ecc3bd7c2d6fb15c6f6174b9427ec7..daf8149e57e45916bc3f35c972dea2844820c530 100644 (file)
@@ -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;
index a77deb4d7b1ad368454acbd27ff3c4a9ad9f3c78..0549a2d83eda92cd25345f7fb535b61f09dbd175 100644 (file)
@@ -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);
index 00dc614113e002c2e2babd9d70f78bc99ad5f7db..25d4b06cec1c87115d347cbc8bee6ef6fa05d61a 100644 (file)
@@ -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;