These functions deals with client, not with entire channel. This avoid some poking some internals of MainChannelClient. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- server/main-channel-client.c | 375 +++++++++++++++++++++++++++++++++++++++++-- server/main-channel-client.h | 51 +----- server/main-channel.c | 353 +--------------------------------------- 3 files changed, 369 insertions(+), 410 deletions(-) diff --git a/server/main-channel-client.c b/server/main-channel-client.c index bac5316..67baa9e 100644 --- a/server/main-channel-client.c +++ b/server/main-channel-client.c @@ -19,8 +19,9 @@ #endif #include <inttypes.h> -#include "main-channel-client.h" -#include "main-channel-client.h" + +#include "common/generated_server_marshallers.h" + #include "main-channel.h" #include "reds.h" @@ -58,6 +59,53 @@ struct MainChannelClient { int seamless_mig_dst; }; +typedef struct RedPingPipeItem { + RedPipeItem base; + int size; +} RedPingPipeItem; + +typedef struct RedTokensPipeItem { + RedPipeItem base; + int tokens; +} RedTokensPipeItem; + +typedef struct RedAgentDataPipeItem { + RedPipeItem base; + uint8_t* data; + size_t len; + spice_marshaller_item_free_func free_data; + void *opaque; +} RedAgentDataPipeItem; + +typedef struct RedInitPipeItem { + RedPipeItem base; + int connection_id; + int display_channels_hint; + int current_mouse_mode; + int is_client_mouse_allowed; + int multi_media_time; + int ram_hint; +} RedInitPipeItem; + +typedef struct RedNamePipeItem { + RedPipeItem base; + SpiceMsgMainName msg; +} RedNamePipeItem; + +typedef struct RedUuidPipeItem { + RedPipeItem base; + SpiceMsgMainUuid msg; +} RedUuidPipeItem; + +typedef struct RedNotifyPipeItem { + RedPipeItem base; + char *msg; +} RedNotifyPipeItem; + +#define ZERO_BUF_SIZE 4096 + +static const uint8_t zero_page[ZERO_BUF_SIZE] = {0}; + static int main_channel_client_push_ping(MainChannelClient *mcc, int size); static RedPipeItem *main_notify_item_new(void *data, int num) @@ -330,11 +378,6 @@ void main_channel_client_handle_pong(MainChannelClient *mcc, SpiceMsgPing *ping, #endif } -gboolean main_channel_client_get_seamless_migration(MainChannelClient *mcc) -{ - return mcc->seamless_mig_dst; -} - void main_channel_client_handle_migrate_end(MainChannelClient *mcc) { if (!red_client_during_migrate_at_target(mcc->base.client)) { @@ -533,17 +576,325 @@ uint32_t main_channel_client_get_connection_id(MainChannelClient *mcc) return mcc->connection_id; } -uint32_t main_channel_client_next_ping_id(MainChannelClient *mcc) +static uint32_t main_channel_client_next_ping_id(MainChannelClient *mcc) { return ++mcc->ping_id; } -void main_channel_client_on_send_init(MainChannelClient *mcc) +static void main_channel_marshall_channels(RedChannelClient *rcc, + SpiceMarshaller *m, + RedPipeItem *item) +{ + SpiceMsgChannels* channels_info; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_CHANNELS_LIST, item); + channels_info = reds_msg_channels_new(rcc->channel->reds); + spice_marshall_msg_main_channels_list(m, channels_info); + free(channels_info); +} + +static void main_channel_marshall_ping(RedChannelClient *rcc, + SpiceMarshaller *m, + RedPingPipeItem *item) +{ + MainChannelClient *mcc = (MainChannelClient*)rcc; + SpiceMsgPing ping; + int size_left = item->size; + + red_channel_client_init_send_data(rcc, SPICE_MSG_PING, &item->base); + ping.id = main_channel_client_next_ping_id(mcc); + ping.timestamp = g_get_monotonic_time(); + spice_marshall_msg_ping(m, &ping); + + while (size_left > 0) { + int now = MIN(ZERO_BUF_SIZE, size_left); + size_left -= now; + spice_marshaller_add_ref(m, zero_page, now); + } +} + +static void main_channel_marshall_mouse_mode(RedChannelClient *rcc, + SpiceMarshaller *m, + RedMouseModePipeItem *item) +{ + SpiceMsgMainMouseMode mouse_mode; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MOUSE_MODE, &item->base); + mouse_mode.supported_modes = SPICE_MOUSE_MODE_SERVER; + if (item->is_client_mouse_allowed) { + mouse_mode.supported_modes |= SPICE_MOUSE_MODE_CLIENT; + } + mouse_mode.current_mode = item->current_mode; + spice_marshall_msg_main_mouse_mode(m, &mouse_mode); +} + +static void main_channel_marshall_agent_disconnected(RedChannelClient *rcc, + SpiceMarshaller *m, + RedPipeItem *item) +{ + SpiceMsgMainAgentDisconnect disconnect; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_DISCONNECTED, item); + disconnect.error_code = SPICE_LINK_ERR_OK; + spice_marshall_msg_main_agent_disconnected(m, &disconnect); +} + +static void main_channel_marshall_tokens(RedChannelClient *rcc, + SpiceMarshaller *m, RedTokensPipeItem *item) +{ + SpiceMsgMainAgentTokens tokens; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_TOKEN, &item->base); + tokens.num_tokens = item->tokens; + spice_marshall_msg_main_agent_token(m, &tokens); +} + +static void main_channel_marshall_agent_data(RedChannelClient *rcc, + SpiceMarshaller *m, + RedAgentDataPipeItem *item) +{ + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_DATA, &item->base); + spice_marshaller_add_ref(m, item->data, item->len); +} + +static void main_channel_marshall_migrate_data_item(RedChannelClient *rcc, + SpiceMarshaller *m, + RedPipeItem *item) +{ + red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, item); + reds_marshall_migrate_data(rcc->channel->reds, m); // TODO: from reds split. ugly separation. +} + +static void main_channel_marshall_init(RedChannelClient *rcc, + SpiceMarshaller *m, + RedInitPipeItem *item) +{ + SpiceMsgMainInit init; // TODO - remove this copy, make RedInitPipeItem reuse SpiceMsgMainInit + + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_INIT, &item->base); + init.session_id = item->connection_id; + init.display_channels_hint = item->display_channels_hint; + init.current_mouse_mode = item->current_mouse_mode; + init.supported_mouse_modes = SPICE_MOUSE_MODE_SERVER; + if (item->is_client_mouse_allowed) { + init.supported_mouse_modes |= SPICE_MOUSE_MODE_CLIENT; + } + init.agent_connected = reds_has_vdagent(rcc->channel->reds); + init.agent_tokens = REDS_AGENT_WINDOW_SIZE; + init.multi_media_time = item->multi_media_time; + init.ram_hint = item->ram_hint; + spice_marshall_msg_main_init(m, &init); +} + +static void main_channel_marshall_notify(RedChannelClient *rcc, + SpiceMarshaller *m, RedNotifyPipeItem *item) +{ + SpiceMsgNotify notify; + + red_channel_client_init_send_data(rcc, SPICE_MSG_NOTIFY, &item->base); + notify.time_stamp = spice_get_monotonic_time_ns(); // TODO - move to main_new_notify_item + notify.severity = SPICE_NOTIFY_SEVERITY_WARN; + notify.visibilty = SPICE_NOTIFY_VISIBILITY_HIGH; + notify.what = SPICE_WARN_GENERAL; + notify.message_len = strlen(item->msg); + spice_marshall_msg_notify(m, ¬ify); + spice_marshaller_add(m, (uint8_t *)item->msg, notify.message_len + 1); +} + +static void main_channel_fill_migrate_dst_info(MainChannel *main_channel, + SpiceMigrationDstInfo *dst_info) +{ + RedsMigSpice *mig_dst = &main_channel->mig_target; + dst_info->port = mig_dst->port; + dst_info->sport = mig_dst->sport; + dst_info->host_size = strlen(mig_dst->host) + 1; + dst_info->host_data = (uint8_t *)mig_dst->host; + if (mig_dst->cert_subject) { + dst_info->cert_subject_size = strlen(mig_dst->cert_subject) + 1; + dst_info->cert_subject_data = (uint8_t *)mig_dst->cert_subject; + } else { + dst_info->cert_subject_size = 0; + dst_info->cert_subject_data = NULL; + } +} + +static void main_channel_marshall_migrate_begin(SpiceMarshaller *m, RedChannelClient *rcc, + RedPipeItem *item) { - mcc->init_sent = TRUE; + SpiceMsgMainMigrationBegin migrate; + MainChannel *main_ch; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_BEGIN, item); + main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); + main_channel_fill_migrate_dst_info(main_ch, &migrate.dst_info); + spice_marshall_msg_main_migrate_begin(m, &migrate); } -gboolean main_channel_client_get_init_sent(MainChannelClient *mcc) +static void main_channel_marshall_migrate_begin_seamless(SpiceMarshaller *m, + RedChannelClient *rcc, + RedPipeItem *item) { - return mcc->init_sent; + SpiceMsgMainMigrateBeginSeamless migrate_seamless; + MainChannel *main_ch; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS, item); + main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); + main_channel_fill_migrate_dst_info(main_ch, &migrate_seamless.dst_info); + migrate_seamless.src_mig_version = SPICE_MIGRATION_PROTOCOL_VERSION; + spice_marshall_msg_main_migrate_begin_seamless(m, &migrate_seamless); +} + +static void main_channel_marshall_multi_media_time(RedChannelClient *rcc, + SpiceMarshaller *m, + RedMultiMediaTimePipeItem *item) +{ + SpiceMsgMainMultiMediaTime time_mes; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MULTI_MEDIA_TIME, &item->base); + time_mes.time = item->time; + spice_marshall_msg_main_multi_media_time(m, &time_mes); +} + +static void main_channel_marshall_migrate_switch(SpiceMarshaller *m, RedChannelClient *rcc, + RedPipeItem *item) +{ + SpiceMsgMainMigrationSwitchHost migrate; + MainChannel *main_ch; + + spice_printerr(""); + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST, item); + main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); + migrate.port = main_ch->mig_target.port; + migrate.sport = main_ch->mig_target.sport; + migrate.host_size = strlen(main_ch->mig_target.host) + 1; + migrate.host_data = (uint8_t *)main_ch->mig_target.host; + if (main_ch->mig_target.cert_subject) { + migrate.cert_subject_size = strlen(main_ch->mig_target.cert_subject) + 1; + migrate.cert_subject_data = (uint8_t *)main_ch->mig_target.cert_subject; + } else { + migrate.cert_subject_size = 0; + migrate.cert_subject_data = NULL; + } + spice_marshall_msg_main_migrate_switch_host(m, &migrate); } + +static void main_channel_marshall_agent_connected(SpiceMarshaller *m, + RedChannelClient *rcc, + RedPipeItem *item) +{ + SpiceMsgMainAgentConnectedTokens connected; + + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS, item); + connected.num_tokens = REDS_AGENT_WINDOW_SIZE; + spice_marshall_msg_main_agent_connected_tokens(m, &connected); +} + +void main_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *base) +{ + MainChannelClient *mcc = SPICE_CONTAINEROF(rcc, MainChannelClient, base); + SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); + + /* In semi-seamless migration (dest side), the connection is started from scratch, and + * we ignore any pipe item that arrives before the INIT msg is sent. + * For seamless we don't send INIT, and the connection continues from the same place + * it stopped on the src side. */ + if (!mcc->init_sent && + !mcc->seamless_mig_dst && + base->type != RED_PIPE_ITEM_TYPE_MAIN_INIT) { + spice_printerr("Init msg for client %p was not sent yet " + "(client is probably during semi-seamless migration). Ignoring msg type %d", + rcc->client, base->type); + main_channel_client_release_pipe_item(rcc, base, FALSE); + return; + } + switch (base->type) { + case RED_PIPE_ITEM_TYPE_MAIN_CHANNELS_LIST: + main_channel_marshall_channels(rcc, m, base); + break; + case RED_PIPE_ITEM_TYPE_MAIN_PING: + main_channel_marshall_ping(rcc, m, + SPICE_CONTAINEROF(base, RedPingPipeItem, base)); + break; + case RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE: + { + RedMouseModePipeItem *item = + SPICE_CONTAINEROF(base, RedMouseModePipeItem, base); + main_channel_marshall_mouse_mode(rcc, m, item); + break; + } + case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DISCONNECTED: + main_channel_marshall_agent_disconnected(rcc, m, base); + break; + case RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN: + main_channel_marshall_tokens(rcc, m, + SPICE_CONTAINEROF(base, RedTokensPipeItem, base)); + break; + case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA: + main_channel_marshall_agent_data(rcc, m, + SPICE_CONTAINEROF(base, RedAgentDataPipeItem, base)); + break; + case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_DATA: + main_channel_marshall_migrate_data_item(rcc, m, base); + break; + case RED_PIPE_ITEM_TYPE_MAIN_INIT: + mcc->init_sent = TRUE; + main_channel_marshall_init(rcc, m, + SPICE_CONTAINEROF(base, RedInitPipeItem, base)); + break; + case RED_PIPE_ITEM_TYPE_MAIN_NOTIFY: + main_channel_marshall_notify(rcc, m, + SPICE_CONTAINEROF(base, RedNotifyPipeItem, base)); + break; + case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN: + main_channel_marshall_migrate_begin(m, rcc, base); + break; + case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN_SEAMLESS: + main_channel_marshall_migrate_begin_seamless(m, rcc, base); + break; + case RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME: + main_channel_marshall_multi_media_time(rcc, m, + SPICE_CONTAINEROF(base, RedMultiMediaTimePipeItem, base)); + break; + case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_SWITCH_HOST: + main_channel_marshall_migrate_switch(m, rcc, base); + break; + case RED_PIPE_ITEM_TYPE_MAIN_NAME: + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_NAME, base); + spice_marshall_msg_main_name(m, &SPICE_CONTAINEROF(base, RedNamePipeItem, base)->msg); + break; + case RED_PIPE_ITEM_TYPE_MAIN_UUID: + red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_UUID, base); + spice_marshall_msg_main_uuid(m, &SPICE_CONTAINEROF(base, RedUuidPipeItem, base)->msg); + break; + case RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS: + main_channel_marshall_agent_connected(m, rcc, base); + break; + default: + break; + }; + red_channel_client_begin_send_message(rcc); +} + +void main_channel_client_release_pipe_item(RedChannelClient *rcc, + RedPipeItem *base, int item_pushed) +{ + switch (base->type) { + case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA: { + RedAgentDataPipeItem *data = (RedAgentDataPipeItem *)base; + + data->free_data(data->data, data->opaque); + break; + } + case RED_PIPE_ITEM_TYPE_MAIN_NOTIFY: { + RedNotifyPipeItem *data = (RedNotifyPipeItem *)base; + free(data->msg); + break; + } + default: + break; + } + free(base); +} + + diff --git a/server/main-channel-client.h b/server/main-channel-client.h index 7e4daf9..5bbaac6 100644 --- a/server/main-channel-client.h +++ b/server/main-channel-client.h @@ -71,11 +71,9 @@ void main_channel_client_push_name(MainChannelClient *mcc, const char *name); void main_channel_client_push_uuid(MainChannelClient *mcc, const uint8_t uuid[16]); uint32_t main_channel_client_get_connection_id(MainChannelClient *mcc); -uint32_t main_channel_client_next_ping_id(MainChannelClient *mcc); - -gboolean main_channel_client_get_seamless_migration(MainChannelClient *mcc); -void main_channel_client_on_send_init(MainChannelClient *mcc); -gboolean main_channel_client_get_init_sent(MainChannelClient *mcc); +void main_channel_client_release_pipe_item(RedChannelClient *rcc, + RedPipeItem *base, int item_pushed); +void main_channel_client_send_item(RedChannelClient *rcc, RedPipeItem *base); enum { RED_PIPE_ITEM_TYPE_MAIN_CHANNELS_LIST = RED_PIPE_ITEM_TYPE_CHANNEL_BASE, @@ -96,55 +94,12 @@ enum { RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS, }; -typedef struct RedPingPipeItem { - RedPipeItem base; - int size; -} RedPingPipeItem; - typedef struct RedMouseModePipeItem { RedPipeItem base; int current_mode; int is_client_mouse_allowed; } RedMouseModePipeItem; -typedef struct RedTokensPipeItem { - RedPipeItem base; - int tokens; -} RedTokensPipeItem; - -typedef struct RedAgentDataPipeItem { - RedPipeItem base; - uint8_t* data; - size_t len; - spice_marshaller_item_free_func free_data; - void *opaque; -} RedAgentDataPipeItem; - -typedef struct RedInitPipeItem { - RedPipeItem base; - int connection_id; - int display_channels_hint; - int current_mouse_mode; - int is_client_mouse_allowed; - int multi_media_time; - int ram_hint; -} RedInitPipeItem; - -typedef struct RedNamePipeItem { - RedPipeItem base; - SpiceMsgMainName msg; -} RedNamePipeItem; - -typedef struct RedUuidPipeItem { - RedPipeItem base; - SpiceMsgMainUuid msg; -} RedUuidPipeItem; - -typedef struct RedNotifyPipeItem { - RedPipeItem base; - char *msg; -} RedNotifyPipeItem; - typedef struct RedMultiMediaTimePipeItem { RedPipeItem base; int time; diff --git a/server/main-channel.c b/server/main-channel.c index f762b18..750a87c 100644 --- a/server/main-channel.c +++ b/server/main-channel.c @@ -19,42 +19,11 @@ #include <config.h> #endif -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <limits.h> -#include <pthread.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> - -#include "common/generated_server_marshallers.h" -#include "common/messages.h" +#include "red-common.h" #include "common/ring.h" -#include "demarshallers.h" #include "main-channel.h" -#include "main-channel-client.h" -#include "red-channel.h" -#include "red-common.h" #include "reds.h" -#include "migration-protocol.h" -#include "main-dispatcher.h" -#include "utils.h" - -#define ZERO_BUF_SIZE 4096 - -static const uint8_t zero_page[ZERO_BUF_SIZE] = {0}; - -static void main_channel_release_pipe_item(RedChannelClient *rcc, - RedPipeItem *base, int item_pushed); int main_channel_is_connected(MainChannel *main_chan) { @@ -124,38 +93,6 @@ static void main_channel_push_channels(MainChannelClient *mcc) red_channel_client_pipe_add_type(main_channel_client_get_base(mcc), RED_PIPE_ITEM_TYPE_MAIN_CHANNELS_LIST); } -static void main_channel_marshall_channels(RedChannelClient *rcc, - SpiceMarshaller *m, - RedPipeItem *item) -{ - SpiceMsgChannels* channels_info; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_CHANNELS_LIST, item); - channels_info = reds_msg_channels_new(rcc->channel->reds); - spice_marshall_msg_main_channels_list(m, channels_info); - free(channels_info); -} - -static void main_channel_marshall_ping(RedChannelClient *rcc, - SpiceMarshaller *m, - RedPingPipeItem *item) -{ - MainChannelClient *mcc = (MainChannelClient*)rcc; - SpiceMsgPing ping; - int size_left = item->size; - - red_channel_client_init_send_data(rcc, SPICE_MSG_PING, &item->base); - ping.id = main_channel_client_next_ping_id(mcc); - ping.timestamp = g_get_monotonic_time(); - spice_marshall_msg_ping(m, &ping); - - while (size_left > 0) { - int now = MIN(ZERO_BUF_SIZE, size_left); - size_left -= now; - spice_marshaller_add_ref(m, zero_page, now); - } -} - void main_channel_push_mouse_mode(MainChannel *main_chan, int current_mode, int is_client_mouse_allowed) { @@ -168,21 +105,6 @@ void main_channel_push_mouse_mode(MainChannel *main_chan, int current_mode, main_mouse_mode_item_new, &info); } -static void main_channel_marshall_mouse_mode(RedChannelClient *rcc, - SpiceMarshaller *m, - RedMouseModePipeItem *item) -{ - SpiceMsgMainMouseMode mouse_mode; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MOUSE_MODE, &item->base); - mouse_mode.supported_modes = SPICE_MOUSE_MODE_SERVER; - if (item->is_client_mouse_allowed) { - mouse_mode.supported_modes |= SPICE_MOUSE_MODE_CLIENT; - } - mouse_mode.current_mode = item->current_mode; - spice_marshall_msg_main_mouse_mode(m, &mouse_mode); -} - void main_channel_push_agent_connected(MainChannel *main_chan) { if (red_channel_test_remote_cap(&main_chan->base, SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS)) { @@ -192,64 +114,16 @@ void main_channel_push_agent_connected(MainChannel *main_chan) } } -static void main_channel_marshall_agent_connected(SpiceMarshaller *m, - RedChannelClient *rcc, - RedPipeItem *item) -{ - SpiceMsgMainAgentConnectedTokens connected; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS, item); - connected.num_tokens = REDS_AGENT_WINDOW_SIZE; - spice_marshall_msg_main_agent_connected_tokens(m, &connected); -} - void main_channel_push_agent_disconnected(MainChannel *main_chan) { red_channel_pipes_add_type(&main_chan->base, RED_PIPE_ITEM_TYPE_MAIN_AGENT_DISCONNECTED); } -static void main_channel_marshall_agent_disconnected(RedChannelClient *rcc, - SpiceMarshaller *m, - RedPipeItem *item) -{ - SpiceMsgMainAgentDisconnect disconnect; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_DISCONNECTED, item); - disconnect.error_code = SPICE_LINK_ERR_OK; - spice_marshall_msg_main_agent_disconnected(m, &disconnect); -} - -static void main_channel_marshall_tokens(RedChannelClient *rcc, - SpiceMarshaller *m, RedTokensPipeItem *item) -{ - SpiceMsgMainAgentTokens tokens; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_TOKEN, &item->base); - tokens.num_tokens = item->tokens; - spice_marshall_msg_main_agent_token(m, &tokens); -} - -static void main_channel_marshall_agent_data(RedChannelClient *rcc, - SpiceMarshaller *m, - RedAgentDataPipeItem *item) -{ - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_AGENT_DATA, &item->base); - spice_marshaller_add_ref(m, item->data, item->len); -} - static void main_channel_push_migrate_data_item(MainChannel *main_chan) { red_channel_pipes_add_type(&main_chan->base, RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_DATA); } -static void main_channel_marshall_migrate_data_item(RedChannelClient *rcc, - SpiceMarshaller *m, - RedPipeItem *item) -{ - red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, item); - reds_marshall_migrate_data(rcc->channel->reds, m); // TODO: from reds split. ugly separation. -} - static int main_channel_handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message) { @@ -272,86 +146,6 @@ static int main_channel_handle_migrate_data(RedChannelClient *rcc, return reds_handle_migrate_data(rcc->channel->reds, mcc, (SpiceMigrateDataMain *)(header + 1), size); } -static void main_channel_marshall_init(RedChannelClient *rcc, - SpiceMarshaller *m, - RedInitPipeItem *item) -{ - SpiceMsgMainInit init; // TODO - remove this copy, make RedInitPipeItem reuse SpiceMsgMainInit - - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_INIT, &item->base); - init.session_id = item->connection_id; - init.display_channels_hint = item->display_channels_hint; - init.current_mouse_mode = item->current_mouse_mode; - init.supported_mouse_modes = SPICE_MOUSE_MODE_SERVER; - if (item->is_client_mouse_allowed) { - init.supported_mouse_modes |= SPICE_MOUSE_MODE_CLIENT; - } - init.agent_connected = reds_has_vdagent(rcc->channel->reds); - init.agent_tokens = REDS_AGENT_WINDOW_SIZE; - init.multi_media_time = item->multi_media_time; - init.ram_hint = item->ram_hint; - spice_marshall_msg_main_init(m, &init); -} - -static void main_channel_marshall_notify(RedChannelClient *rcc, - SpiceMarshaller *m, RedNotifyPipeItem *item) -{ - SpiceMsgNotify notify; - - red_channel_client_init_send_data(rcc, SPICE_MSG_NOTIFY, &item->base); - notify.time_stamp = spice_get_monotonic_time_ns(); // TODO - move to main_new_notify_item - notify.severity = SPICE_NOTIFY_SEVERITY_WARN; - notify.visibilty = SPICE_NOTIFY_VISIBILITY_HIGH; - notify.what = SPICE_WARN_GENERAL; - notify.message_len = strlen(item->msg); - spice_marshall_msg_notify(m, ¬ify); - spice_marshaller_add(m, (uint8_t *)item->msg, notify.message_len + 1); -} - -static void main_channel_fill_migrate_dst_info(MainChannel *main_channel, - SpiceMigrationDstInfo *dst_info) -{ - RedsMigSpice *mig_dst = &main_channel->mig_target; - dst_info->port = mig_dst->port; - dst_info->sport = mig_dst->sport; - dst_info->host_size = strlen(mig_dst->host) + 1; - dst_info->host_data = (uint8_t *)mig_dst->host; - if (mig_dst->cert_subject) { - dst_info->cert_subject_size = strlen(mig_dst->cert_subject) + 1; - dst_info->cert_subject_data = (uint8_t *)mig_dst->cert_subject; - } else { - dst_info->cert_subject_size = 0; - dst_info->cert_subject_data = NULL; - } -} - -static void main_channel_marshall_migrate_begin(SpiceMarshaller *m, RedChannelClient *rcc, - RedPipeItem *item) -{ - SpiceMsgMainMigrationBegin migrate; - MainChannel *main_ch; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_BEGIN, item); - main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); - main_channel_fill_migrate_dst_info(main_ch, &migrate.dst_info); - spice_marshall_msg_main_migrate_begin(m, &migrate); -} - -static void main_channel_marshall_migrate_begin_seamless(SpiceMarshaller *m, - RedChannelClient *rcc, - RedPipeItem *item) -{ - SpiceMsgMainMigrateBeginSeamless migrate_seamless; - MainChannel *main_ch; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS, item); - main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); - main_channel_fill_migrate_dst_info(main_ch, &migrate_seamless.dst_info); - migrate_seamless.src_mig_version = SPICE_MIGRATION_PROTOCOL_VERSION; - spice_marshall_msg_main_migrate_begin_seamless(m, &migrate_seamless); -} - void main_channel_push_multi_media_time(MainChannel *main_chan, int time) { RedMultiMediaTimePipeItem info = { @@ -383,147 +177,6 @@ void main_channel_migrate_switch(MainChannel *main_chan, RedsMigSpice *mig_targe red_channel_pipes_add_type(&main_chan->base, RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_SWITCH_HOST); } -static void main_channel_marshall_migrate_switch(SpiceMarshaller *m, RedChannelClient *rcc, - RedPipeItem *item) -{ - SpiceMsgMainMigrationSwitchHost migrate; - MainChannel *main_ch; - - spice_printerr(""); - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST, item); - main_ch = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); - migrate.port = main_ch->mig_target.port; - migrate.sport = main_ch->mig_target.sport; - migrate.host_size = strlen(main_ch->mig_target.host) + 1; - migrate.host_data = (uint8_t *)main_ch->mig_target.host; - if (main_ch->mig_target.cert_subject) { - migrate.cert_subject_size = strlen(main_ch->mig_target.cert_subject) + 1; - migrate.cert_subject_data = (uint8_t *)main_ch->mig_target.cert_subject; - } else { - migrate.cert_subject_size = 0; - migrate.cert_subject_data = NULL; - } - spice_marshall_msg_main_migrate_switch_host(m, &migrate); -} - -static void main_channel_marshall_multi_media_time(RedChannelClient *rcc, - SpiceMarshaller *m, - RedMultiMediaTimePipeItem *item) -{ - SpiceMsgMainMultiMediaTime time_mes; - - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_MULTI_MEDIA_TIME, &item->base); - time_mes.time = item->time; - spice_marshall_msg_main_multi_media_time(m, &time_mes); -} - -static void main_channel_send_item(RedChannelClient *rcc, RedPipeItem *base) -{ - MainChannelClient *mcc = (MainChannelClient*)rcc; - SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); - - /* In semi-seamless migration (dest side), the connection is started from scratch, and - * we ignore any pipe item that arrives before the INIT msg is sent. - * For seamless we don't send INIT, and the connection continues from the same place - * it stopped on the src side. */ - if (!main_channel_client_get_init_sent(mcc) && - !main_channel_client_get_seamless_migration(mcc) && - base->type != RED_PIPE_ITEM_TYPE_MAIN_INIT) { - spice_printerr("Init msg for client %p was not sent yet " - "(client is probably during semi-seamless migration). Ignoring msg type %d", - rcc->client, base->type); - main_channel_release_pipe_item(rcc, base, FALSE); - return; - } - switch (base->type) { - case RED_PIPE_ITEM_TYPE_MAIN_CHANNELS_LIST: - main_channel_marshall_channels(rcc, m, base); - break; - case RED_PIPE_ITEM_TYPE_MAIN_PING: - main_channel_marshall_ping(rcc, m, - SPICE_CONTAINEROF(base, RedPingPipeItem, base)); - break; - case RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE: - { - RedMouseModePipeItem *item = - SPICE_CONTAINEROF(base, RedMouseModePipeItem, base); - main_channel_marshall_mouse_mode(rcc, m, item); - break; - } - case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DISCONNECTED: - main_channel_marshall_agent_disconnected(rcc, m, base); - break; - case RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN: - main_channel_marshall_tokens(rcc, m, - SPICE_CONTAINEROF(base, RedTokensPipeItem, base)); - break; - case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA: - main_channel_marshall_agent_data(rcc, m, - SPICE_CONTAINEROF(base, RedAgentDataPipeItem, base)); - break; - case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_DATA: - main_channel_marshall_migrate_data_item(rcc, m, base); - break; - case RED_PIPE_ITEM_TYPE_MAIN_INIT: - main_channel_client_on_send_init(mcc); - main_channel_marshall_init(rcc, m, - SPICE_CONTAINEROF(base, RedInitPipeItem, base)); - break; - case RED_PIPE_ITEM_TYPE_MAIN_NOTIFY: - main_channel_marshall_notify(rcc, m, - SPICE_CONTAINEROF(base, RedNotifyPipeItem, base)); - break; - case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN: - main_channel_marshall_migrate_begin(m, rcc, base); - break; - case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN_SEAMLESS: - main_channel_marshall_migrate_begin_seamless(m, rcc, base); - break; - case RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME: - main_channel_marshall_multi_media_time(rcc, m, - SPICE_CONTAINEROF(base, RedMultiMediaTimePipeItem, base)); - break; - case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_SWITCH_HOST: - main_channel_marshall_migrate_switch(m, rcc, base); - break; - case RED_PIPE_ITEM_TYPE_MAIN_NAME: - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_NAME, base); - spice_marshall_msg_main_name(m, &SPICE_CONTAINEROF(base, RedNamePipeItem, base)->msg); - break; - case RED_PIPE_ITEM_TYPE_MAIN_UUID: - red_channel_client_init_send_data(rcc, SPICE_MSG_MAIN_UUID, base); - spice_marshall_msg_main_uuid(m, &SPICE_CONTAINEROF(base, RedUuidPipeItem, base)->msg); - break; - case RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS: - main_channel_marshall_agent_connected(m, rcc, base); - break; - default: - break; - }; - red_channel_client_begin_send_message(rcc); -} - -static void main_channel_release_pipe_item(RedChannelClient *rcc, - RedPipeItem *base, int item_pushed) -{ - switch (base->type) { - case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA: { - RedAgentDataPipeItem *data = (RedAgentDataPipeItem *)base; - - data->free_data(data->data, data->opaque); - break; - } - case RED_PIPE_ITEM_TYPE_MAIN_NOTIFY: { - RedNotifyPipeItem *data = (RedNotifyPipeItem *)base; - free(data->msg); - break; - } - default: - break; - } - free(base); -} - static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t type, void *message) { @@ -679,9 +332,9 @@ MainChannel* main_channel_new(RedsState *reds) channel_cbs.config_socket = main_channel_config_socket; channel_cbs.on_disconnect = main_channel_client_on_disconnect; - channel_cbs.send_item = main_channel_send_item; + channel_cbs.send_item = main_channel_client_send_item; channel_cbs.hold_item = main_channel_hold_pipe_item; - channel_cbs.release_item = main_channel_release_pipe_item; + channel_cbs.release_item = main_channel_client_release_pipe_item; channel_cbs.alloc_recv_buf = main_channel_alloc_msg_rcv_buf; channel_cbs.release_recv_buf = main_channel_release_msg_rcv_buf; channel_cbs.handle_migrate_flush_mark = main_channel_handle_migrate_flush_mark; -- 2.5.5 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel