summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2012-06-24 12:07:09 +0300
committerYonit Halperin <yhalperi@redhat.com>2012-07-03 14:13:41 +0300
commitfffa38672ce53c07a3341798e2bd66d806e8cf0d (patch)
tree2df692ee1395602daf0cc76a4cfb9991370e5d4c
parent50e3af6a995eb8aeee8bd8fb82a5cf6aa93f21cf (diff)
downloadspice-fffa38672ce53c07a3341798e2bd66d806e8cf0d.tar.gz
spice-fffa38672ce53c07a3341798e2bd66d806e8cf0d.tar.xz
spice-fffa38672ce53c07a3341798e2bd66d806e8cf0d.zip
agent: Fix tokens handling in main_channel
- 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.
-rw-r--r--server/main_channel.c32
-rw-r--r--server/main_channel.h2
-rw-r--r--server/reds.c33
-rw-r--r--server/reds.h3
4 files changed, 46 insertions, 24 deletions
diff --git a/server/main_channel.c b/server/main_channel.c
index ace24ff6..ce467f83 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 afff3139..7f620bba 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 26d6f89f..9da89580 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 1c59e689..674052a8 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