diff options
-rw-r--r-- | source4/lib/tls/tls_tstream.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 4086fd96a5..e1137571a5 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -50,7 +50,7 @@ struct tstream_tls { struct tevent_immediate *retry_im; struct { - uint8_t buffer[4096]; + uint8_t *buf; off_t ofs; struct iovec iov; struct tevent_req *subreq; @@ -153,6 +153,7 @@ static ssize_t tstream_tls_push_function(gnutls_transport_ptr ptr, struct tstream_tls *tlss = tstream_context_data(stream, struct tstream_tls); + uint8_t *nbuf; size_t len; if (tlss->error != 0) { @@ -165,13 +166,26 @@ static ssize_t tstream_tls_push_function(gnutls_transport_ptr ptr, return -1; } - if (tlss->push.ofs == sizeof(tlss->push.buffer)) { + len = MIN(size, UINT16_MAX - tlss->push.ofs); + + if (len == 0) { errno = EAGAIN; return -1; } - len = MIN(size, sizeof(tlss->push.buffer) - tlss->push.ofs); - memcpy(tlss->push.buffer + tlss->push.ofs, buf, len); + nbuf = talloc_realloc(tlss, tlss->push.buf, + uint8_t, tlss->push.ofs + len); + if (nbuf == NULL) { + if (tlss->push.buf) { + errno = EAGAIN; + return -1; + } + + return -1; + } + tlss->push.buf = nbuf; + + memcpy(tlss->push.buf + tlss->push.ofs, buf, len); if (tlss->push.im == NULL) { tlss->push.im = tevent_create_immediate(tlss); @@ -187,7 +201,7 @@ static ssize_t tstream_tls_push_function(gnutls_transport_ptr ptr, * in the next event cycle. * * This way we can batch all push requests, - * if they fit into the buffer. + * if they fit into a UINT16_MAX buffer. * * This is important as gnutls_handshake() * had a bug in some versions e.g. 2.4.1 @@ -223,7 +237,7 @@ static void tstream_tls_push_trigger_write(struct tevent_context *ev, return; } - tlss->push.iov.iov_base = (char *)tlss->push.buffer; + tlss->push.iov.iov_base = (char *)tlss->push.buf; tlss->push.iov.iov_len = tlss->push.ofs; subreq = tstream_writev_send(tlss, @@ -253,6 +267,7 @@ static void tstream_tls_push_done(struct tevent_req *subreq) tlss->push.subreq = NULL; ZERO_STRUCT(tlss->push.iov); + TALLOC_FREE(tlss->push.buf); tlss->push.ofs = 0; ret = tstream_writev_recv(subreq, &sys_errno); |