From f54a9f4db407ab8224ee76c945e72741e4f3ffba Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 29 Apr 2015 13:07:17 +0900 Subject: [PATCH] secur32: Add a loop around gnutls_record_send since it may send a partial record. --- dlls/secur32/schannel_gnutls.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c index 11735745b90..7039dcdb7ab 100644 --- a/dlls/secur32/schannel_gnutls.c +++ b/dlls/secur32/schannel_gnutls.c @@ -400,30 +400,31 @@ SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer, SIZE_T *length) { gnutls_session_t s = (gnutls_session_t)session; - ssize_t ret; - -again: - ret = pgnutls_record_send(s, buffer, *length); + ssize_t ret, total = 0; - if (ret >= 0) - *length = ret; - else if (ret == GNUTLS_E_AGAIN) + for (;;) { - struct schan_transport *t = (struct schan_transport *)pgnutls_transport_get_ptr(s); - SIZE_T count = 0; - - if (schan_get_buffer(t, &t->out, &count)) - goto again; + ret = pgnutls_record_send(s, (const char *)buffer + total, *length - total); + if (ret >= 0) + { + total += ret; + TRACE( "sent %d now %d/%ld\n", ret, total, *length ); + if (total == *length) return SEC_E_OK; + } + else if (ret == GNUTLS_E_AGAIN) + { + struct schan_transport *t = (struct schan_transport *)pgnutls_transport_get_ptr(s); + SIZE_T count = 0; - return SEC_I_CONTINUE_NEEDED; - } - else - { - pgnutls_perror(ret); - return SEC_E_INTERNAL_ERROR; + if (schan_get_buffer(t, &t->out, &count)) continue; + return SEC_I_CONTINUE_NEEDED; + } + else + { + pgnutls_perror(ret); + return SEC_E_INTERNAL_ERROR; + } } - - return SEC_E_OK; } SECURITY_STATUS schan_imp_recv(schan_imp_session session, void *buffer, -- 2.11.4.GIT