[Spice-devel] [PATCH spice-server v2 6/8] server: Limit the access to SpiceDataHeader of messages - only via red_channel.

Yonit Halperin yhalperi at redhat.com
Tue Jan 10 03:25:20 PST 2012


---
 server/inputs_channel.c    |   10 +++++++---
 server/main_channel.c      |    8 ++++++--
 server/red_channel.c       |   34 +++++++++++++++++++++++++---------
 server/red_channel.h       |   24 ++++++++++--------------
 server/red_tunnel_worker.c |   43 ++++++++++++++++++++++---------------------
 server/red_worker.c        |    9 ++++-----
 server/smartcard.c         |   18 +++++++++++-------
 server/spicevmc.c          |   24 ++++++++++++++----------
 8 files changed, 99 insertions(+), 71 deletions(-)

diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index c8b42e3..a987478 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -168,18 +168,22 @@ const VDAgentMouseState *inputs_get_mouse_state(void)
     return &g_inputs_channel->mouse_state;
 }
 
-static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header)
+static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
+                                                 uint16_t type,
+                                                 uint32_t size)
 {
     InputsChannel *inputs_channel = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base);
 
-    if (msg_header->size > RECEIVE_BUF_SIZE) {
+    if (size > RECEIVE_BUF_SIZE) {
         red_printf("error: too large incoming message");
         return NULL;
     }
     return inputs_channel->recv_buf;
 }
 
-static void inputs_channel_release_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header,
+static void inputs_channel_release_msg_rcv_buf(RedChannelClient *rcc,
+                                               uint16_t type,
+                                               uint32_t size,
                                                uint8_t *msg)
 {
 }
diff --git a/server/main_channel.c b/server/main_channel.c
index 4b5b669..b55bf00 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -852,14 +852,18 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
     return TRUE;
 }
 
-static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header)
+static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
+                                               uint16_t type,
+                                               uint32_t size)
 {
     MainChannel *main_chan = SPICE_CONTAINEROF(rcc->channel, MainChannel, base);
 
     return main_chan->recv_buf;
 }
 
-static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header,
+static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc,
+                                               uint16_t type,
+                                               uint32_t size,
                                                uint8_t *msg)
 {
 }
diff --git a/server/red_channel.c b/server/red_channel.c
index 671bcf5..06b4ef0 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -103,7 +103,9 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
 
         if (handler->msg_pos < handler->header.size) {
             if (!handler->msg) {
-                handler->msg = handler->cb->alloc_msg_buf(handler->opaque, &handler->header);
+                handler->msg = handler->cb->alloc_msg_buf(handler->opaque,
+                                                          handler->header.type,
+                                                          handler->header.size);
                 if (handler->msg == NULL) {
                     red_printf("ERROR: channel refused to allocate buffer.");
                     handler->cb->on_error(handler->opaque);
@@ -115,7 +117,10 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
                                           handler->msg + handler->msg_pos,
                                           handler->header.size - handler->msg_pos);
             if (bytes_read == -1) {
-                handler->cb->release_msg_buf(handler->opaque, &handler->header, handler->msg);
+                handler->cb->release_msg_buf(handler->opaque,
+                                             handler->header.type,
+                                             handler->header.size,
+                                             handler->msg);
                 handler->cb->on_error(handler->opaque);
                 return;
             }
@@ -131,7 +136,9 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
                 SPICE_VERSION_MINOR, &parsed_size, &parsed_free);
             if (parsed == NULL) {
                 red_printf("failed to parse message type %d", handler->header.type);
-                handler->cb->release_msg_buf(handler->opaque, &handler->header, handler->msg);
+                handler->cb->release_msg_buf(handler->opaque, handler->header.type,
+                                             handler->header.size,
+                                             handler->msg);
                 handler->cb->on_error(handler->opaque);
                 return;
             }
@@ -139,11 +146,16 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
                                     handler->header.type, parsed);
             parsed_free(parsed);
         } else {
-            ret_handle = handler->cb->handle_message(handler->opaque, &handler->header,
-                                                 handler->msg);
+            ret_handle = handler->cb->handle_message(handler->opaque,
+                                                     handler->header.type,
+                                                     handler->header.size,
+                                                     handler->msg);
         }
         handler->msg_pos = 0;
