summaryrefslogtreecommitdiff
path: root/source4/lib
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2012-07-18 15:28:50 +1000
committerAndrew Bartlett <abartlet@samba.org>2012-07-18 11:23:55 +0200
commitd0d05f8474ed1882d373f042aba2c0209247678a (patch)
tree88b39ca2b2519743559f3dae1d66278fecc1d124 /source4/lib
parent02a356ea775a3ba589cb50af3c861ab86aaffa0b (diff)
downloadsamba-d0d05f8474ed1882d373f042aba2c0209247678a.tar.gz
samba-d0d05f8474ed1882d373f042aba2c0209247678a.tar.bz2
samba-d0d05f8474ed1882d373f042aba2c0209247678a.zip
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 <abartlet@samba.org> Autobuild-Date(master): Wed Jul 18 11:23:55 CEST 2012 on sn-devel-104
Diffstat (limited to 'source4/lib')
-rw-r--r--source4/lib/tls/tls.c39
1 files changed, 26 insertions, 13 deletions
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;
}
/*