[Spice-devel] [PATCH spice-server 04/14] agent: Fix tokens handling in main_channel

Yonit Halperin yhalperi at redhat.com
Wed Jun 27 08:16:42 PDT 2012


- Allow sending tokens to a specific client.
- Do not ignore tokens that are sent from the client to the server.

The tokens support for multiple clients and for server side tokens
is still broken in reds. It will be fixed in following patches, when
the server-side agent code will use the SpiceCharDeviceState api.

Notice that ignoring the server-side tokens didn't introduce a problem
since both the client and the server set it to ~0.
---
 server/main_channel.c |   32 +++++++++++++++++---------------
 server/main_channel.h |    2 +-
 server/reds.c         |   33 ++++++++++++++++++++++++++-------
 server/reds.h         |    3 ++-
 4 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/server/main_channel.c b/server/main_channel.c
index ace24ff..ce467f8 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -222,18 +222,13 @@ static PipeItem *main_ping_item_new(MainChannelClient *mcc, int size)
     return &item->base;
 }
 
-typedef struct MainTokensItemInfo {
-    uint32_t num_tokens;
-} MainTokensItemInfo;
-
-static PipeItem *main_tokens_item_new(RedChannelClient *rcc, void *data, int num)
+static PipeItem *main_agent_tokens_item_new(RedChannelClient *rcc, uint32_t num_tokens)
 {
     TokensPipeItem *item = spice_malloc(sizeof(TokensPipeItem));
-    MainTokensItemInfo *init = data;
 
     red_channel_pipe_item_init(rcc->channel, &item->base,
                                SPICE_MSG_MAIN_AGENT_TOKEN);
-    item->tokens = init->num_tokens;
+    item->tokens = num_tokens;
     return &item->base;
 }
 
@@ -422,13 +417,11 @@ static void main_channel_marshall_agent_disconnected(SpiceMarshaller *m)
     spice_marshall_msg_main_agent_disconnected(m, &disconnect);
 }
 
-// TODO: make this targeted (requires change to agent token accounting)
-void main_channel_push_tokens(MainChannel *main_chan, uint32_t num_tokens)
+void main_channel_client_push_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens)
 {
-    MainTokensItemInfo init = {.num_tokens = num_tokens};
+    PipeItem *item = main_agent_tokens_item_new(&mcc->base, num_tokens);
 
-    red_channel_pipes_new_add_push(&main_chan->base,
-        main_tokens_item_new, &init);
+    red_channel_client_pipe_add_push(&mcc->base, item);
 }
 
 static void main_channel_marshall_tokens(SpiceMarshaller *m, uint32_t num_tokens)
@@ -828,19 +821,28 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
     MainChannelClient *mcc = SPICE_CONTAINEROF(rcc, MainChannelClient, base);
 
     switch (type) {
-    case SPICE_MSGC_MAIN_AGENT_START:
+    case SPICE_MSGC_MAIN_AGENT_START: {
+        SpiceMsgcMainAgentStart *tokens;
+
         spice_printerr("agent start");
         if (!main_chan) {
             return FALSE;
         }
-        reds_on_main_agent_start();
+        tokens = (SpiceMsgcMainAgentStart *)message;
+        reds_on_main_agent_start(mcc, tokens->num_tokens);
         break;
+    }
     case SPICE_MSGC_MAIN_AGENT_DATA: {
         reds_on_main_agent_data(mcc, message, size);
         break;
     }
-    case SPICE_MSGC_MAIN_AGENT_TOKEN:
+    case SPICE_MSGC_MAIN_AGENT_TOKEN: {
+        SpiceMsgcMainAgentTokens *tokens;
+
+        tokens = (SpiceMsgcMainAgentTokens *)message;
+        reds_on_main_agent_tokens(mcc, tokens->num_tokens);
         break;
+    }
     case SPICE_MSGC_MAIN_ATTACH_CHANNELS:
         main_channel_push_channels(mcc);
         break;
diff --git a/server/main_channel.h b/server/main_channel.h
index afff313..7f620bb 100644
--- a/server/main_channel.h
+++ b/server/main_channel.h
@@ -72,7 +72,7 @@ void main_channel_close(MainChannel *main_chan); // not destroy, just socket clo
 void main_channel_push_mouse_mode(MainChannel *main_chan, int current_mode, int is_client_mouse_allowed);
 void main_channel_push_agent_connected(MainChannel *main_chan);
 void main_channel_push_agent_disconnected(MainChannel *main_chan);
-void main_channel_push_tokens(MainChannel *main_chan, uint32_t num_tokens);
+void main_channel_client_push_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens);
 void main_channel_push_agent_data(MainChannel *main_chan, uint8_t* data, size_t len,
            spice_marshaller_item_free_func free_data, void *opaque);
 void main_channel_client_start_net_test(MainChannelClient *mcc);
