From d0d05f8474ed1882d373f042aba2c0209247678a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 18 Jul 2012 15:28:50 +1000 Subject: s4-lib/tls: Try socket_send() multiple times to send partial packets This works around an artificial limitation in socket_wrapper that breaks some versions of GnuTLS when we return a short write. Instead, keep pushing until the OS will not take it. The correct solution will be to use tls_tstream, but the client code for this is not yet tested and needs the ldap client layer changed to use it. Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Wed Jul 18 11:23:55 CEST 2012 on sn-devel-104 --- source4/lib/tls/tls.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'source4/lib') diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c index 7bf2ff8e43..db6d1eb5de 100644 --- a/source4/lib/tls/tls.c +++ b/source4/lib/tls/tls.c @@ -152,7 +152,7 @@ static ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size) { struct tls_context *tls = talloc_get_type(ptr, struct tls_context); NTSTATUS status; - size_t nwritten; + size_t nwritten, total_nwritten = 0; DATA_BLOB b; if (!tls->tls_enabled) { @@ -162,19 +162,32 @@ static ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size) b.data = discard_const(buf); b.length = size; - status = socket_send(tls->socket, &b, &nwritten); - if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - errno = EAGAIN; - return -1; - } - if (!NT_STATUS_IS_OK(status)) { - TEVENT_FD_WRITEABLE(tls->fde); - return -1; - } - if (size != nwritten) { + /* Cope with socket_wrapper 1500 byte chunking for PCAP */ + do { + status = socket_send(tls->socket, &b, &nwritten); + + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + errno = EAGAIN; + return -1; + } + if (!NT_STATUS_IS_OK(status)) { + TEVENT_FD_WRITEABLE(tls->fde); + return -1; + } + + total_nwritten += nwritten; + + if (size == nwritten) { + break; + } + + b.data += nwritten; + b.length -= nwritten; + TEVENT_FD_WRITEABLE(tls->fde); - } - return nwritten; + } while (b.length); + + return total_nwritten; } /* -- cgit