Alexandre Julliard : secur32: Add a loop around gnutls_record_send since it may send a partial record.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Apr 29 09:22:18 CDT 2015


Module: wine
Branch: master
Commit: f54a9f4db407ab8224ee76c945e72741e4f3ffba
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f54a9f4db407ab8224ee76c945e72741e4f3ffba

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Apr 29 13:07:17 2015 +0900

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 1173574..7039dcd 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,




More information about the wine-cvs mailing list