diff --git a/server/reds.c b/server/reds.c
index 26d6f89..9da8958 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -756,11 +756,13 @@ static void reds_agent_remove(void)
     }
 }
 
-static void reds_push_tokens(void)
+/* this will be fixed to handle multiple clients
+   in following patches */
+static void reds_push_tokens(MainChannelClient *mcc)
 {
     reds->agent_state.num_client_tokens += reds->agent_state.num_tokens;
     spice_assert(reds->agent_state.num_client_tokens <= REDS_AGENT_WINDOW_SIZE);
-    main_channel_push_tokens(reds->main_channel, reds->agent_state.num_tokens);
+    main_channel_client_push_agent_tokens(mcc, reds->agent_state.num_tokens);
     reds->agent_state.num_tokens = 0;
 }
 
@@ -998,12 +1000,14 @@ void reds_handle_agent_mouse_event(const VDAgentMouseState *mouse_state)
     write_to_vdi_port();
 }
 
-static void add_token(void)
+static void add_token(MainChannelClient *mcc)
 {
     VDIPortState *state = &reds->agent_state;
 
+    /* this will be fixed to handle multiple clients
+       in following patches */
     if (++state->num_tokens == REDS_TOKENS_TO_SEND) {
-        reds_push_tokens();
+        reds_push_tokens(mcc);
     }
 }
 
@@ -1012,6 +1016,7 @@ int reds_num_of_channels(void)
     return reds ? reds->num_of_channels : 0;
 }
 
+
 int reds_num_of_clients(void)
 {
     return reds ? reds->num_clients : 0;
@@ -1059,7 +1064,7 @@ void reds_fill_channels(SpiceMsgChannels *channels_info)
     }
 }
 
-void reds_on_main_agent_start(void)
+void reds_on_main_agent_start(MainChannelClient *mcc, uint32_t num_tokens)
 {
     if (!vdagent) {
         return;
@@ -1067,6 +1072,14 @@ void reds_on_main_agent_start(void)
     reds->agent_state.write_filter.discard_all = FALSE;
 }
 
+void reds_on_main_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens)
+{
+    if (!vdagent) {
+        return;
+    }
+    spice_printerr("to be implemented");
+}
+
 void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
 {
     // TODO - use mcc (and start tracking agent data per channel. probably just move the whole
@@ -1088,7 +1101,7 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
     case AGENT_MSG_FILTER_OK:
         break;
     case AGENT_MSG_FILTER_DISCARD:
-        add_token();
+        add_token(mcc);
         return;
     case AGENT_MSG_FILTER_PROTO_ERROR:
         reds_disconnect();
@@ -3577,9 +3590,15 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
 static void free_external_agent_buff(VDIPortBuf *in_buf)
 {
     VDIPortState *state = &reds->agent_state;
+    RedClient *random_client;
 
     ring_add(&state->external_bufs, &in_buf->link);
-    add_token();
+    /* this will be fixed to handle multiple clients
+       in following patches */
+    random_client = SPICE_CONTAINEROF(ring_get_tail(&reds->clients),
+                                      RedClient,
+                                      link);
+    add_token(red_client_get_main(random_client));
 }
 
 static void free_internal_agent_buff(VDIPortBuf *in_buf)
diff --git a/server/reds.h b/server/reds.h
index 1c59e68..674052a 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -145,7 +145,8 @@ void reds_update_stat_value(uint32_t value);
 
 /* callbacks from main channel messages */
 
-void reds_on_main_agent_start(void);
+void reds_on_main_agent_start(MainChannelClient *mcc, uint32_t num_tokens);
+void reds_on_main_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens);
 void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size);
 void reds_on_main_migrate_connected(void); //should be called when all the clients
                                            // are connected to the target
-- 
1.7.7.6



More information about the Spice-devel mailing list