From 27b7077c363d07d1cd861cb0008eb35acea49970 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 23 Aug 2016 13:02:07 +0200 Subject: [PATCH] Add versioning into remote server protocol --- renderdoc/api/replay/replay_enums.h | 1 + renderdoc/core/core.cpp | 1 + renderdoc/core/remote_server.cpp | 59 +++++++++++++++++--- renderdocui/Code/PersistantConfig.cs | 10 +++- renderdocui/Interop/Enums.cs | 2 + renderdocui/Windows/Dialogs/RemoteManager.cs | 2 + renderdocui/Windows/MainWindow.cs | 6 +- 7 files changed, 72 insertions(+), 9 deletions(-) diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 0909b5f51..ae76fd232 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -509,6 +509,7 @@ enum ReplayCreateStatus eReplayCreate_IncompatibleProcess, eReplayCreate_NetworkIOFailed, eReplayCreate_NetworkRemoteBusy, + eReplayCreate_NetworkVersionMismatch, eReplayCreate_FileIOFailed, eReplayCreate_FileIncompatibleVersion, eReplayCreate_FileCorrupted, diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 1f72be7f9..23bc14942 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -108,6 +108,7 @@ string ToStrHelper::Get(const ReplayCreateStatus &el) case eReplayCreate_IncompatibleProcess: return "Process is incompatible"; case eReplayCreate_NetworkIOFailed: return "Network I/O operation failed"; case eReplayCreate_NetworkRemoteBusy: return "Remote side of network connection is busy"; + case eReplayCreate_NetworkVersionMismatch: return "Version mismatch between network clients"; case eReplayCreate_FileIOFailed: return "File I/O failed"; case eReplayCreate_FileIncompatibleVersion: return "File of incompatible version"; case eReplayCreate_FileCorrupted: return "File corrupted"; diff --git a/renderdoc/core/remote_server.cpp b/renderdoc/core/remote_server.cpp index fb8388139..09b8c1c0b 100644 --- a/renderdoc/core/remote_server.cpp +++ b/renderdoc/core/remote_server.cpp @@ -66,11 +66,15 @@ void Serialiser::Serialise(const char *name, Process::EnvironmentModification &e Serialise("value", el.value); } +static const uint32_t RemoteServerProtocolVersion = 1; + enum RemoteServerPacket { eRemoteServer_Noop, eRemoteServer_Handshake, + eRemoteServer_VersionMismatch, eRemoteServer_Busy, + eRemoteServer_RemoteDriverList, eRemoteServer_TakeOwnershipCapture, eRemoteServer_CopyCaptureToRemote, @@ -140,16 +144,31 @@ static void InactiveRemoteClientThread(void *data) // this thread just handles receiving the handshake and sending a busy signal without blocking the // server thread - RemoteServerPacket type = (RemoteServerPacket)RecvPacket(threadData->socket); + RemoteServerPacket type = eRemoteServer_Noop; + Serialiser *recvser = NULL; - if(type != eRemoteServer_Handshake) + if(!RecvPacket(threadData->socket, type, &recvser) || type != eRemoteServer_Handshake) { RDCWARN("Didn't receive proper handshake"); SAFE_DELETE(threadData->socket); return; } - SendPacket(threadData->socket, eRemoteServer_Busy); + uint32_t version = 0; + recvser->Serialise("version", version); + + SAFE_DELETE(recvser); + + if(version != RemoteServerProtocolVersion) + { + RDCLOG("Connection using protocol %u, but we are running %u", version, + RemoteServerProtocolVersion); + SendPacket(threadData->socket, eRemoteServer_VersionMismatch); + } + else + { + SendPacket(threadData->socket, eRemoteServer_Busy); + } SAFE_DELETE(threadData->socket); @@ -165,16 +184,34 @@ static void ActiveRemoteClientThread(void *data) uint32_t ip = client->GetRemoteIP(); - RemoteServerPacket type = (RemoteServerPacket)RecvPacket(client); + RemoteServerPacket type = eRemoteServer_Noop; + Serialiser *handshakeSer = NULL; - if(type != eRemoteServer_Handshake) + if(!RecvPacket(threadData->socket, type, &handshakeSer) || type != eRemoteServer_Handshake) { RDCWARN("Didn't receive proper handshake"); SAFE_DELETE(client); return; } - SendPacket(client, eRemoteServer_Handshake); + uint32_t version = 0; + handshakeSer->Serialise("version", version); + + SAFE_DELETE(handshakeSer); + + if(version != RemoteServerProtocolVersion) + { + RDCLOG("Connection using protocol %u, but we are running %u", version, + RemoteServerProtocolVersion); + SendPacket(threadData->socket, eRemoteServer_VersionMismatch); + SAFE_DELETE(client); + return; + } + else + { + // handshake and continue + SendPacket(threadData->socket, eRemoteServer_Handshake); + } vector tempFiles; IRemoteDriver *driver = NULL; @@ -1135,7 +1172,9 @@ RENDERDOC_CreateRemoteServerConnection(const char *host, uint32_t port, RemoteSe } Serialiser sendData("", Serialiser::WRITING, false); - SendPacket(sock, eRemoteServer_Handshake); + uint32_t version = RemoteServerProtocolVersion; + sendData.Serialise("version", version); + SendPacket(sock, eRemoteServer_Handshake, sendData); RemoteServerPacket type = (RemoteServerPacket)RecvPacket(sock); @@ -1145,6 +1184,12 @@ RENDERDOC_CreateRemoteServerConnection(const char *host, uint32_t port, RemoteSe return eReplayCreate_NetworkRemoteBusy; } + if(type == eRemoteServer_VersionMismatch) + { + SAFE_DELETE(sock); + return eReplayCreate_NetworkVersionMismatch; + } + if(type != eRemoteServer_Handshake) { RDCWARN("Didn't get proper handshake"); diff --git a/renderdocui/Code/PersistantConfig.cs b/renderdocui/Code/PersistantConfig.cs index 450fda3e5..64263f760 100644 --- a/renderdocui/Code/PersistantConfig.cs +++ b/renderdocui/Code/PersistantConfig.cs @@ -49,6 +49,8 @@ namespace renderdocui.Code public bool Connected = false; [XmlIgnore] public bool Busy = false; + [XmlIgnore] + public bool VersionMismatch = false; public void CheckStatus() { @@ -56,7 +58,7 @@ namespace renderdocui.Code { RemoteServer server = StaticExports.CreateRemoteServer(Hostname, 0); ServerRunning = true; - Busy = false; + VersionMismatch = Busy = false; server.ShutdownConnection(); } catch (ReplayCreateException ex) @@ -66,6 +68,12 @@ namespace renderdocui.Code ServerRunning = true; Busy = true; } + else if (ex.Status == ReplayCreateStatus.NetworkVersionMismatch) + { + ServerRunning = true; + Busy = true; + VersionMismatch = true; + } else { ServerRunning = false; diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index 8514fb365..26c7a65cf 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -521,6 +521,7 @@ namespace renderdoc IncompatibleProcess, NetworkIOFailed, NetworkRemoteBusy, + NetworkVersionMismatch, FileIOFailed, FileIncompatibleVersion, FileCorrupted, @@ -624,6 +625,7 @@ namespace renderdoc case ReplayCreateStatus.IncompatibleProcess: return "Process is incompatible (likely 64-bit/32-bit issue)"; case ReplayCreateStatus.NetworkIOFailed: return "Network I/O operation failed"; case ReplayCreateStatus.NetworkRemoteBusy: return "Remote side of network connection is busy"; + case ReplayCreateStatus.NetworkVersionMismatch: return "Version mismatch between network clients"; case ReplayCreateStatus.FileIOFailed: return "File I/O operation failed"; case ReplayCreateStatus.FileIncompatibleVersion: return "File is of an incompatible version"; case ReplayCreateStatus.FileCorrupted: return "File is corrupted or unrecognisable format"; diff --git a/renderdocui/Windows/Dialogs/RemoteManager.cs b/renderdocui/Windows/Dialogs/RemoteManager.cs index ab28c12a0..cb55d803c 100644 --- a/renderdocui/Windows/Dialogs/RemoteManager.cs +++ b/renderdocui/Windows/Dialogs/RemoteManager.cs @@ -80,6 +80,8 @@ namespace renderdocui.Windows.Dialogs if (host.Connected) text += " (Active Context)"; + else if (host.VersionMismatch) + text += " (Version Mismatch)"; else if (host.Busy) text += " (Busy)"; diff --git a/renderdocui/Windows/MainWindow.cs b/renderdocui/Windows/MainWindow.cs index 418a642cd..093200517 100644 --- a/renderdocui/Windows/MainWindow.cs +++ b/renderdocui/Windows/MainWindow.cs @@ -1111,7 +1111,11 @@ namespace renderdocui.Windows ? global::renderdocui.Properties.Resources.connect : global::renderdocui.Properties.Resources.disconnect; - if (host.Busy) + if (host.VersionMismatch) + { + statusText.Text = "Remote server is not running RenderDoc " + VersionString; + } + else if (host.Busy) { statusText.Text = "Remote server in use elsewhere"; }