-        handler->cb->release_msg_buf(handler->opaque, &handler->header, handler->msg);
+        handler->cb->release_msg_buf(handler->opaque,
+                                     handler->header.type,
+                                     handler->header.size,
+                                     handler->msg);
         handler->msg = NULL;
         handler->header_pos = 0;
 
@@ -586,7 +598,10 @@ RedChannel *red_channel_create_dummy(int size, uint32_t type, uint32_t id)
     return channel;
 }
 
-static int do_nothing_handle_message(RedChannelClient *rcc, SpiceDataHeader *header, uint8_t *msg)
+static int do_nothing_handle_message(RedChannelClient *rcc,
+                                     uint16_t type,
+                                     uint32_t size,
+                                     uint8_t *msg)
 {
     return TRUE;
 }
@@ -1204,10 +1219,11 @@ RedClient *red_channel_client_get_client(RedChannelClient *rcc)
     return rcc->client;
 }
 
-SpiceDataHeader *red_channel_client_get_header(RedChannelClient *rcc)
+void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_list)
 {
-    return rcc->send_data.header;
+    rcc->send_data.header->sub_list = sub_list;
 }
+
 /* end of accessors */
 
 int red_channel_get_first_socket(RedChannel *channel)
diff --git a/server/red_channel.h b/server/red_channel.h
index cb80100..40792c1 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -38,11 +38,11 @@
    At the final stage, this interface shouldn't be exposed. Only RedChannel will use it. */
 
 typedef int (*handle_message_proc)(void *opaque,
-                                   SpiceDataHeader *header, uint8_t *msg);
+                                   uint16_t type, uint32_t size, uint8_t *msg);
 typedef int (*handle_parsed_proc)(void *opaque, uint32_t size, uint16_t type, void *message);
-typedef uint8_t *(*alloc_msg_recv_buf_proc)(void *opaque, SpiceDataHeader *msg_header);
+typedef uint8_t *(*alloc_msg_recv_buf_proc)(void *opaque, uint16_t type, uint32_t size);
 typedef void (*release_msg_recv_buf_proc)(void *opaque,
-                                          SpiceDataHeader *msg_header, uint8_t *msg);
+                                          uint16_t type, uint32_t size, uint8_t *msg);
 typedef void (*on_incoming_error_proc)(void *opaque);
 
 typedef struct IncomingHandlerInterface {
@@ -119,13 +119,13 @@ typedef struct PipeItem {
 } PipeItem;
 
 typedef uint8_t *(*channel_alloc_msg_recv_buf_proc)(RedChannelClient *channel,
-                                                    SpiceDataHeader *msg_header);
+                                                    uint16_t type, uint32_t size);
 typedef int (*channel_handle_parsed_proc)(RedChannelClient *rcc, uint32_t size, uint16_t type,
                                         void *message);
 typedef int (*channel_handle_message_proc)(RedChannelClient *rcc,
-                                           SpiceDataHeader *header, uint8_t *msg);
+                                           uint16_t type, uint32_t size, uint8_t *msg);
 typedef void (*channel_release_msg_recv_buf_proc)(RedChannelClient *channel,
-                                                  SpiceDataHeader *msg_header, uint8_t *msg);
+                                                  uint16_t type, uint32_t size, uint8_t *msg);
 typedef void (*channel_disconnect_proc)(RedChannelClient *rcc);
 typedef int (*channel_configure_socket_proc)(RedChannelClient *rcc);
 typedef void (*channel_send_pipe_item_proc)(RedChannelClient *rcc, PipeItem *item);
@@ -334,7 +334,7 @@ void red_channel_init_outgoing_messages_window(RedChannel *channel);
 
 /* handles general channel msgs from the client */
 int red_channel_client_handle_message(RedChannelClient *rcc, uint32_t size,
-                               uint16_t type, void *message);
+                                      uint16_t type, void *message);
 
 /* when preparing send_data: should call init and then use marshaller */
 void red_channel_client_init_send_data(RedChannelClient *rcc, uint16_t msg_type, PipeItem *item);
