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_sendFileThread(NULL),
|
||||||
m_writeToDropDirThread(NULL),
|
m_writeToDropDirThread(NULL),
|
||||||
m_enableDragDrop(enableDragDrop),
|
m_enableDragDrop(enableDragDrop),
|
||||||
m_socket(NULL)
|
m_socket(NULL),
|
||||||
|
m_useSecureNetwork(false)
|
||||||
{
|
{
|
||||||
assert(m_socketFactory != NULL);
|
assert(m_socketFactory != NULL);
|
||||||
assert(m_screen != NULL);
|
assert(m_screen != NULL);
|
||||||
|
@ -155,13 +156,13 @@ Client::connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the socket
|
// create the socket
|
||||||
bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
|
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
|
||||||
IDataSocket* socket = m_socketFactory->create(useSecureSocket);
|
IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork);
|
||||||
m_socket = dynamic_cast<TCPSocket*>(socket);
|
m_socket = dynamic_cast<TCPSocket*>(socket);
|
||||||
|
|
||||||
// filter socket messages, including a packetizing filter
|
// filter socket messages, including a packetizing filter
|
||||||
m_stream = socket;
|
m_stream = socket;
|
||||||
bool adopt = !useSecureSocket;
|
bool adopt = !m_useSecureNetwork;
|
||||||
m_stream = new PacketStreamFilter(m_events, m_stream, adopt);
|
m_stream = new PacketStreamFilter(m_events, m_stream, adopt);
|
||||||
|
|
||||||
if (m_crypto.m_mode != kDisabled) {
|
if (m_crypto.m_mode != kDisabled) {
|
||||||
|
@ -570,10 +571,14 @@ Client::cleanupTimer()
|
||||||
void
|
void
|
||||||
Client::cleanupStream()
|
Client::cleanupStream()
|
||||||
{
|
{
|
||||||
bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
|
|
||||||
if (!useSecureSocket) {
|
|
||||||
delete m_stream;
|
delete m_stream;
|
||||||
m_stream = NULL;
|
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;
|
Thread* m_writeToDropDirThread;
|
||||||
bool m_enableDragDrop;
|
bool m_enableDragDrop;
|
||||||
TCPSocket* m_socket;
|
TCPSocket* m_socket;
|
||||||
|
bool m_useSecureNetwork;
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,13 +49,13 @@ public:
|
||||||
virtual bool isReady() const;
|
virtual bool isReady() const;
|
||||||
virtual UInt32 getSize() const;
|
virtual UInt32 getSize() const;
|
||||||
|
|
||||||
protected:
|
|
||||||
//! Get the stream
|
//! Get the stream
|
||||||
/*!
|
/*!
|
||||||
Returns the stream passed to the c'tor.
|
Returns the stream passed to the c'tor.
|
||||||
*/
|
*/
|
||||||
synergy::IStream* getStream() const;
|
synergy::IStream* getStream() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
//! Handle events from source stream
|
//! Handle events from source stream
|
||||||
/*!
|
/*!
|
||||||
Does the event filtering. The default simply dispatches an event
|
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.
|
data stream. Returns NULL if no socket is waiting to be accepted.
|
||||||
This is only valid after a call to \c bind().
|
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
|
// IListenSocket overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
accept();
|
accept();
|
||||||
|
virtual void deleteSocket(void*) { }
|
||||||
ArchSocket& getSocket() { return m_socket; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISocketMultiplexerJob*
|
ISocketMultiplexerJob*
|
||||||
|
|
|
@ -55,7 +55,7 @@ TCPSocketFactory::create(bool secure) const
|
||||||
m_socketMultiplexer
|
m_socketMultiplexer
|
||||||
};
|
};
|
||||||
socket = static_cast<IDataSocket*>(
|
socket = static_cast<IDataSocket*>(
|
||||||
ARCH->plugin().invoke(s_networkSecurity, "getSecureSocket", args));
|
ARCH->plugin().invoke(s_networkSecurity, "getSocket", args));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
socket = new TCPSocket(m_events, m_socketMultiplexer);
|
socket = new TCPSocket(m_events, m_socketMultiplexer);
|
||||||
|
@ -74,7 +74,7 @@ TCPSocketFactory::createListen(bool secure) const
|
||||||
m_socketMultiplexer
|
m_socketMultiplexer
|
||||||
};
|
};
|
||||||
socket = static_cast<IListenSocket*>(
|
socket = static_cast<IListenSocket*>(
|
||||||
ARCH->plugin().invoke(s_networkSecurity, "getSecureListenSocket", args));
|
ARCH->plugin().invoke(s_networkSecurity, "getListenSocket", args));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
socket = new TCPListenSocket(m_events, m_socketMultiplexer);
|
socket = new TCPListenSocket(m_events, m_socketMultiplexer);
|
||||||
|
|
|
@ -36,6 +36,11 @@ SecureListenSocket::SecureListenSocket(
|
||||||
|
|
||||||
SecureListenSocket::~SecureListenSocket()
|
SecureListenSocket::~SecureListenSocket()
|
||||||
{
|
{
|
||||||
|
SecureSocketSet::iterator it;
|
||||||
|
for (it = m_secureSocketSet.begin(); it != m_secureSocketSet.end(); it++) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
m_secureSocketSet.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDataSocket*
|
IDataSocket*
|
||||||
|
@ -47,6 +52,9 @@ SecureListenSocket::accept()
|
||||||
m_events,
|
m_events,
|
||||||
m_socketMultiplexer,
|
m_socketMultiplexer,
|
||||||
ARCH->acceptSocket(m_socket, NULL));
|
ARCH->acceptSocket(m_socket, NULL));
|
||||||
|
|
||||||
|
m_secureSocketSet.insert(socket);
|
||||||
|
|
||||||
socket->initSsl(true);
|
socket->initSsl(true);
|
||||||
// TODO: customized certificate path
|
// TODO: customized certificate path
|
||||||
socket->loadCertificates("C:\\Temp\\synergy.pem");
|
socket->loadCertificates("C:\\Temp\\synergy.pem");
|
||||||
|
@ -73,3 +81,14 @@ SecureListenSocket::accept()
|
||||||
throw ex;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "net/TCPListenSocket.h"
|
#include "net/TCPListenSocket.h"
|
||||||
|
#include "common/stdset.h"
|
||||||
|
|
||||||
class IEventQueue;
|
class IEventQueue;
|
||||||
class SocketMultiplexer;
|
class SocketMultiplexer;
|
||||||
|
class IDataSocket;
|
||||||
|
|
||||||
class SecureListenSocket : public TCPListenSocket{
|
class SecureListenSocket : public TCPListenSocket{
|
||||||
public:
|
public:
|
||||||
|
@ -31,4 +33,10 @@ public:
|
||||||
// IListenSocket overrides
|
// IListenSocket overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
accept();
|
accept();
|
||||||
|
void deleteSocket(void*);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::set<IDataSocket*> SecureSocketSet;
|
||||||
|
|
||||||
|
SecureSocketSet m_secureSocketSet;
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,21 +68,6 @@ SecureSocket::~SecureSocket()
|
||||||
|
|
||||||
delete[] m_error;
|
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
|
void
|
||||||
SecureSocket::secureConnect()
|
SecureSocket::secureConnect()
|
||||||
|
|
|
@ -42,9 +42,6 @@ public:
|
||||||
ArchSocket socket);
|
ArchSocket socket);
|
||||||
~SecureSocket();
|
~SecureSocket();
|
||||||
|
|
||||||
// ISocket overrides
|
|
||||||
void close();
|
|
||||||
|
|
||||||
void secureConnect();
|
void secureConnect();
|
||||||
void secureAccept();
|
void secureAccept();
|
||||||
bool isSecureReady();
|
bool isSecureReady();
|
||||||
|
|
|
@ -59,7 +59,7 @@ invoke(const char* command, void** args)
|
||||||
arg2 = reinterpret_cast<SocketMultiplexer*>(args[1]);
|
arg2 = reinterpret_cast<SocketMultiplexer*>(args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(command, "getSecureSocket") == 0) {
|
if (strcmp(command, "getSocket") == 0) {
|
||||||
if (g_secureSocket != NULL) {
|
if (g_secureSocket != NULL) {
|
||||||
delete g_secureSocket;
|
delete g_secureSocket;
|
||||||
}
|
}
|
||||||
|
@ -67,17 +67,28 @@ invoke(const char* command, void** args)
|
||||||
g_secureSocket->initSsl(false);
|
g_secureSocket->initSsl(false);
|
||||||
return g_secureSocket;
|
return g_secureSocket;
|
||||||
}
|
}
|
||||||
else if (strcmp(command, "getSecureListenSocket") == 0) {
|
else if (strcmp(command, "getListenSocket") == 0) {
|
||||||
if (g_secureListenSocket != NULL) {
|
if (g_secureListenSocket != NULL) {
|
||||||
delete g_secureListenSocket;
|
delete g_secureListenSocket;
|
||||||
}
|
}
|
||||||
g_secureListenSocket = new SecureListenSocket(arg1, arg2);
|
g_secureListenSocket = new SecureListenSocket(arg1, arg2);
|
||||||
return g_secureListenSocket;
|
return g_secureListenSocket;
|
||||||
}
|
}
|
||||||
else {
|
else if (strcmp(command, "deleteSocket") == 0) {
|
||||||
return NULL;
|
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
|
void
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "synergy/IClient.h"
|
#include "synergy/IClient.h"
|
||||||
#include "base/String.h"
|
#include "base/String.h"
|
||||||
|
|
||||||
|
namespace synergy { class IStream; }
|
||||||
|
|
||||||
//! Generic proxy for client or primary
|
//! Generic proxy for client or primary
|
||||||
class BaseClientProxy : public IClient {
|
class BaseClientProxy : public IClient {
|
||||||
public:
|
public:
|
||||||
|
@ -82,6 +84,8 @@ public:
|
||||||
size_t size) = 0;
|
size_t size) = 0;
|
||||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
|
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
|
||||||
virtual String getName() const;
|
virtual String getName() const;
|
||||||
|
virtual synergy::IStream*
|
||||||
|
getStream() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_name;
|
String m_name;
|
||||||
|
|
|
@ -54,8 +54,8 @@ ClientListener::ClientListener(const NetworkAddress& address,
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// create listen socket
|
// create listen socket
|
||||||
m_useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
|
m_useSecureNetwork = ARCH->plugin().exists(s_networkSecurity);
|
||||||
m_listen = m_socketFactory->createListen(m_useSecureSocket);
|
m_listen = m_socketFactory->createListen(m_useSecureNetwork);
|
||||||
|
|
||||||
// bind listen address
|
// bind listen address
|
||||||
LOG((CLOG_DEBUG1 "binding listen socket"));
|
LOG((CLOG_DEBUG1 "binding listen socket"));
|
||||||
|
@ -115,6 +115,12 @@ ClientListener::setServer(Server* server)
|
||||||
m_server = server;
|
m_server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientListener::deleteSocket(void* socket)
|
||||||
|
{
|
||||||
|
m_listen->deleteSocket(socket);
|
||||||
|
}
|
||||||
|
|
||||||
ClientProxy*
|
ClientProxy*
|
||||||
ClientListener::getNextClient()
|
ClientListener::getNextClient()
|
||||||
{
|
{
|
||||||
|
@ -132,13 +138,16 @@ ClientListener::handleClientConnecting(const Event&, void*)
|
||||||
{
|
{
|
||||||
// accept client connection
|
// accept client connection
|
||||||
synergy::IStream* stream = m_listen->accept();
|
synergy::IStream* stream = m_listen->accept();
|
||||||
|
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG((CLOG_NOTE "accepted client connection"));
|
LOG((CLOG_NOTE "accepted client connection"));
|
||||||
|
|
||||||
// filter socket messages, including a packetizing filter
|
// 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) {
|
if (m_crypto.m_mode != kDisabled) {
|
||||||
CryptoStream* cryptoStream = new CryptoStream(
|
CryptoStream* cryptoStream = new CryptoStream(
|
||||||
|
@ -212,7 +221,13 @@ ClientListener::handleClientDisconnected(const Event&, void* vclient)
|
||||||
void
|
void
|
||||||
ClientListener::cleanupListenSocket()
|
ClientListener::cleanupListenSocket()
|
||||||
{
|
{
|
||||||
if (!m_useSecureSocket) {
|
if (!m_useSecureNetwork) {
|
||||||
delete m_listen;
|
delete m_listen;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ARCH->plugin().invoke(
|
||||||
|
s_networkSecurity,
|
||||||
|
"deleteListenSocket",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ public:
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
void deleteSocket(void* socket);
|
||||||
|
|
||||||
//! @name accessors
|
//! @name accessors
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
@ -84,5 +86,5 @@ private:
|
||||||
Server* m_server;
|
Server* m_server;
|
||||||
CryptoOptions m_crypto;
|
CryptoOptions m_crypto;
|
||||||
IEventQueue* m_events;
|
IEventQueue* m_events;
|
||||||
bool m_useSecureSocket;
|
bool m_useSecureNetwork;
|
||||||
};
|
};
|
||||||
|
|
|
@ -146,6 +146,9 @@ public:
|
||||||
virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
|
virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size);
|
||||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
|
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
|
||||||
|
|
||||||
|
virtual synergy::IStream*
|
||||||
|
getStream() const { return NULL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
synergy::Screen* m_screen;
|
synergy::Screen* m_screen;
|
||||||
bool m_clipboardDirty[kClipboardEnd];
|
bool m_clipboardDirty[kClipboardEnd];
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "server/ClientProxy.h"
|
#include "server/ClientProxy.h"
|
||||||
#include "server/ClientProxyUnknown.h"
|
#include "server/ClientProxyUnknown.h"
|
||||||
#include "server/PrimaryClient.h"
|
#include "server/PrimaryClient.h"
|
||||||
|
#include "server/ClientListener.h"
|
||||||
#include "synergy/IPlatformScreen.h"
|
#include "synergy/IPlatformScreen.h"
|
||||||
#include "synergy/DropHelper.h"
|
#include "synergy/DropHelper.h"
|
||||||
#include "synergy/option_types.h"
|
#include "synergy/option_types.h"
|
||||||
|
@ -30,6 +31,8 @@
|
||||||
#include "synergy/FileChunker.h"
|
#include "synergy/FileChunker.h"
|
||||||
#include "synergy/KeyState.h"
|
#include "synergy/KeyState.h"
|
||||||
#include "synergy/Screen.h"
|
#include "synergy/Screen.h"
|
||||||
|
#include "synergy/PacketStreamFilter.h"
|
||||||
|
#include "net/TCPSocket.h"
|
||||||
#include "net/IDataSocket.h"
|
#include "net/IDataSocket.h"
|
||||||
#include "net/IListenSocket.h"
|
#include "net/IListenSocket.h"
|
||||||
#include "net/XSocket.h"
|
#include "net/XSocket.h"
|
||||||
|
@ -1358,7 +1361,11 @@ Server::handleClientDisconnected(const Event&, void* vclient)
|
||||||
BaseClientProxy* client = reinterpret_cast<BaseClientProxy*>(vclient);
|
BaseClientProxy* client = reinterpret_cast<BaseClientProxy*>(vclient);
|
||||||
removeActiveClient(client);
|
removeActiveClient(client);
|
||||||
removeOldClient(client);
|
removeOldClient(client);
|
||||||
|
|
||||||
|
PacketStreamFilter* streamFileter = dynamic_cast<PacketStreamFilter*>(client->getStream());
|
||||||
|
TCPSocket* socket = dynamic_cast<TCPSocket*>(streamFileter->getStream());
|
||||||
delete client;
|
delete client;
|
||||||
|
m_clientListener->deleteSocket(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -39,6 +39,7 @@ class InputFilter;
|
||||||
namespace synergy { class Screen; }
|
namespace synergy { class Screen; }
|
||||||
class IEventQueue;
|
class IEventQueue;
|
||||||
class Thread;
|
class Thread;
|
||||||
|
class ClientListener;
|
||||||
|
|
||||||
//! Synergy server
|
//! Synergy server
|
||||||
/*!
|
/*!
|
||||||
|
@ -155,6 +156,9 @@ public:
|
||||||
//! Received dragging information from client
|
//! Received dragging information from client
|
||||||
void dragInfoReceived(UInt32 fileNum, String content);
|
void dragInfoReceived(UInt32 fileNum, String content);
|
||||||
|
|
||||||
|
//! Store ClientListener pointer
|
||||||
|
void setListener(ClientListener* p) { m_clientListener = p; }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
//! @name accessors
|
//! @name accessors
|
||||||
//@{
|
//@{
|
||||||
|
@ -474,4 +478,6 @@ private:
|
||||||
|
|
||||||
Thread* m_getDragInfoThread;
|
Thread* m_getDragInfoThread;
|
||||||
bool m_waitDragInfoThread;
|
bool m_waitDragInfoThread;
|
||||||
|
|
||||||
|
ClientListener* m_clientListener;
|
||||||
};
|
};
|
||||||
|
|
|
@ -543,6 +543,7 @@ ServerApp::startServer()
|
||||||
listener = openClientListener(args().m_config->getSynergyAddress());
|
listener = openClientListener(args().m_config->getSynergyAddress());
|
||||||
m_server = openServer(*args().m_config, m_primaryClient);
|
m_server = openServer(*args().m_config, m_primaryClient);
|
||||||
listener->setServer(m_server);
|
listener->setServer(m_server);
|
||||||
|
m_server->setListener(listener);
|
||||||
m_listener = listener;
|
m_listener = listener;
|
||||||
updateStatus();
|
updateStatus();
|
||||||
LOG((CLOG_NOTE "started server, waiting for clients"));
|
LOG((CLOG_NOTE "started server, waiting for clients"));
|
||||||
|
|
Loading…
Reference in New Issue