From 85813fd49b9749ef0a58a8269ac50b2e80c8f0c2 Mon Sep 17 00:00:00 2001 From: XinyuHou Date: Tue, 27 Jan 2015 10:42:10 +0000 Subject: [PATCH] added plugin unload and cleanup #4313 --- src/lib/arch/IArchPlugin.h | 6 ++++++ src/lib/arch/unix/ArchPluginUnix.cpp | 13 +++++++++++++ src/lib/arch/unix/ArchPluginUnix.h | 1 + src/lib/arch/win32/ArchPluginWindows.cpp | 15 +++++++++++++++ src/lib/arch/win32/ArchPluginWindows.h | 1 + src/lib/plugin/ns/SecureListenSocket.cpp | 2 ++ src/lib/plugin/ns/SecureSocket.cpp | 15 +++++++++++++++ src/lib/plugin/ns/SecureSocket.h | 2 ++ src/lib/plugin/ns/ns.cpp | 4 +--- src/lib/plugin/ns/ns.h | 2 +- src/lib/plugin/winmmjoy/winmmjoy.cpp | 4 +--- src/lib/plugin/winmmjoy/winmmjoy.h | 2 +- src/lib/server/ClientListener.cpp | 22 ++++++++++++++-------- src/lib/server/ClientListener.h | 10 +++++++--- src/lib/synergy/ClientApp.cpp | 3 +++ src/lib/synergy/ServerApp.cpp | 3 +++ 16 files changed, 86 insertions(+), 19 deletions(-) diff --git a/src/lib/arch/IArchPlugin.h b/src/lib/arch/IArchPlugin.h index 478b66cc..f6bfd599 100644 --- a/src/lib/arch/IArchPlugin.h +++ b/src/lib/arch/IArchPlugin.h @@ -42,6 +42,12 @@ public: */ virtual void load() = 0; + //!Unload plugins + /*! + Look through the loaded plugins and unload them. + */ + virtual void unload() = 0; + //! Init the common parts /*! Initializes common parts like log and arch. diff --git a/src/lib/arch/unix/ArchPluginUnix.cpp b/src/lib/arch/unix/ArchPluginUnix.cpp index 905672c8..0678120e 100644 --- a/src/lib/arch/unix/ArchPluginUnix.cpp +++ b/src/lib/arch/unix/ArchPluginUnix.cpp @@ -31,6 +31,7 @@ typedef void (*initFunc)(void*, void*); typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*)); typedef void* (*invokeFunc)(const char*, void*); +typedef void (*cleanupFunc)(); void* g_eventTarget = NULL; IEventQueue* g_events = NULL; @@ -84,6 +85,18 @@ ArchPluginUnix::load() } } +void +ArchPluginUnix::unload() +{ + PluginTable::iterator it; + for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { + cleanupFunc cleanup = (cleanupFunc)dlsym(it->second, "cleanup"); + cleanup(); + LOG((CLOG_DEBUG "unloading plugin: %s", it->first.c_str())); + dlclose(it->second); + } +} + void ArchPluginUnix::init(void* log, void* arch) { diff --git a/src/lib/arch/unix/ArchPluginUnix.h b/src/lib/arch/unix/ArchPluginUnix.h index 15e9b1a6..092a1fd9 100644 --- a/src/lib/arch/unix/ArchPluginUnix.h +++ b/src/lib/arch/unix/ArchPluginUnix.h @@ -32,6 +32,7 @@ public: // IArchPlugin overrides void load(); + void unload(); void init(void* log, void* arch); void initEvent(void* eventTarget, IEventQueue* events); bool exists(const char* name); diff --git a/src/lib/arch/win32/ArchPluginWindows.cpp b/src/lib/arch/win32/ArchPluginWindows.cpp index c7a361fe..378258f3 100644 --- a/src/lib/arch/win32/ArchPluginWindows.cpp +++ b/src/lib/arch/win32/ArchPluginWindows.cpp @@ -30,6 +30,7 @@ typedef void (*initFunc)(void*, void*); typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*)); typedef void* (*invokeFunc)(const char*, void**); +typedef void (*cleanupFunc)(); void* g_eventTarget = NULL; IEventQueue* g_events = NULL; @@ -68,6 +69,20 @@ ArchPluginWindows::load() } } +void +ArchPluginWindows::unload() +{ + PluginTable::iterator it; + HINSTANCE lib; + for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { + lib = reinterpret_cast(it->second); + cleanupFunc cleanup = (cleanupFunc)GetProcAddress(lib, "cleanup"); + cleanup(); + LOG((CLOG_DEBUG "unloading plugin: %s", it->first.c_str())); + FreeLibrary(lib); + } +} + void ArchPluginWindows::init(void* log, void* arch) { diff --git a/src/lib/arch/win32/ArchPluginWindows.h b/src/lib/arch/win32/ArchPluginWindows.h index 7a252e60..fdde9169 100644 --- a/src/lib/arch/win32/ArchPluginWindows.h +++ b/src/lib/arch/win32/ArchPluginWindows.h @@ -35,6 +35,7 @@ public: // IArchPlugin overrides void load(); + void unload(); void init(void* log, void* arch); void initEvent(void* eventTarget, IEventQueue* events); bool exists(const char* name); diff --git a/src/lib/plugin/ns/SecureListenSocket.cpp b/src/lib/plugin/ns/SecureListenSocket.cpp index 672669c6..778a4c1e 100644 --- a/src/lib/plugin/ns/SecureListenSocket.cpp +++ b/src/lib/plugin/ns/SecureListenSocket.cpp @@ -50,6 +50,8 @@ SecureListenSocket::accept() socket->initSsl(true); // TODO: customized certificate path socket->loadCertificates("C:\\Temp\\synergy.pem"); + socket->secureAccept(); + if (socket != NULL) { m_socketMultiplexer->addSocket(this, new TSocketMultiplexerMethodJob( diff --git a/src/lib/plugin/ns/SecureSocket.cpp b/src/lib/plugin/ns/SecureSocket.cpp index c4ea34e5..88aa37b5 100644 --- a/src/lib/plugin/ns/SecureSocket.cpp +++ b/src/lib/plugin/ns/SecureSocket.cpp @@ -68,6 +68,21 @@ SecureSocket::~SecureSocket() delete[] m_error; } +void +SecureSocket::close() +{ + if (m_ssl->m_ssl != NULL) { + SSL_free(m_ssl->m_ssl); + m_ssl->m_ssl = NULL; + } + + if (m_ssl->m_context != NULL) { + SSL_CTX_free(m_ssl->m_context); + m_ssl->m_context = NULL; + } + + TCPSocket::close(); +} void SecureSocket::secureConnect() diff --git a/src/lib/plugin/ns/SecureSocket.h b/src/lib/plugin/ns/SecureSocket.h index bae6d909..b46c6e52 100644 --- a/src/lib/plugin/ns/SecureSocket.h +++ b/src/lib/plugin/ns/SecureSocket.h @@ -42,6 +42,8 @@ public: ArchSocket socket); ~SecureSocket(); + // ISocket overrides + void close(); void secureConnect(); void secureAccept(); diff --git a/src/lib/plugin/ns/ns.cpp b/src/lib/plugin/ns/ns.cpp index 44a5ac36..4e492bb7 100644 --- a/src/lib/plugin/ns/ns.cpp +++ b/src/lib/plugin/ns/ns.cpp @@ -79,7 +79,7 @@ invoke(const char* command, void** args) } } -int +void cleanup() { if (g_secureSocket != NULL) { @@ -89,8 +89,6 @@ cleanup() if (g_secureListenSocket != NULL) { delete g_secureListenSocket; } - - return 0; } } \ No newline at end of file diff --git a/src/lib/plugin/ns/ns.h b/src/lib/plugin/ns/ns.h index fa5a444f..9e725166 100644 --- a/src/lib/plugin/ns/ns.h +++ b/src/lib/plugin/ns/ns.h @@ -36,6 +36,6 @@ extern "C" { NS_API void init(void* log, void* arch); NS_API int initEvent(void (*sendEvent)(const char*, void*)); NS_API void* invoke(const char* command, void** args); -NS_API int cleanup(); +NS_API void cleanup(); } diff --git a/src/lib/plugin/winmmjoy/winmmjoy.cpp b/src/lib/plugin/winmmjoy/winmmjoy.cpp index 0ae535e7..da4739d3 100644 --- a/src/lib/plugin/winmmjoy/winmmjoy.cpp +++ b/src/lib/plugin/winmmjoy/winmmjoy.cpp @@ -49,12 +49,10 @@ initEvent(void (*sendEvent)(const char*, void*)) return 0; } -int +void cleanup() { - LOG("cleanup"); s_running = false; - return 0; } } diff --git a/src/lib/plugin/winmmjoy/winmmjoy.h b/src/lib/plugin/winmmjoy/winmmjoy.h index 38e8518c..bd10896f 100644 --- a/src/lib/plugin/winmmjoy/winmmjoy.h +++ b/src/lib/plugin/winmmjoy/winmmjoy.h @@ -31,7 +31,7 @@ extern "C" { WINMMJOY_API void init(void* log, void* arch); WINMMJOY_API int initEvent(void (*sendEvent)(const char*, void*)); -WINMMJOY_API int cleanup(); +WINMMJOY_API void cleanup(); } diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index 3b4d872b..de895781 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -21,7 +21,6 @@ #include "server/ClientProxy.h" #include "server/ClientProxyUnknown.h" #include "synergy/PacketStreamFilter.h" -#include "net/TCPSocket.h" #include "net/IDataSocket.h" #include "net/IListenSocket.h" #include "net/ISocketFactory.h" @@ -58,21 +57,21 @@ ClientListener::ClientListener(const NetworkAddress& address, try { // create listen socket - bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity); - m_listen = m_socketFactory->createListen(useSecureSocket); + m_useSecureSocket = ARCH->plugin().exists(s_networkSecurity); + m_listen = m_socketFactory->createListen(m_useSecureSocket); // bind listen address LOG((CLOG_DEBUG1 "binding listen socket")); m_listen->bind(address); } catch (XSocketAddressInUse&) { - delete m_listen; + cleanupListenSocket(); delete m_socketFactory; delete m_streamFilterFactory; throw; } catch (XBase&) { - delete m_listen; + cleanupListenSocket(); delete m_socketFactory; delete m_streamFilterFactory; throw; @@ -110,7 +109,7 @@ ClientListener::~ClientListener() } m_events->removeHandler(m_events->forIListenSocket().connecting(), m_listen); - delete m_listen; + cleanupListenSocket(); delete m_socketFactory; delete m_streamFilterFactory; } @@ -143,8 +142,7 @@ ClientListener::handleClientConnecting(const Event&, void*) return; } LOG((CLOG_NOTE "accepted client connection")); - TCPSocket* socket = dynamic_cast(stream); - socket->secureAccept(); + // filter socket messages, including a packetizing filter if (m_streamFilterFactory != NULL) { stream = m_streamFilterFactory->create(stream, true); @@ -219,3 +217,11 @@ ClientListener::handleClientDisconnected(const Event&, void* vclient) } } } + +void +ClientListener::cleanupListenSocket() +{ + if (!m_useSecureSocket) { + delete m_listen; + } +} diff --git a/src/lib/server/ClientListener.h b/src/lib/server/ClientListener.h index a37f2132..4e5d4f23 100644 --- a/src/lib/server/ClientListener.h +++ b/src/lib/server/ClientListener.h @@ -63,7 +63,7 @@ public: ClientProxy* getNextClient(); //! Get server which owns this listener - Server* getServer() { return m_server; } + Server* getServer() { return m_server; } //@} @@ -73,16 +73,20 @@ private: void handleUnknownClient(const Event&, void*); void handleClientDisconnected(const Event&, void*); + void cleanupListenSocket(); + private: typedef std::set NewClients; typedef std::deque WaitingClients; IListenSocket* m_listen; ISocketFactory* m_socketFactory; - IStreamFilterFactory* m_streamFilterFactory; + IStreamFilterFactory* + m_streamFilterFactory; NewClients m_newClients; WaitingClients m_waitingClients; - Server* m_server; + Server* m_server; CryptoOptions m_crypto; IEventQueue* m_events; + bool m_useSecureSocket; }; diff --git a/src/lib/synergy/ClientApp.cpp b/src/lib/synergy/ClientApp.cpp index fe10b697..b26bc700 100644 --- a/src/lib/synergy/ClientApp.cpp +++ b/src/lib/synergy/ClientApp.cpp @@ -509,6 +509,9 @@ ClientApp::mainLoop() cleanupIpcClient(); } + // unload all plugins. + ARCH->plugin().unload(); + return kExitSuccess; } diff --git a/src/lib/synergy/ServerApp.cpp b/src/lib/synergy/ServerApp.cpp index 3adf0bfe..6cbc2016 100644 --- a/src/lib/synergy/ServerApp.cpp +++ b/src/lib/synergy/ServerApp.cpp @@ -780,6 +780,9 @@ ServerApp::mainLoop() cleanupIpcClient(); } + // unload all plugins. + ARCH->plugin().unload(); + return kExitSuccess; }