diff options
author | Stefan Metzmacher <metze@samba.org> | 2010-11-29 12:27:11 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2010-12-04 12:12:21 +0100 |
commit | 69ad3f7f90273cb62f67331982a40aa99ea05d90 (patch) | |
tree | 903f6b940ddc22efb581d479daab3c4db76404b5 | |
parent | a42ccab929766702029f624f5cc18bc034889c29 (diff) | |
download | samba-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
-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); |