summaryrefslogtreecommitdiffstats
path: root/client/red_client.cpp
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2010-03-31 17:45:12 +0300
committerAlexander Larsson <alexl@redhat.com>2010-04-06 14:56:46 +0200
commit88aa56045a57e760beb35e659731741dc15f3aac (patch)
tree2444ebdcbd6aa35081b965ba699745c0c3b4bf42 /client/red_client.cpp
parent91bc0e8625d8878d93648dbb452c37fcf85305f5 (diff)
downloadspice-88aa56045a57e760beb35e659731741dc15f3aac.tar.gz
spice-88aa56045a57e760beb35e659731741dc15f3aac.tar.xz
spice-88aa56045a57e760beb35e659731741dc15f3aac.zip
client: handling SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST
disconnecting from the current host and connecting to the target host.
Diffstat (limited to 'client/red_client.cpp')
-rw-r--r--client/red_client.cpp42
1 files changed, 39 insertions, 3 deletions
diff --git a/client/red_client.cpp b/client/red_client.cpp
index 6a83a051..0844910c 100644
--- a/client/red_client.cpp
+++ b/client/red_client.cpp
@@ -178,7 +178,7 @@ void Migrate::run()
for (++iter; iter != _channels.end(); ++iter) {
conn_type = _client.get_connection_options((*iter)->get_type());
con_opt = RedPeer::ConnectionOptions(conn_type, _port, _sport,
- _auth_options, _con_ciphers);
+ _auth_options, _con_ciphers);
connect_one(**iter, con_opt, connection_id);
}
_connected = true;
@@ -332,6 +332,9 @@ RedClient::RedClient(Application& application)
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_BEGIN, &RedClient::handle_migrate_begin,
sizeof(SpiceMsgMainMigrationBegin));
message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_CANCEL, &RedClient::handle_migrate_cancel, 0);
+ message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST,
+ &RedClient::handle_migrate_switch_host,
+ sizeof(SpiceMsgMainMigrationSwitchHost));
message_loop->set_handler(SPICE_MSG_MAIN_INIT, &RedClient::handle_init, sizeof(SpiceMsgMainInit));
message_loop->set_handler(SPICE_MSG_MAIN_CHANNELS_LIST, &RedClient::handle_channels,
sizeof(SpiceMsgChannels));
@@ -437,11 +440,19 @@ RedPeer::ConnectionOptions::Type RedClient::get_connection_options(uint32_t chan
void RedClient::connect()
{
+ connect(false);
+}
+
+void RedClient::connect(bool wait_main_disconnect)
+{
+ // assumption: read _connection_id is atomic
if (_connection_id) {
- return;
+ if (!wait_main_disconnect) {
+ return;
+ }
}
- while (!abort_channels()) {
+ while (!abort_channels() || _connection_id) {
_application.process_events_queue();
Platform::msleep(100);
}
@@ -837,6 +848,31 @@ void RedClient::handle_agent_tokens(RedPeer::InMessage* message)
_agent_tokens += token->num_tokens;
}
+void RedClient::handle_migrate_switch_host(RedPeer::InMessage* message)
+{
+ SpiceMsgMainMigrationSwitchHost* migrate = (SpiceMsgMainMigrationSwitchHost*)message->data();
+ char* host = ((char*)migrate) + migrate->host_offset;
+ char* subject = NULL;
+
+ if (host[migrate->host_size - 1] != '\0') {
+ THROW("host is not a null-terminated string");
+ }
+
+ if (migrate->cert_subject_size) {
+ subject = ((char*)migrate)+ migrate->cert_subject_offset;
+ if (subject[migrate->cert_subject_size - 1] != '\0') {
+ THROW("cert subject is not a null-terminated string");
+ }
+ }
+
+ AutoRef<SwitchHostEvent> switch_event(new SwitchHostEvent(host,
+ migrate->port,
+ migrate->sport,
+ subject));
+ push_event(*switch_event);
+}
+
+
void RedClient::migrate_channel(RedChannel& channel)
{
DBG(0, "channel type %u id %u", channel.get_type(), channel.get_id());