summaryrefslogtreecommitdiff
path: root/source4/lib/tls
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-11-29 12:27:11 +0100
committerStefan Metzmacher <metze@samba.org>2010-12-04 12:12:21 +0100
commit69ad3f7f90273cb62f67331982a40aa99ea05d90 (patch)
tree903f6b940ddc22efb581d479daab3c4db76404b5 /source4/lib/tls
parenta42ccab929766702029f624f5cc18bc034889c29 (diff)
downloadsamba-69ad3f7f90273cb62f67331982a40aa99ea05d90.tar.gz
samba-69ad3f7f90273cb62f67331982a40aa99ea05d90.tar.bz2
samba-69ad3f7f90273cb62f67331982a40aa99ea05d90.zip
tls_tstream: use a dynamic buffer for the push case
Some versions of gnutls doesn't handle EAGAIN correctly, so we better allow sending buffers without a low size limitation, the limit is now UINT16_MAX (0xFFFF) and we allocate the buffer with talloc each time. metze
Diffstat (limited to 'source4/lib/tls')
-rw-r--r--source4/lib/tls/tls_tstream.c27
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);