From 697c91db808446e1422dc5593c9f040e373e40bb Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 13 Dec 2010 23:08:57 +0100 Subject: client migration: switch host Implement server-side support for switch-host client migration. Client side support is present already in the tree. Setting the migration information is done using the existing spice_server_migrate_info() function. A new spice_server_migrate_switch() function has been added which triggers sending out the switch-host message. Seamless migration functions are left there for now. spice_server_migrate_start() has been chamnged to just fail unconditionally though as seamless migration is broken anyway. Signed-off-by: Gerd Hoffmann (cherry picked from commit 4b1ea4e102bb8a737487dab51dd0f3fc94352948) --- server/reds.c | 66 ++++++++++++++++++++++++++++++++++++++------- server/spice-experimental.h | 4 ++- 2 files changed, 59 insertions(+), 11 deletions(-) (limited to 'server') diff --git a/server/reds.c b/server/reds.c index 28409b93..601acc48 100644 --- a/server/reds.c +++ b/server/reds.c @@ -3238,6 +3238,7 @@ struct RedsMigSpice { char pub_key[SPICE_TICKET_PUBKEY_BYTES]; uint32_t mig_key; char *host; + char *cert_subject; int port; int sport; uint16_t cert_pub_key_type; @@ -3254,6 +3255,16 @@ typedef struct RedsMigCertPubKeyInfo { uint32_t len; } RedsMigCertPubKeyInfo; +static void reds_mig_release(void) +{ + if (reds->mig_spice) { + free(reds->mig_spice->cert_subject); + free(reds->mig_spice->host); + free(reds->mig_spice); + reds->mig_spice = NULL; + } +} + static void reds_mig_continue(void) { RedsMigSpice *s = reds->mig_spice; @@ -3274,9 +3285,7 @@ static void reds_mig_continue(void) reds_push_pipe_item(item); - free(reds->mig_spice->host); - free(reds->mig_spice); - reds->mig_spice = NULL; + reds_mig_release(); reds->mig_wait_connect = TRUE; core->timer_start(reds->mig_timer, MIGRATE_TIMEOUT); @@ -3311,11 +3320,7 @@ static void reds_mig_started(void) return; error: - if (reds->mig_spice) { - free(reds->mig_spice->host); - free(reds->mig_spice); - reds->mig_spice = NULL; - } + reds_mig_release(); reds_mig_disconnect(); } @@ -3362,6 +3367,33 @@ static void reds_mig_finished(int completed) } } +static void reds_mig_switch(void) +{ + RedsMigSpice *s = reds->mig_spice; + SpiceMsgMainMigrationSwitchHost migrate; + RedsOutItem *item; + + red_printf(""); + item = new_out_item(SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST); + + migrate.port = s->port; + migrate.sport = s->sport; + migrate.host_size = strlen(s->host) + 1; + migrate.host_data = (uint8_t *)s->host; + if (s->cert_subject) { + migrate.cert_subject_size = strlen(s->cert_subject) + 1; + migrate.cert_subject_data = (uint8_t *)s->cert_subject; + } else { + migrate.cert_subject_size = 0; + migrate.cert_subject_data = NULL; + } + spice_marshall_msg_main_migrate_switch_host(item->m, &migrate); + + reds_push_pipe_item(item); + + reds_mig_release(); +} + static void migrate_timout(void *opaque) { red_printf(""); @@ -4098,19 +4130,25 @@ __visible__ int spice_server_migrate_info(SpiceServer *s, const char* dest, spice_migration->port = port; spice_migration->sport = secure_port; spice_migration->host = strdup(dest); - if (cert_subject) { - /* TODO */ + spice_migration->cert_subject = strdup(cert_subject); } + reds_mig_release(); reds->mig_spice = spice_migration; return 0; } +/* interface for seamless migration */ __visible__ int spice_server_migrate_start(SpiceServer *s) { ASSERT(reds == s); + if (1) { + /* seamless doesn't work, fixing needs protocol change. */ + return -1; + } + if (!reds->mig_spice) { return -1; } @@ -4138,3 +4176,11 @@ __visible__ int spice_server_migrate_end(SpiceServer *s, int completed) reds_mig_finished(completed); return 0; } + +/* interface for switch-host migration */ +__visible__ int spice_server_migrate_switch(SpiceServer *s) +{ + ASSERT(reds == s); + reds_mig_switch(); + return 0; +} diff --git a/server/spice-experimental.h b/server/spice-experimental.h index 526062f3..70d22468 100644 --- a/server/spice-experimental.h +++ b/server/spice-experimental.h @@ -61,11 +61,13 @@ enum { SPICE_MIGRATE_CLIENT_READY, }; -int spice_server_migrate_info(SpiceServer *s, const char* dest, int port, int secure_port, +int spice_server_migrate_info(SpiceServer *s, const char* dest, + int port, int secure_port, const char* cert_subject); int spice_server_migrate_start(SpiceServer *s); int spice_server_migrate_client_state(SpiceServer *s); int spice_server_migrate_end(SpiceServer *s, int completed); +int spice_server_migrate_switch(SpiceServer *s); #endif // __SPICE_EXPERIMENTAL_H__ -- cgit