@@ -444,13 +444,9 @@ SpiceMarshaller *red_channel_client_get_marshaller(RedChannelClient *rcc);
 RedsStream *red_channel_client_get_stream(RedChannelClient *rcc);
 RedClient *red_channel_client_get_client(RedChannelClient *rcc);
 
-/* this is a convenience function for sending messages, sometimes (migration only?)
- * the serial from the header needs to be available for sending. Note that the header
- * pointer retrieved is not valid except between red_channel_reset_send_data and
- * red_channel_begin_send_message. red_channel_init_send_data changes the header (sets
- * the type in it) as a convenience function. It is preffered to do that through it and
- * not via the below accessor and direct header manipulation. */
-SpiceDataHeader *red_channel_client_get_header(RedChannelClient *rcc);
+/* Note that the header is valid only between red_channel_reset_send_data and
+ * red_channel_begin_send_message.*/
+void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_list);
 
 /* return the sum of all the rcc pipe size */
 uint32_t red_channel_max_pipe_size(RedChannel *channel);
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 1e8267e..250e8b3 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -1644,27 +1644,27 @@ static int tunnel_channel_handle_socket_token(TunnelChannelClient *channel, RedS
 }
 
 static uint8_t *tunnel_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
-                                                 SpiceDataHeader *msg_header)
+                                                 uint16_t type, uint32_t size)
 {
     TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel;
 
-    if (msg_header->type == SPICE_MSGC_TUNNEL_SOCKET_DATA) {
+    if (type == SPICE_MSGC_TUNNEL_SOCKET_DATA) {
         return (__tunnel_worker_alloc_socket_rcv_buf(tunnel_channel->worker)->buf);
-    } else if ((msg_header->type == SPICE_MSGC_MIGRATE_DATA) ||
-               (msg_header->type == SPICE_MSGC_TUNNEL_SERVICE_ADD)) {
-        return spice_malloc(msg_header->size);
+    } else if ((type == SPICE_MSGC_MIGRATE_DATA) ||
+               (type == SPICE_MSGC_TUNNEL_SERVICE_ADD)) {
+        return spice_malloc(size);
     } else {
         return (tunnel_channel->control_rcv_buf);
     }
 }
 
 // called by the receive routine of the channel, before the buffer was assigned to a socket
-static void tunnel_channel_release_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header,
+static void tunnel_channel_release_msg_rcv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size,
                                                uint8_t *msg)
 {
     TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel;
 
-    if (msg_header->type == SPICE_MSGC_TUNNEL_SOCKET_DATA) {
+    if (type == SPICE_MSGC_TUNNEL_SOCKET_DATA) {
         ASSERT(!(SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf)->base.usr_opaque));
         __tunnel_worker_free_socket_rcv_buf(tunnel_channel->worker,
                                             SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf));
@@ -2243,12 +2243,13 @@ error:
 }
 
 //  msg was allocated by tunnel_channel_alloc_msg_rcv_buf
