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
struct tevent_immediate *retry_im;
struct {
struct tevent_immediate *retry_im;
struct {
off_t ofs;
struct iovec iov;
struct tevent_req *subreq;
off_t ofs;
struct iovec iov;
struct tevent_req *subreq;
struct tstream_tls *tlss =
tstream_context_data(stream,
struct tstream_tls);
struct tstream_tls *tlss =
tstream_context_data(stream,
struct tstream_tls);
size_t len;
if (tlss->error != 0) {
size_t len;
if (tlss->error != 0) {
- if (tlss->push.ofs == sizeof(tlss->push.buffer)) {
+ len = MIN(size, UINT16_MAX - tlss->push.ofs);
+
+ if (len == 0) {
errno = EAGAIN;
return -1;
}
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);
if (tlss->push.im == NULL) {
tlss->push.im = tevent_create_immediate(tlss);
* in the next event cycle.
*
* This way we can batch all push requests,
* 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
*
* This is important as gnutls_handshake()
* had a bug in some versions e.g. 2.4.1
- 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,
tlss->push.iov.iov_len = tlss->push.ofs;
subreq = tstream_writev_send(tlss,
tlss->push.subreq = NULL;
ZERO_STRUCT(tlss->push.iov);
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);
tlss->push.ofs = 0;
ret = tstream_writev_recv(subreq, &sys_errno);