[Spice-commits] 8 commits - server/reds.c server/reds_stream.c server/reds_stream.h

Christophe Fergau teuf at kemper.freedesktop.org
Wed Apr 16 08:19:01 PDT 2014


 server/reds.c        |   46 +++++++----------
 server/reds_stream.c |  133 ++++++++++++++++++++++++++-------------------------
 server/reds_stream.h |   18 +-----
 3 files changed, 92 insertions(+), 105 deletions(-)

New commits:
commit 91a6feb9f4e0c7c179b179f82ff1308ccaf48fdd
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Mon Mar 17 14:10:10 2014 +0100

    Add missing buffer (re)allocation to reds_sasl_handle_auth_steplen()
    
    We need to make sure we have a buffer big enough to accomodate the data
    sent by the coming SASL step.

diff --git a/server/reds_stream.c b/server/reds_stream.c
index f598950..4b61e31 100644
--- a/server/reds_stream.c
+++ b/server/reds_stream.c
@@ -760,6 +760,7 @@ RedsSaslError reds_sasl_handle_auth_steplen(RedsStream *stream, AsyncReadDone re
          * treatment */
         return REDS_SASL_ERROR_OK;
     } else {
+        sasl->data = spice_realloc(sasl->data, sasl->len);
         reds_stream_async_read(stream, (uint8_t *)sasl->data, sasl->len,
                                read_cb, opaque);
         return REDS_SASL_ERROR_OK;
commit 27f968afd203be51a184a0b18c0f531559ac7a15
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Fri Mar 14 17:26:10 2014 +0100

    Call correct SASL helper in reds_handle_auth_sasl_step
    
    sasl_handle_auth_start() was called instead of reds_sasl_handle_auth_step()

diff --git a/server/reds.c b/server/reds.c
index 4484839..2c437ac 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -1908,7 +1908,7 @@ static void reds_handle_auth_sasl_step(void *opaque)
     RedLinkInfo *link = (RedLinkInfo *)opaque;
     RedsSaslError status;
 
-    status = reds_sasl_handle_auth_start(link->stream, reds_handle_auth_sasl_steplen, link);
+    status = reds_sasl_handle_auth_step(link->stream, reds_handle_auth_sasl_steplen, link);
     if (status == REDS_SASL_ERROR_OK) {
         reds_handle_link(link);
     } else if (status != REDS_SASL_ERROR_CONTINUE) {
commit 390a36ea34bbff271169994a5eea6faec41c9d26
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Mon Mar 17 14:08:53 2014 +0100

    Add G_GNUC_UNUSED annotations to async_read_handler args
    
    2 of the arguments are not used, the G_GNUC_UNUSED annotation will make
    this explicit.

diff --git a/server/reds_stream.c b/server/reds_stream.c
index 2c6be61..f598950 100644
--- a/server/reds_stream.c
+++ b/server/reds_stream.c
@@ -413,7 +413,9 @@ static inline void async_read_clear_handlers(AsyncRead *async)
     async->stream = NULL;
 }
 
-static void async_read_handler(int fd, int event, void *data)
+static void async_read_handler(G_GNUC_UNUSED int fd,
+                               G_GNUC_UNUSED int event,
+                               void *data)
 {
     AsyncRead *async = (AsyncRead *)data;
 
commit e36c7efe81373cdc2741f2e24ab4bc5be2010047
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Fri Mar 14 17:44:57 2014 +0100

    Make struct AsyncRead/async_read_handler private
    
    All users are now contained in reds_stream.c

diff --git a/server/reds_stream.c b/server/reds_stream.c
index 191d8f2..2c6be61 100644
--- a/server/reds_stream.c
+++ b/server/reds_stream.c
@@ -33,6 +33,16 @@
 
 #include <openssl/err.h>
 
+struct AsyncRead {
+    RedsStream *stream;
+    void *opaque;
+    uint8_t *now;
+    uint8_t *end;
+    AsyncReadDone done;
+    AsyncReadError error;
+};
+typedef struct AsyncRead AsyncRead;
+
 extern SpiceCoreInterface *core;
 
 #if HAVE_SASL
@@ -403,7 +413,7 @@ static inline void async_read_clear_handlers(AsyncRead *async)
     async->stream = NULL;
 }
 
-void async_read_handler(int fd, int event, void *data)
+static void async_read_handler(int fd, int event, void *data)
 {
     AsyncRead *async = (AsyncRead *)data;
 
diff --git a/server/reds_stream.h b/server/reds_stream.h
index a5b7a17..6cbbbbb 100644
--- a/server/reds_stream.h
+++ b/server/reds_stream.h
@@ -29,17 +29,6 @@ typedef void (*AsyncReadDone)(void *opaque);
 typedef void (*AsyncReadError)(void *opaque, int err);
 
 typedef struct RedsStream RedsStream;
-typedef struct AsyncRead {
-    RedsStream *stream;
-    void *opaque;
-    uint8_t *now;
-    uint8_t *end;
-    AsyncReadDone done;
-    AsyncReadError error;
-} AsyncRead;
-
-void async_read_handler(int fd, int event, void *data);
-
 typedef struct RedsStreamPrivate RedsStreamPrivate;
 
 struct RedsStream {
commit 17f89a348aa3b34b0198e4899be8d39fdccb3582
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Fri Mar 14 17:20:34 2014 +0100

    Remove RedLinkInfo::async_read
    
    9feed69 moved the async reader code to RedsStream so that it can be used
    for the SASL authentication code. In particular, it introduced a
    RedsStream::async_read member which is used by the SASL authentication code
    for its async operations.
    
    However, what was not done is to remove the now redundant
    RedLinkInfo::async_read field. This causes failures when using SASL
    authentication as the async read error callback is getting set
    on the RedLinkInfo::async_read structure, but then the SASL code is trying
    to use the RedeStream::async_read structure for its async IOs, which do not
    have the needed error callback set.
    
    This commit makes use of the newly introduced reds_stream_async_read()
    helper in order to make use of RedsStream::async_read.

diff --git a/server/reds.c b/server/reds.c
index 0390602..4484839 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -123,7 +123,6 @@ static RedsState *reds = NULL;
 
 typedef struct RedLinkInfo {
     RedsStream *stream;
-    AsyncRead async_read;
     SpiceLinkHeader link_header;
     SpiceLinkMess *link_mess;
     int mess_pos;
@@ -1880,12 +1879,9 @@ end:
 
 static void reds_get_spice_ticket(RedLinkInfo *link)
 {
-    AsyncRead *obj = &link->async_read;
-
-    obj->now = (uint8_t *)&link->tiTicketing.encrypted_ticket.encrypted_data;
-    obj->end = obj->now + link->tiTicketing.rsa_size;
-    obj->done = reds_handle_ticket;
-    async_read_handler(0, 0, &link->async_read);
+    reds_stream_async_read(link->stream,
+                           (uint8_t *)&link->tiTicketing.encrypted_ticket.encrypted_data,
+                           link->tiTicketing.rsa_size, reds_handle_ticket, link);
 }
 
 #if HAVE_SASL
@@ -2048,7 +2044,6 @@ static void reds_handle_read_link_done(void *opaque)
 {
     RedLinkInfo *link = (RedLinkInfo *)opaque;
     SpiceLinkMess *link_mess = link->link_mess;
-    AsyncRead *obj = &link->async_read;
     uint32_t num_caps = link_mess->num_common_caps + link_mess->num_channel_caps;
     uint32_t *caps = (uint32_t *)((uint8_t *)link_mess + link_mess->caps_offset);
     int auth_selection;
@@ -2090,10 +2085,11 @@ static void reds_handle_read_link_done(void *opaque)
         spice_warning("Peer doesn't support AUTH selection");
         reds_get_spice_ticket(link);
     } else {
-        obj->now = (uint8_t *)&link->auth_mechanism;
-        obj->end = obj->now + sizeof(SpiceLinkAuthMechanism);
-        obj->done = reds_handle_auth_mechanism;
-        async_read_handler(0, 0, &link->async_read);
+        reds_stream_async_read(link->stream,
+                               (uint8_t *)&link->auth_mechanism,
+                               sizeof(SpiceLinkAuthMechanism),
+                               reds_handle_auth_mechanism,
+                               link);
     }
 }
 
@@ -2115,7 +2111,6 @@ static void reds_handle_read_header_done(void *opaque)
 {
     RedLinkInfo *link = (RedLinkInfo *)opaque;
     SpiceLinkHeader *header = &link->link_header;
-    AsyncRead *obj = &link->async_read;
 
     if (header->magic != SPICE_MAGIC) {
         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_MAGIC);
@@ -2144,22 +2139,21 @@ static void reds_handle_read_header_done(void *opaque)
 
     link->link_mess = spice_malloc(header->size);
 
-    obj->now = (uint8_t *)link->link_mess;
-    obj->end = obj->now + header->size;
-    obj->done = reds_handle_read_link_done;
-    async_read_handler(0, 0, &link->async_read);
+    reds_stream_async_read(link->stream,
+                           (uint8_t *)link->link_mess,
+                           header->size,
+                           reds_handle_read_link_done,
+                           link);
 }
 
 static void reds_handle_new_link(RedLinkInfo *link)
 {
-    AsyncRead *obj = &link->async_read;
-    obj->opaque = link;
-    obj->stream = link->stream;
-    obj->now = (uint8_t *)&link->link_header;
-    obj->end = (uint8_t *)((SpiceLinkHeader *)&link->link_header + 1);
-    obj->done = reds_handle_read_header_done;
-    obj->error = reds_handle_link_error;
-    async_read_handler(0, 0, &link->async_read);
+    reds_stream_set_async_error_handler(link->stream, reds_handle_link_error);
+    reds_stream_async_read(link->stream,
+                           (uint8_t *)&link->link_header,
+                           sizeof(SpiceLinkHeader),
+                           reds_handle_read_header_done,
+                           link);
 }
 
 static void reds_handle_ssl_accept(int fd, int event, void *data)
commit 81427961bd121222681e9275cd5fb4fe7e6e3f25
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Tue Mar 25 14:12:40 2014 +0100

    Call AsyncRead variables 'async' instead of 'obj'
    
    This is a more explicit name.

diff --git a/server/reds_stream.c b/server/reds_stream.c
index b9cddd0..191d8f2 100644
--- a/server/reds_stream.c
+++ b/server/reds_stream.c
@@ -395,54 +395,54 @@ void reds_stream_set_async_error_handler(RedsStream *stream,
     stream->priv->async_read.error = error_handler;
 }
 
-static inline void async_read_clear_handlers(AsyncRead *obj)
+static inline void async_read_clear_handlers(AsyncRead *async)
 {
-    if (obj->stream->watch) {
-        reds_stream_remove_watch(obj->stream);
+    if (async->stream->watch) {
+        reds_stream_remove_watch(async->stream);
     }
-    obj->stream = NULL;
+    async->stream = NULL;
 }
 
 void async_read_handler(int fd, int event, void *data)
 {
-    AsyncRead *obj = (AsyncRead *)data;
+    AsyncRead *async = (AsyncRead *)data;
 
     for (;;) {
-        int n = obj->end - obj->now;
+        int n = async->end - async->now;
 
         spice_assert(n > 0);
-        n = reds_stream_read(obj->stream, obj->now, n);
+        n = reds_stream_read(async->stream, async->now, n);
         if (n <= 0) {
             if (n < 0) {
                 switch (errno) {
                 case EAGAIN:
-                    if (!obj->stream->watch) {
-                        obj->stream->watch = core->watch_add(obj->stream->socket,
-                                                           SPICE_WATCH_EVENT_READ,
-                                                           async_read_handler, obj);
+                    if (!async->stream->watch) {
+                        async->stream->watch = core->watch_add(async->stream->socket,
+                                                               SPICE_WATCH_EVENT_READ,
+                                                               async_read_handler, async);
                     }
                     return;
                 case EINTR:
                     break;
                 default:
-                    async_read_clear_handlers(obj);
-		    if (obj->error) {
-                        obj->error(obj->opaque, errno);
+                    async_read_clear_handlers(async);
+		    if (async->error) {
+                        async->error(async->opaque, errno);
 		    }
                     return;
                 }
             } else {
-                async_read_clear_handlers(obj);
-		if (obj->error) {
-		    obj->error(obj->opaque, 0);
+                async_read_clear_handlers(async);
+		if (async->error) {
+		    async->error(async->opaque, 0);
 		}
                 return;
             }
         } else {
-            obj->now += n;
-            if (obj->now == obj->end) {
-                async_read_clear_handlers(obj);
-                obj->done(obj->opaque);
+            async->now += n;
+            if (async->now == async->end) {
+                async_read_clear_handlers(async);
+                async->done(async->opaque);
                 return;
             }
         }
@@ -454,15 +454,15 @@ void reds_stream_async_read(RedsStream *stream,
                             AsyncReadDone read_done_cb,
                             void *opaque)
 {
-    AsyncRead *obj = &stream->priv->async_read;
-
-    g_return_if_fail(!obj->stream);
-    obj->stream = stream;
-    obj->now = data;
-    obj->end = obj->now + size;
-    obj->done = read_done_cb;
-    obj->opaque = opaque;
-    async_read_handler(0, 0, obj);
+    AsyncRead *async = &stream->priv->async_read;
+
+    g_return_if_fail(!async->stream);
+    async->stream = stream;
+    async->now = data;
+    async->end = async->now + size;
+    async->done = read_done_cb;
+    async->opaque = opaque;
+    async_read_handler(0, 0, async);
 
 }
 
commit 3dd4723e48da6de886963d9781bf53dea65a7e42
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Fri Mar 14 17:43:55 2014 +0100

    Add reds_stream_set_async_error_handler() helper
    
    This replaces async_read_set_error_handler() which was unused. This sets a
    callback to be called when an async operation fails.
    
    We could pass the error_handler to each reds_stream_async_read() call, but as
    we will be using the same one for all async calls, it's more convenient to set it
    once and for all.
    AsyncRead is going to be private to reds_stream.c in one of the next
    commits, and the error handler will need to be set from reds.c,
    hence the move to a public RedsStream method.

diff --git a/server/reds_stream.c b/server/reds_stream.c
index 070a3d5..b9cddd0 100644
--- a/server/reds_stream.c
+++ b/server/reds_stream.c
@@ -389,11 +389,10 @@ int reds_stream_enable_ssl(RedsStream *stream, SSL_CTX *ctx)
     return reds_stream_ssl_accept(stream);
 }
 
-void async_read_set_error_handler(AsyncRead *async,
-                                  AsyncReadError error_handler,
-                                 void *opaque)
+void reds_stream_set_async_error_handler(RedsStream *stream,
+                                         AsyncReadError error_handler)
 {
-    async->error = error_handler;
+    stream->priv->async_read.error = error_handler;
 }
 
 static inline void async_read_clear_handlers(AsyncRead *obj)
diff --git a/server/reds_stream.h b/server/reds_stream.h
index 866679a..a5b7a17 100644
--- a/server/reds_stream.h
+++ b/server/reds_stream.h
@@ -39,9 +39,6 @@ typedef struct AsyncRead {
 } AsyncRead;
 
 void async_read_handler(int fd, int event, void *data);
-void async_read_set_error_handler(AsyncRead *async,
-                                  AsyncReadError error_handler,
-                                  void *opaque);
 
 typedef struct RedsStreamPrivate RedsStreamPrivate;
 
@@ -67,6 +64,8 @@ typedef enum {
 ssize_t reds_stream_read(RedsStream *s, void *buf, size_t nbyte);
 void reds_stream_async_read(RedsStream *stream, uint8_t *data, size_t size,
                             AsyncReadDone read_done_cb, void *opaque);
+void reds_stream_set_async_error_handler(RedsStream *stream,
+                                         AsyncReadError error_handler);
 ssize_t reds_stream_write(RedsStream *s, const void *buf, size_t nbyte);
 ssize_t reds_stream_writev(RedsStream *s, const struct iovec *iov, int iovcnt);
 bool reds_stream_write_all(RedsStream *stream, const void *in_buf, size_t n);
commit dc017bb9ae934594289b99a67d929f075e60819f
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Fri Mar 14 17:39:47 2014 +0100

    Introduce reds_stream_async_read() helper
    
    This will allow to make RedsStream::async_read private

diff --git a/server/reds_stream.c b/server/reds_stream.c
index bc423a1..070a3d5 100644
--- a/server/reds_stream.c
+++ b/server/reds_stream.c
@@ -314,8 +314,6 @@ RedsStream *reds_stream_new(int socket)
     stream->priv->write = stream_write_cb;
     stream->priv->writev = stream_writev_cb;
 
-    stream->priv->async_read.stream = stream;
-
     return stream;
 }
 
@@ -400,11 +398,10 @@ void async_read_set_error_handler(AsyncRead *async,
 
 static inline void async_read_clear_handlers(AsyncRead *obj)
 {
-    if (!obj->stream->watch) {
-        return;
+    if (obj->stream->watch) {
+        reds_stream_remove_watch(obj->stream);
     }
-
-    reds_stream_remove_watch(obj->stream);
+    obj->stream = NULL;
 }
 
 void async_read_handler(int fd, int event, void *data)
@@ -453,6 +450,23 @@ void async_read_handler(int fd, int event, void *data)
     }
 }
 
+void reds_stream_async_read(RedsStream *stream,
+                            uint8_t *data, size_t size,
+                            AsyncReadDone read_done_cb,
+                            void *opaque)
+{
+    AsyncRead *obj = &stream->priv->async_read;
+
+    g_return_if_fail(!obj->stream);
+    obj->stream = stream;
+    obj->now = data;
+    obj->end = obj->now + size;
+    obj->done = read_done_cb;
+    obj->opaque = opaque;
+    async_read_handler(0, 0, obj);
+
+}
+
 #if HAVE_SASL
 bool reds_stream_write_u8(RedsStream *s, uint8_t n)
 {
@@ -642,7 +656,6 @@ RedsSaslError reds_sasl_handle_auth_step(RedsStream *stream, AsyncReadDone read_
     char *clientdata = NULL;
     RedsSASL *sasl = &stream->priv->sasl;
     uint32_t datalen = sasl->len;
-    AsyncRead *obj = &stream->priv->async_read;
 
     /* NB, distinction of NULL vs "" is *critical* in SASL */
     if (datalen) {
@@ -687,10 +700,8 @@ RedsSaslError reds_sasl_handle_auth_step(RedsStream *stream, AsyncReadDone read_
     if (err == SASL_CONTINUE) {
         spice_info("%s", "Authentication must continue (step)");
         /* Wait for step length */
-        obj->now = (uint8_t *)&sasl->len;
-        obj->end = obj->now + sizeof(uint32_t);
-        obj->done = read_cb;
-        async_read_handler(0, 0, &stream->priv->async_read);
+        reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
+                               read_cb, opaque);
         return REDS_SASL_ERROR_CONTINUE;
     } else {
         int ssf;
@@ -722,7 +733,6 @@ authreject:
 
 RedsSaslError reds_sasl_handle_auth_steplen(RedsStream *stream, AsyncReadDone read_cb, void *opaque)
 {
-    AsyncRead *obj = &stream->priv->async_read;
     RedsSASL *sasl = &stream->priv->sasl;
 
     spice_info("Got steplen %d", sasl->len);
@@ -739,11 +749,8 @@ RedsSaslError reds_sasl_handle_auth_steplen(RedsStream *stream, AsyncReadDone re
          * treatment */
         return REDS_SASL_ERROR_OK;
     } else {
-        sasl->data = spice_realloc(sasl->data, sasl->len);
-        obj->now = (uint8_t *)sasl->data;
-        obj->end = obj->now + sasl->len;
-        obj->done = read_cb;
-        async_read_handler(0, 0, obj);
+        reds_stream_async_read(stream, (uint8_t *)sasl->data, sasl->len,
+                               read_cb, opaque);
         return REDS_SASL_ERROR_OK;
     }
 }
@@ -765,7 +772,6 @@ RedsSaslError reds_sasl_handle_auth_steplen(RedsStream *stream, AsyncReadDone re
 
 RedsSaslError reds_sasl_handle_auth_start(RedsStream *stream, AsyncReadDone read_cb, void *opaque)
 {
-    AsyncRead *obj = &stream->priv->async_read;
     const char *serverout;
     unsigned int serveroutlen;
     int err;
@@ -817,10 +823,8 @@ RedsSaslError reds_sasl_handle_auth_start(RedsStream *stream, AsyncReadDone read
     if (err == SASL_CONTINUE) {
         spice_info("%s", "Authentication must continue (start)");
         /* Wait for step length */
-        obj->now = (uint8_t *)&sasl->len;
-        obj->end = obj->now + sizeof(uint32_t);
-        obj->done = read_cb;
-        async_read_handler(0, 0, &stream->priv->async_read);
+        reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
+                               read_cb, opaque);
         return REDS_SASL_ERROR_CONTINUE;
     } else {
         int ssf;
@@ -851,7 +855,6 @@ authreject:
 
 RedsSaslError reds_sasl_handle_auth_startlen(RedsStream *stream, AsyncReadDone read_cb, void *opaque)
 {
-    AsyncRead *obj = &stream->priv->async_read;
     RedsSASL *sasl = &stream->priv->sasl;
 
     spice_info("Got client start len %d", sasl->len);
@@ -865,17 +868,14 @@ RedsSaslError reds_sasl_handle_auth_startlen(RedsStream *stream, AsyncReadDone r
     }
 
     sasl->data = spice_realloc(sasl->data, sasl->len);
-    obj->now = (uint8_t *)sasl->data;
-    obj->end = obj->now + sasl->len;
-    obj->done = read_cb;
-    async_read_handler(0, 0, obj);
+    reds_stream_async_read(stream, (uint8_t *)sasl->data, sasl->len,
+                           read_cb, opaque);
 
     return REDS_SASL_ERROR_OK;
 }
 
 bool reds_sasl_handle_auth_mechname(RedsStream *stream, AsyncReadDone read_cb, void *opaque)
 {
-    AsyncRead *obj = &stream->priv->async_read;
     RedsSASL *sasl = &stream->priv->sasl;
 
     sasl->mechname[sasl->len] = '\0';
@@ -907,17 +907,14 @@ bool reds_sasl_handle_auth_mechname(RedsStream *stream, AsyncReadDone read_cb, v
 
     spice_info("Validated mechname '%s'", sasl->mechname);
 
-    obj->now = (uint8_t *)&sasl->len;
-    obj->end = obj->now + sizeof(uint32_t);
-    obj->done = read_cb;
-    async_read_handler(0, 0, &stream->priv->async_read);
+    reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
+                           read_cb, opaque);
 
     return TRUE;
 }
 
 bool reds_sasl_handle_auth_mechlen(RedsStream *stream, AsyncReadDone read_cb, void *opaque)
 {
-    AsyncRead *obj = &stream->priv->async_read;
     RedsSASL *sasl = &stream->priv->sasl;
 
     if (sasl->len < 1 || sasl->len > 100) {
@@ -928,10 +925,8 @@ bool reds_sasl_handle_auth_mechlen(RedsStream *stream, AsyncReadDone read_cb, vo
     sasl->mechname = spice_malloc(sasl->len + 1);
 
     spice_info("Wait for client mechname");
-    obj->now = (uint8_t *)sasl->mechname;
-    obj->end = obj->now + sasl->len;
-    obj->done = read_cb;
-    async_read_handler(0, 0, &stream->priv->async_read);
+    reds_stream_async_read(stream, (uint8_t *)sasl->mechname, sasl->len,
+                           read_cb, opaque);
 
     return TRUE;
 }
@@ -943,7 +938,6 @@ bool reds_sasl_start_auth(RedsStream *stream, AsyncReadDone read_cb, void *opaqu
     int err;
     char *localAddr, *remoteAddr;
     int mechlistlen;
-    AsyncRead *obj = &stream->priv->async_read;
     RedsSASL *sasl = &stream->priv->sasl;
 
     if (!(localAddr = reds_stream_get_local_address(stream))) {
@@ -1040,11 +1034,8 @@ bool reds_sasl_start_auth(RedsStream *stream, AsyncReadDone read_cb, void *opaqu
     }
 
     spice_info("Wait for client mechname length");
-    obj->now = (uint8_t *)&sasl->len;
-    obj->end = obj->now + sizeof(uint32_t);
-    obj->done = read_cb;
-    obj->opaque = opaque;
-    async_read_handler(0, 0, obj);
+    reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
+                           read_cb, opaque);
 
     return TRUE;
 
diff --git a/server/reds_stream.h b/server/reds_stream.h
index ae3403a..866679a 100644
--- a/server/reds_stream.h
+++ b/server/reds_stream.h
@@ -65,6 +65,8 @@ typedef enum {
 
 /* any thread */
 ssize_t reds_stream_read(RedsStream *s, void *buf, size_t nbyte);
+void reds_stream_async_read(RedsStream *stream, uint8_t *data, size_t size,
+                            AsyncReadDone read_done_cb, void *opaque);
 ssize_t reds_stream_write(RedsStream *s, const void *buf, size_t nbyte);
 ssize_t reds_stream_writev(RedsStream *s, const struct iovec *iov, int iovcnt);
 bool reds_stream_write_all(RedsStream *stream, const void *in_buf, size_t n);


More information about the Spice-commits mailing list