-static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader *header, uint8_t *msg)
+static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type,
+                                         uint32_t size, uint8_t *msg)
 {
     TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel;
     RedSocket *sckt = NULL;
     // retrieve the sckt
-    switch (header->type) {
+    switch (type) {
     case SPICE_MSGC_MIGRATE_FLUSH_MARK:
     case SPICE_MSGC_MIGRATE_DATA:
     case SPICE_MSGC_TUNNEL_SERVICE_ADD:
@@ -2269,12 +2270,12 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader
         }
         break;
     default:
-        return red_channel_client_handle_message(rcc, header->size, header->type, msg);
+        return red_channel_client_handle_message(rcc, size, type, msg);
     }
 
-    switch (header->type) {
+    switch (type) {
     case SPICE_MSGC_TUNNEL_SERVICE_ADD:
-        if (header->size < sizeof(SpiceMsgcTunnelAddGenericService)) {
+        if (size < sizeof(SpiceMsgcTunnelAddGenericService)) {
             red_printf("bad message size");
             free(msg);
             return FALSE;
@@ -2285,7 +2286,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader
         red_printf("REDC_TUNNEL_REMOVE_SERVICE not supported yet");
         return FALSE;
     case SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK:
-        if (header->size != sizeof(SpiceMsgcTunnelSocketOpenAck)) {
+        if (size != sizeof(SpiceMsgcTunnelSocketOpenAck)) {
             red_printf("bad message size");
             return FALSE;
         }
@@ -2294,7 +2295,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader
                                                         ((SpiceMsgcTunnelSocketOpenAck *)msg)->tokens);
 
     case SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK:
-        if (header->size != sizeof(SpiceMsgcTunnelSocketOpenNack)) {
+        if (size != sizeof(SpiceMsgcTunnelSocketOpenNack)) {
             red_printf("bad message size");
             return FALSE;
         }
@@ -2302,35 +2303,35 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader
         return tunnel_channel_handle_socket_connect_nack(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_DATA:
     {
-        if (header->size < sizeof(SpiceMsgcTunnelSocketData)) {
+        if (size < sizeof(SpiceMsgcTunnelSocketData)) {
             red_printf("bad message size");
             return FALSE;
         }
 
         return tunnel_channel_handle_socket_receive_data(tunnel_channel, sckt,
                                                     SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf),
-                                                    header->size - sizeof(SpiceMsgcTunnelSocketData));
+                                                    size - sizeof(SpiceMsgcTunnelSocketData));
     }
     case SPICE_MSGC_TUNNEL_SOCKET_FIN:
-        if (header->size != sizeof(SpiceMsgcTunnelSocketFin)) {
+        if (size != sizeof(SpiceMsgcTunnelSocketFin)) {
             red_printf("bad message size");
             return FALSE;
         }
         return tunnel_channel_handle_socket_fin(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_CLOSED:
-        if (header->size != sizeof(SpiceMsgcTunnelSocketClosed)) {
+        if (size != sizeof(SpiceMsgcTunnelSocketClosed)) {
             red_printf("bad message size");
             return FALSE;
         }
         return tunnel_channel_handle_socket_closed(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK:
-        if (header->size != sizeof(SpiceMsgcTunnelSocketClosedAck)) {
+        if (size != sizeof(SpiceMsgcTunnelSocketClosedAck)) {
             red_printf("bad message size");
             return FALSE;
         }
         return tunnel_channel_handle_socket_closed_ack(tunnel_channel, sckt);
     case SPICE_MSGC_TUNNEL_SOCKET_TOKEN:
-        if (header->size != sizeof(SpiceMsgcTunnelSocketTokens)) {
+        if (size != sizeof(SpiceMsgcTunnelSocketTokens)) {
             red_printf("bad message size");
             return FALSE;
         }
@@ -2338,7 +2339,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader
         return tunnel_channel_handle_socket_token(tunnel_channel, sckt,
                                                   (SpiceMsgcTunnelSocketTokens *)msg);
     default:
-        return red_channel_client_handle_message(rcc, header->size, header->type, msg);
+        return red_channel_client_handle_message(rcc, size, type, msg);
     }
     return TRUE;
 }
diff --git a/server/red_worker.c b/server/red_worker.c
index d82c84e..f454302 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1517,15 +1517,15 @@ static void release_upgrade_item(RedWorker* worker, UpgradeItem *item)
     }
 }
 
-static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header)
+static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size)
 {
     CommonChannel *common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base);
 
     return common->recv_buf;
 }
 
-static void common_release_recv_buf(RedChannelClient *rcc,
-                                    SpiceDataHeader *msg_header, uint8_t* msg)
+static void common_release_recv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size,
+                                    uint8_t* msg)
 {
 }
 
@@ -7785,7 +7785,6 @@ static inline void display_begin_send_message(RedChannelClient *rcc,
 {
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
     FreeList *free_list = &dcc->send_data.free_list;
-    SpiceDataHeader *header = red_channel_client_get_header(rcc);
 
     if (free_list->res->count) {
         int sub_list_len = 1;
@@ -7828,7 +7827,7 @@ static inline void display_begin_send_message(RedChannelClient *rcc,
             spice_marshaller_add_uint32(sub_list_m, spice_marshaller_get_offset(wait_m));
         }
         spice_marshaller_add_uint32(sub_list_m, spice_marshaller_get_offset(inval_m));
-        header->sub_list = spice_marshaller_get_offset(sub_list_m);
+        red_channel_client_set_header_sub_list(rcc, spice_marshaller_get_offset(sub_list_m));
     }
     red_channel_client_begin_send_message(rcc);
 }
diff --git a/server/smartcard.c b/server/smartcard.c
index f9cafdf..08ba3da 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -273,15 +273,18 @@ static int smartcard_channel_client_config_socket(RedChannelClient *rcc)
 }
 
 static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
-                                                    SpiceDataHeader *msg_header)
+                                                    uint16_t type,
+                                                    uint32_t size)
 {
-    return spice_malloc(msg_header->size);
+    return spice_malloc(size);
 }
 
 static void smartcard_channel_release_msg_rcv_buf(RedChannelClient *rcc,
-                                SpiceDataHeader *msg_header, uint8_t *msg)
+                                                  uint16_t type,
+                                                  uint32_t size,
+                                                  uint8_t *msg)
 {
-    red_printf("freeing %d bytes", msg_header->size);
+    red_printf("freeing %d bytes", size);
     free(msg);
 }
 
@@ -439,14 +442,15 @@ static void smartcard_channel_write_to_reader(VSCMsgHeader *vheader)
 }
 
 static int smartcard_channel_handle_message(RedChannelClient *rcc,
-                                            SpiceDataHeader *header,
+                                            uint16_t type,
+                                            uint32_t size,
                                             uint8_t *msg)
 {
     VSCMsgHeader* vheader = (VSCMsgHeader*)msg;
 
-    if (header->type != SPICE_MSGC_SMARTCARD_DATA) {
+    if (type != SPICE_MSGC_SMARTCARD_DATA) {
         /* handle ack's, spicy sends them while spicec does not */
-        return red_channel_client_handle_message(rcc, header->size, header->type, msg);
+        return red_channel_client_handle_message(rcc, size, type, msg);
     }
 
     ASSERT(header->size == vheader->length + sizeof(VSCMsgHeader));
diff --git a/server/spicevmc.c b/server/spicevmc.c
index a08f330..6df5313 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -126,7 +126,9 @@ static void spicevmc_red_channel_client_on_disconnect(RedChannelClient *rcc)
 }
 
 static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc,
-    SpiceDataHeader *header, uint8_t *msg)
+                                                      uint16_t type,
+                                                      uint32_t size,
+                                                      uint8_t *msg)
 {
     SpiceVmcState *state;
     SpiceCharDeviceInstance *sin;
@@ -136,22 +138,22 @@ static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc,
     sin = state->chardev_sin;
     sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
 
-    if (header->type != SPICE_MSGC_SPICEVMC_DATA) {
-        return red_channel_client_handle_message(rcc, header->size,
-                                                 header->type, msg);
+    if (type != SPICE_MSGC_SPICEVMC_DATA) {
+        return red_channel_client_handle_message(rcc, size, type, msg);
     }
 
     /*
      * qemu spicevmc will consume everything we give it, no need for
      * flow control checks (or to use a pipe).
      */
-    sif->write(sin, msg, header->size);
+    sif->write(sin, msg, size);
 
     return TRUE;
 }
 
 static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
-    SpiceDataHeader *msg_header)
+                                                       uint16_t type,
+                                                       uint32_t size)
 {
     SpiceVmcState *state;
 
@@ -159,9 +161,9 @@ static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
 
     assert(!state->rcv_buf_in_use);
 
-    if (msg_header->size > state->rcv_buf_size) {
-        state->rcv_buf = spice_realloc(state->rcv_buf, msg_header->size);
-        state->rcv_buf_size = msg_header->size;
+    if (size > state->rcv_buf_size) {
+        state->rcv_buf = spice_realloc(state->rcv_buf, size);
+        state->rcv_buf_size = size;
     }
 
     state->rcv_buf_in_use = 1;
@@ -170,7 +172,9 @@ static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
 }
 
 static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
-    SpiceDataHeader *msg_header, uint8_t *msg)
+                                                     uint16_t type,
+                                                     uint32_t size,
+                                                     uint8_t *msg)
 {
     SpiceVmcState *state;
 
-- 
1.7.6.4



More information about the Spice-devel mailing list