managed secure socket allocation and deallocation #4313
This commit is contained in:
parent
d80aa7c938
commit
622e40e5d7
|
@ -81,7 +81,8 @@ Client::Client(
|
|||
m_sendFileThread(NULL),
|
||||
m_writeToDropDirThread(NULL),
|
||||
m_enableDragDrop(enableDragDrop),
|
||||
m_socket(NULL)
|
||||
m_socket(NULL),
|
||||
m_useSecureNetwork(false)
|
||||
{
|
||||
assert(m_socketFactory != NULL);
|
||||
assert(m_screen != NULL);
|
||||
|
@ -155,13 +156,13 @@ Client::connect()
|
|||
}
|
||||
|
||||
// create the socket
|
||||
bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
|
||||
IDataSocket* socket = m_socketFactory->create(useSecureSocket);
|
||||
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
|
||||
IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork);
|
||||
m_socket = dynamic_cast<TCPSocket*>(socket);
|
||||
|
||||
// filter socket messages, including a packetizing filter
|
||||
m_stream = socket;
|
||||
bool adopt = !useSecureSocket;
|
||||
bool adopt = !m_useSecureNetwork;
|
||||
m_stream = new PacketStreamFilter(m_events, m_stream, adopt);
|
||||
|
||||
if (m_crypto.m_mode != kDisabled) {
|
||||
|
@ -570,10 +571,14 @@ Client::cleanupTimer()
|
|||
void
|
||||
Client::cleanupStream()
|
||||
{
|
||||
bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
|
||||
if (!useSecureSocket) {
|
||||
delete m_stream;
|
||||
m_stream = NULL;
|
||||
delete m_stream;
|
||||
m_stream = NULL;
|
||||
|
||||
// PacketStreamFilter doen't adopt secure socket, because
|
||||
// we need to tell the dynamic lib that allocated this object
|
||||
// to do the deletion.
|
||||
if (m_useSecureNetwork) {
|
||||
ARCH->plugin().invoke(s_networkSecurity, "deleteSocket", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -233,4 +233,5 @@ private:
|
|||
Thread* m_writeToDropDirThread;
|
||||
bool m_enableDragDrop;
|
||||
TCPSocket* m_socket;
|
||||
bool m_useSecureNetwork;
|
||||
};
|
||||
|
|
|
@ -49,13 +49,13 @@ public:
|
|||
virtual bool isReady() const;
|
||||
virtual UInt32 getSize() const;
|
||||
|
||||
protected:
|
||||
//! Get the stream
|
||||
/*!
|
||||
Returns the stream passed to the c'tor.
|
||||
*/
|
||||
synergy::IStream* getStream() const;
|
||||
|
||||
protected:
|
||||
//! Handle events from source stream
|
||||
/*!
|
||||
Does the event filtering. The default simply dispatches an event
|
||||
|
|
|
@ -39,7 +39,15 @@ public:
|
|||
data stream. Returns NULL if no socket is waiting to be accepted.
|
||||
This is only valid after a call to \c bind().
|
||||
*/
|
||||
virtual IDataSocket* accept() = 0;
|
||||
virtual IDataSocket*
|
||||
accept() = 0;
|
||||
|
||||
//! Delete connection socket
|
||||
/*!
|
||||
This is used when the socket was created but not adopted by a client
|
||||
proxy.
|
||||
*/
|
||||
virtual void deleteSocket(void*) = 0;
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -43,8 +43,7 @@ public:
|
|||
// IListenSocket overrides
|
||||
virtual IDataSocket*
|
||||
accept();
|
||||
|
||||
ArchSocket& getSocket() { return m_socket; }
|
||||
virtual void deleteSocket(void*) { }
|
||||
|
||||
public:
|
||||
ISocketMultiplexerJob*
|
||||
|
|
|
@ -55,7 +55,7 @@ TCPSocketFactory::create(bool secure) const
|
|||
m_socketMultiplexer
|
||||
};
|
||||
socket = static_cast<IDataSocket*>(
|
||||
ARCH->plugin().invoke(s_networkSecurity, "getSecureSocket", args));
|
||||
ARCH->plugin().invoke(s_networkSecurity, "getSocket", args));
|
||||
}
|
||||
else {
|
||||
socket = new TCPSocket(m_events, m_socketMultiplexer);
|
||||
|
@ -74,7 +74,7 @@ TCPSocketFactory::createListen(bool secure) const
|
|||
m_socketMultiplexer
|
||||
};
|
||||
socket = static_cast<IListenSocket*>(
|
||||
ARCH->plugin().invoke(s_networkSecurity, "getSecureListenSocket", args));
|
||||
ARCH->plugin().invoke(s_networkSecurity, "getListenSocket", args));
|
||||
}
|
||||
else {
|
||||
socket = new TCPListenSocket(m_events, m_socketMultiplexer);
|
||||
|
|
|
@ -36,6 +36,11 @@ SecureListenSocket::SecureListenSocket(
|
|||
|
||||
SecureListenSocket::~SecureListenSocket()
|
||||
{
|
||||
SecureSocketSet::iterator it;
|
||||
for (it = m_secureSocketSet.begin(); it != m_secureSocketSet.end(); it++) {
|
||||
delete *it;
|
||||
}
|
||||
m_secureSocketSet.clear();
|
||||
}
|
||||
|
||||
IDataSocket*
|
||||
|
@ -47,6 +52,9 @@ SecureListenSocket::accept()
|
|||
m_events,
|
||||
m_socketMultiplexer,
|
||||
ARCH->acceptSocket(m_socket, NULL));
|
||||
|
||||
m_secureSocketSet.insert(socket);
|
||||
|
||||
socket->initSsl(true);
|
||||
// TODO: customized certificate path
|
||||
socket->loadCertificates("C:\\Temp\\synergy.pem");
|
||||
|
@ -73,3 +81,14 @@ SecureListenSocket::accept()
|
|||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SecureListenSocket::deleteSocket(void* socket)
|
||||
{
|
||||
SecureSocketSet::iterator it;
|
||||
it = m_secureSocketSet.find((IDataSocket*)socket);
|
||||
if (it != m_secureSocketSet.end()) {
|
||||
delete *it;
|
||||
m_secureSocketSet.erase(it);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "net/TCPListenSocket.h"
|
||||
#include "common/stdset.h"
|
||||
|
||||
class IEventQueue;
|
||||
class SocketMultiplexer;
|
||||
class IDataSocket;
|
||||
|
||||
class SecureListenSocket : public TCPListenSocket{
|
||||
public:
|
||||
|
@ -31,4 +33,10 @@ public:
|
|||
// IListenSocket overrides
|
||||
virtual IDataSocket*
|
||||
accept();
|
||||
void deleteSocket(void*);
|
||||
|
||||
private:
|
||||
typedef std::set<IDataSocket*> SecureSocketSet;
|
||||
|
||||
SecureSocketSet m_secureSocketSet;
|
||||
};
|
||||
|
|
|
@ -68,21 +68,6 @@ 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()
|
||||
|
|
|
@ -42,9 +42,6 @@ public:
|
|||
ArchSocket socket);
|
||||
~SecureSocket();
|
||||
|
||||
// ISocket overrides
|
||||
void close();
|
||||
|
||||
void secureConnect();
|
||||
void secureAccept();
|
||||
bool isSecureReady();
|
||||
|
|
|
@ -59,7 +59,7 @@ invoke(const char* command, void** args)
|
|||
arg2 = reinterpret_cast<SocketMultiplexer*>(args[1]);
|
||||
}
|
||||
|
||||
if (strcmp(command, "getSecureSocket") == 0) {
|
||||
if (strcmp(command, "getSocket") == 0) {
|
||||
if (g_secureSocket != NULL) {
|
||||
delete g_secureSocket;
|
||||
}
|
||||
|
@ -67,16 +67,27 @@ invoke(const char* command, void** args)
|
|||
g_secureSocket->initSsl(false);
|
||||
return g_secureSocket;
|
||||
}
|
||||
else if (strcmp(command, "getSecureListenSocket") == 0) {
|
||||
else if (strcmp(command, "getListenSocket") == 0) {
|
||||
if (g_secureListenSocket != NULL) {
|
||||
delete g_secureListenSocket;
|
||||
}
|
||||
g_secureListenSocket = new SecureListenSocket(arg1, arg2);
|
||||
return g_secureListenSocket;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
else if (strcmp(command, "deleteSocket") == 0) {
|
||||
if (g_secureSocket != NULL) {
|
||||
delete g_secureSocket;
|
||||
g_secureSocket = NULL;
|
||||
}
|
||||
}
|
||||
else if (strcmp(command, "deleteListenSocket") == 0) {
|
||||
if (g_secureListenSocket != NULL) {
|
||||
delete g_secureListenSocket;
|
||||
g_secureListenSocket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "synergy/IClient.h"
|
||||
#include "base/String.h"
|
||||
|
||||
namespace synergy { class IStream; }
|
||||
|
||||
//! Generic proxy for client or primary
|
||||
class BaseClientProxy : public IClient {
|
||||
public:
|
||||
|
@ -82,6 +84,8 @@ public:
|
|||
size_t size) = 0;
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
|
||||
virtual String getName() const;
|
||||
virtual synergy::IStream*
|
||||
getStream() const = 0;
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
|
|
|
@ -54,8 +54,8 @@ ClientListener::ClientListener(const NetworkAddress& address,
|
|||
|
||||
try {
|
||||
// create listen socket
|
||||
m_useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
|
||||
m_listen = m_socketFactory->createListen(m_useSecureSocket);
|
||||
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
|
||||
m_listen = m_socketFactory->createListen(m_useSecureNetwork);
|
||||
|
||||
// bind listen address
|
||||
LOG((CLOG_DEBUG1 "binding listen socket"));
|
||||
|
@ -115,6 +115,12 @@ ClientListener::setServer(Server* server)
|
|||
m_server = server;
|
||||
}
|
||||
|
||||
void
|
||||
ClientListener::deleteSocket(void* socket)
|
||||
{
|
||||
m_listen->deleteSocket(socket);
|
||||
}
|
||||
|
||||
ClientProxy*
|
||||
ClientListener::getNextClient()
|
||||
{
|
||||
|
@ -132,13 +138,16 @@ ClientListener::handleClientConnecting(const Event&, void*)
|
|||
{
|
||||
// accept client connection
|
||||
synergy::IStream* stream = m_listen->accept();
|
||||
|
||||
if (stream == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG((CLOG_NOTE "accepted client connection"));
|
||||
|
||||
// filter socket messages, including a packetizing filter
|
||||
stream = new PacketStreamFilter(m_events, stream, true);
|
||||
bool adopt = !m_useSecureNetwork;
|
||||
stream = new PacketStreamFilter(m_events, stream, adopt);
|
||||
|
||||
if (m_crypto.m_mode != kDisabled) {
|
||||
CryptoStream* cryptoStream = new CryptoStream(
|
||||
|
@ -212,7 +221,13 @@ ClientListener::handleClientDisconnected(const Event&, void* vclient)
|
|||
void
|
||||
ClientListener::cleanupListenSocket()
|
||||
{
|
||||
if (!m_useSecureSocket) {
|
||||
if (!m_useSecureNetwork) {
|
||||
delete m_listen;
|
||||
}
|
||||
else {
|
||||
ARCH->plugin().invoke(
|
||||
s_networkSecurity,
|
||||
"deleteListenSocket",
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
|
||||
//@}
|
||||
|
||||
void deleteSocket(void* socket);
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
|
@ -84,5 +86,5 @@ private:
|
|||
Server* m_server;
|
||||
CryptoOptions m_crypto;
|
||||
IEventQueue* m_events;
|
||||
bool m_useSecureSocket;
|
||||
bool m_useSecureNetwork;
|
||||
};
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
Returns a crypto stream if the user has this enabled,
|
||||
otherwise returns the original stream passed to the c'tor.
|
||||
*/
|
||||
synergy::IStream* getStream() const;
|
||||
synergy::IStream* getStream() const;
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -63,6 +63,6 @@ private:
|
|||
EventQueueTimer* m_timer;
|
||||
ClientProxy* m_proxy;
|
||||
bool m_ready;
|
||||
Server* m_server;
|
||||
Server* m_server;
|
||||
IEventQueue* m_events;
|
||||
};
|
||||
|
|
|
@ -146,6 +146,9 @@ public:
|
|||
virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
|
||||
|
||||
virtual synergy::IStream*
|
||||
getStream() const { return NULL; }
|
||||
|
||||
private:
|
||||
synergy::Screen* m_screen;
|
||||
bool m_clipboardDirty[kClipboardEnd];
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "server/ClientProxy.h"
|
||||
#include "server/ClientProxyUnknown.h"
|
||||
#include "server/PrimaryClient.h"
|
||||
#include "server/ClientListener.h"
|
||||
#include "synergy/IPlatformScreen.h"
|
||||
#include "synergy/DropHelper.h"
|
||||
#include "synergy/option_types.h"
|
||||
|
@ -30,6 +31,8 @@
|
|||
#include "synergy/FileChunker.h"
|
||||
#include "synergy/KeyState.h"
|
||||
#include "synergy/Screen.h"
|
||||
#include "synergy/PacketStreamFilter.h"
|
||||
#include "net/TCPSocket.h"
|
||||
#include "net/IDataSocket.h"
|
||||
#include "net/IListenSocket.h"
|
||||
#include "net/XSocket.h"
|
||||
|
@ -1358,7 +1361,11 @@ Server::handleClientDisconnected(const Event&, void* vclient)
|
|||
BaseClientProxy* client = reinterpret_cast<BaseClientProxy*>(vclient);
|
||||
removeActiveClient(client);
|
||||
removeOldClient(client);
|
||||
|
||||
PacketStreamFilter* streamFileter = dynamic_cast<PacketStreamFilter*>(client->getStream());
|
||||
TCPSocket* socket = dynamic_cast<TCPSocket*>(streamFileter->getStream());
|
||||
delete client;
|
||||
m_clientListener->deleteSocket(socket);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -39,6 +39,7 @@ class InputFilter;
|
|||
namespace synergy { class Screen; }
|
||||
class IEventQueue;
|
||||
class Thread;
|
||||
class ClientListener;
|
||||
|
||||
//! Synergy server
|
||||
/*!
|
||||
|
@ -154,6 +155,9 @@ public:
|
|||
|
||||
//! Received dragging information from client
|
||||
void dragInfoReceived(UInt32 fileNum, String content);
|
||||
|
||||
//! Store ClientListener pointer
|
||||
void setListener(ClientListener* p) { m_clientListener = p; }
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
|
@ -412,7 +416,7 @@ private:
|
|||
SInt32 m_xDelta2, m_yDelta2;
|
||||
|
||||
// current configuration
|
||||
Config* m_config;
|
||||
Config* m_config;
|
||||
|
||||
// input filter (from m_config);
|
||||
InputFilter* m_inputFilter;
|
||||
|
@ -458,7 +462,7 @@ private:
|
|||
bool m_lockedToScreen;
|
||||
|
||||
// server screen
|
||||
synergy::Screen* m_screen;
|
||||
synergy::Screen* m_screen;
|
||||
|
||||
IEventQueue* m_events;
|
||||
|
||||
|
@ -466,12 +470,14 @@ private:
|
|||
size_t m_expectedFileSize;
|
||||
String m_receivedFileData;
|
||||
DragFileList m_dragFileList;
|
||||
Thread* m_sendFileThread;
|
||||
Thread* m_writeToDropDirThread;
|
||||
Thread* m_sendFileThread;
|
||||
Thread* m_writeToDropDirThread;
|
||||
String m_dragFileExt;
|
||||
bool m_ignoreFileTransfer;
|
||||
bool m_enableDragDrop;
|
||||
|
||||
Thread* m_getDragInfoThread;
|
||||
Thread* m_getDragInfoThread;
|
||||
bool m_waitDragInfoThread;
|
||||
|
||||
ClientListener* m_clientListener;
|
||||
};
|
||||
|
|
|
@ -543,6 +543,7 @@ ServerApp::startServer()
|
|||
listener = openClientListener(args().m_config->getSynergyAddress());
|
||||
m_server = openServer(*args().m_config, m_primaryClient);
|
||||
listener->setServer(m_server);
|
||||
m_server->setListener(listener);
|
||||
m_listener = listener;
|
||||
updateStatus();
|
||||
LOG((CLOG_NOTE "started server, waiting for clients"));
|
||||
|
|
Loading…
Reference in New Issue