sending IV to client before DKDN, DKUP and DKRP (the most sensitive messages). unit tests to support changes. made crypto stream tests a bit less spammy by using NiceMock.

This commit is contained in:
Nick Bolton
2013-04-09 18:56:19 +00:00
parent 23998fc06c
commit 7010de9cc4
37 changed files with 490 additions and 227 deletions

View File

@@ -48,16 +48,12 @@ CEvent::Type CClient::s_connectedEvent = CEvent::kUnknown;
CEvent::Type CClient::s_connectionFailedEvent = CEvent::kUnknown;
CEvent::Type CClient::s_disconnectedEvent = CEvent::kUnknown;
CClient::CClient(IEventQueue& eventQueue) :
m_eventQueue(eventQueue)
{
}
CClient::CClient(IEventQueue& eventQueue,
CClient::CClient(IEventQueue* eventQueue,
const CString& name, const CNetworkAddress& address,
ISocketFactory* socketFactory,
IStreamFilterFactory* streamFilterFactory,
CScreen* screen) :
m_mock(false),
m_name(name),
m_serverAddress(address),
m_socketFactory(socketFactory),
@@ -71,25 +67,25 @@ CClient::CClient(IEventQueue& eventQueue,
m_suspended(false),
m_connectOnResume(false),
m_eventQueue(eventQueue),
m_mock(false)
m_cryptoStream(NULL)
{
assert(m_socketFactory != NULL);
assert(m_screen != NULL);
// register suspend/resume event handlers
m_eventQueue.adoptHandler(IScreen::getSuspendEvent(),
m_eventQueue->adoptHandler(IScreen::getSuspendEvent(),
getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleSuspend));
m_eventQueue.adoptHandler(IScreen::getResumeEvent(),
m_eventQueue->adoptHandler(IScreen::getResumeEvent(),
getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleResume));
EVENTQUEUE->adoptHandler(IPlatformScreen::getGameDeviceTimingRespEvent(),
m_eventQueue->adoptHandler(IPlatformScreen::getGameDeviceTimingRespEvent(),
getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleGameDeviceTimingResp));
EVENTQUEUE->adoptHandler(IPlatformScreen::getGameDeviceFeedbackEvent(),
m_eventQueue->adoptHandler(IPlatformScreen::getGameDeviceFeedbackEvent(),
getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleGameDeviceFeedback));
@@ -97,13 +93,13 @@ CClient::CClient(IEventQueue& eventQueue,
CClient::~CClient()
{
// HACK: can't disable dtor with mocks
if (m_mock)
if (m_mock) {
return;
}
m_eventQueue.removeHandler(IScreen::getSuspendEvent(),
m_eventQueue->removeHandler(IScreen::getSuspendEvent(),
getEventTarget());
m_eventQueue.removeHandler(IScreen::getResumeEvent(),
m_eventQueue->removeHandler(IScreen::getResumeEvent(),
getEventTarget());
cleanupTimer();
@@ -153,9 +149,9 @@ CClient::connect()
m_stream = new CPacketStreamFilter(m_stream, true);
if (s_cryptoEnabled) {
CCryptoStream* cryptoStream = new CCryptoStream(*EVENTQUEUE, m_stream, true);
cryptoStream->setKeyWithIv(g_key, sizeof(g_key), g_iv);
m_stream = cryptoStream;
m_cryptoStream = new CCryptoStream(m_eventQueue, m_stream, true);
m_cryptoStream->setKeyWithIv(g_key, sizeof(g_key), g_iv);
m_stream = m_cryptoStream;
}
// connect
@@ -199,6 +195,14 @@ CClient::handshakeComplete()
sendEvent(getConnectedEvent(), NULL);
}
void
CClient::setCryptoIv(const UInt8* iv)
{
if (m_cryptoStream != NULL) {
m_cryptoStream->setIv(iv);
}
}
bool
CClient::isConnected() const
{
@@ -444,7 +448,7 @@ CClient::sendClipboard(ClipboardID id)
void
CClient::sendEvent(CEvent::Type type, void* data)
{
m_eventQueue.addEvent(CEvent(type, getEventTarget(), data));
m_eventQueue->addEvent(CEvent(type, getEventTarget(), data));
}
void
@@ -453,7 +457,7 @@ CClient::sendConnectionFailedEvent(const char* msg)
CFailInfo* info = new CFailInfo(msg);
info->m_retry = true;
CEvent event(getConnectionFailedEvent(), getEventTarget(), info, CEvent::kDontFreeData);
EVENTQUEUE->addEvent(event);
m_eventQueue->addEvent(event);
}
void
@@ -461,11 +465,11 @@ CClient::setupConnecting()
{
assert(m_stream != NULL);
m_eventQueue.adoptHandler(IDataSocket::getConnectedEvent(),
m_eventQueue->adoptHandler(IDataSocket::getConnectedEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleConnected));
m_eventQueue.adoptHandler(IDataSocket::getConnectionFailedEvent(),
m_eventQueue->adoptHandler(IDataSocket::getConnectionFailedEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleConnectionFailed));
@@ -476,23 +480,23 @@ CClient::setupConnection()
{
assert(m_stream != NULL);
m_eventQueue.adoptHandler(ISocket::getDisconnectedEvent(),
m_eventQueue->adoptHandler(ISocket::getDisconnectedEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleDisconnected));
m_eventQueue.adoptHandler(m_stream->getInputReadyEvent(),
m_eventQueue->adoptHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleHello));
m_eventQueue.adoptHandler(m_stream->getOutputErrorEvent(),
m_eventQueue->adoptHandler(m_stream->getOutputErrorEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleOutputError));
m_eventQueue.adoptHandler(m_stream->getInputShutdownEvent(),
m_eventQueue->adoptHandler(m_stream->getInputShutdownEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleDisconnected));
m_eventQueue.adoptHandler(m_stream->getOutputShutdownEvent(),
m_eventQueue->adoptHandler(m_stream->getOutputShutdownEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleDisconnected));
@@ -504,12 +508,12 @@ CClient::setupScreen()
assert(m_server == NULL);
m_ready = false;
m_server = new CServerProxy(this, m_stream, *EVENTQUEUE);
m_eventQueue.adoptHandler(IScreen::getShapeChangedEvent(),
m_server = new CServerProxy(this, m_stream, m_eventQueue);
m_eventQueue->adoptHandler(IScreen::getShapeChangedEvent(),
getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleShapeChanged));
m_eventQueue.adoptHandler(IScreen::getClipboardGrabbedEvent(),
m_eventQueue->adoptHandler(IScreen::getClipboardGrabbedEvent(),
getEventTarget(),
new TMethodEventJob<CClient>(this,
&CClient::handleClipboardGrabbed));
@@ -520,8 +524,8 @@ CClient::setupTimer()
{
assert(m_timer == NULL);
m_timer = m_eventQueue.newOneShotTimer(15.0, NULL);
m_eventQueue.adoptHandler(CEvent::kTimer, m_timer,
m_timer = m_eventQueue->newOneShotTimer(15.0, NULL);
m_eventQueue->adoptHandler(CEvent::kTimer, m_timer,
new TMethodEventJob<CClient>(this,
&CClient::handleConnectTimeout));
}
@@ -530,9 +534,9 @@ void
CClient::cleanupConnecting()
{
if (m_stream != NULL) {
m_eventQueue.removeHandler(IDataSocket::getConnectedEvent(),
m_eventQueue->removeHandler(IDataSocket::getConnectedEvent(),
m_stream->getEventTarget());
m_eventQueue.removeHandler(IDataSocket::getConnectionFailedEvent(),
m_eventQueue->removeHandler(IDataSocket::getConnectionFailedEvent(),
m_stream->getEventTarget());
}
}
@@ -541,15 +545,15 @@ void
CClient::cleanupConnection()
{
if (m_stream != NULL) {
m_eventQueue.removeHandler(m_stream->getInputReadyEvent(),
m_eventQueue->removeHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget());
m_eventQueue.removeHandler(m_stream->getOutputErrorEvent(),
m_eventQueue->removeHandler(m_stream->getOutputErrorEvent(),
m_stream->getEventTarget());
m_eventQueue.removeHandler(m_stream->getInputShutdownEvent(),
m_eventQueue->removeHandler(m_stream->getInputShutdownEvent(),
m_stream->getEventTarget());
m_eventQueue.removeHandler(m_stream->getOutputShutdownEvent(),
m_eventQueue->removeHandler(m_stream->getOutputShutdownEvent(),
m_stream->getEventTarget());
m_eventQueue.removeHandler(ISocket::getDisconnectedEvent(),
m_eventQueue->removeHandler(ISocket::getDisconnectedEvent(),
m_stream->getEventTarget());
delete m_stream;
m_stream = NULL;
@@ -564,9 +568,9 @@ CClient::cleanupScreen()
m_screen->disable();
m_ready = false;
}
m_eventQueue.removeHandler(IScreen::getShapeChangedEvent(),
m_eventQueue->removeHandler(IScreen::getShapeChangedEvent(),
getEventTarget());
m_eventQueue.removeHandler(IScreen::getClipboardGrabbedEvent(),
m_eventQueue->removeHandler(IScreen::getClipboardGrabbedEvent(),
getEventTarget());
delete m_server;
m_server = NULL;
@@ -577,8 +581,8 @@ void
CClient::cleanupTimer()
{
if (m_timer != NULL) {
m_eventQueue.removeHandler(CEvent::kTimer, m_timer);
m_eventQueue.deleteTimer(m_timer);
m_eventQueue->removeHandler(CEvent::kTimer, m_timer);
m_eventQueue->deleteTimer(m_timer);
m_timer = NULL;
}
}
@@ -708,7 +712,7 @@ CClient::handleHello(const CEvent&, void*)
// receive another event for already pending messages so we fake
// one.
if (m_stream->isReady()) {
m_eventQueue.addEvent(CEvent(m_stream->getInputReadyEvent(),
m_eventQueue->addEvent(CEvent(m_stream->getInputReadyEvent(),
m_stream->getEventTarget()));
}
}

View File

@@ -32,6 +32,7 @@ class ISocketFactory;
namespace synergy { class IStream; }
class IStreamFilterFactory;
class IEventQueue;
class CCryptoStream;
//! Synergy client
/*!
@@ -46,21 +47,22 @@ public:
CString m_what;
};
protected:
CClient(IEventQueue& eventQueue);
public:
/*!
This client will attempt to connect to the server using \p name
as its name and \p address as the server's address and \p factory
to create the socket. \p screen is the local screen.
*/
CClient(IEventQueue& eventQueue,
CClient(IEventQueue* eventQueue,
const CString& name, const CNetworkAddress& address,
ISocketFactory* socketFactory,
IStreamFilterFactory* streamFilterFactory,
CScreen* screen);
~CClient();
#ifdef TEST_ENV
CClient() { }
#endif
//! @name manipulators
//@{
@@ -82,7 +84,10 @@ public:
/*!
Notifies the client that the connection handshake has completed.
*/
void handshakeComplete();
virtual void handshakeComplete();
//! Set crypto IV
virtual void setCryptoIv(const UInt8* iv);
//@}
//! @name accessors
@@ -190,6 +195,9 @@ private:
void handleGameDeviceTimingResp(const CEvent& event, void*);
void handleGameDeviceFeedback(const CEvent& event, void*);
public:
bool m_mock;
private:
CString m_name;
CNetworkAddress m_serverAddress;
@@ -207,8 +215,8 @@ private:
bool m_sentClipboard[kClipboardEnd];
IClipboard::Time m_timeClipboard[kClipboardEnd];
CString m_dataClipboard[kClipboardEnd];
IEventQueue& m_eventQueue;
bool m_mock;
IEventQueue* m_eventQueue;
CCryptoStream* m_cryptoStream;
static CEvent::Type s_connectedEvent;
static CEvent::Type s_connectionFailedEvent;

View File

@@ -35,10 +35,9 @@
// CServerProxy
//
CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue& eventQueue) :
CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue* eventQueue) :
m_client(client),
m_stream(stream),
m_cryptoStream(NULL),
m_seqNum(0),
m_compressMouse(false),
m_compressMouseRelative(false),
@@ -60,7 +59,7 @@ CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueu
m_modifierTranslationTable[id] = id;
// handle data on stream
m_eventQueue.adoptHandler(m_stream->getInputReadyEvent(),
m_eventQueue->adoptHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget(),
new TMethodEventJob<CServerProxy>(this,
&CServerProxy::handleData));
@@ -72,7 +71,7 @@ CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueu
CServerProxy::~CServerProxy()
{
setKeepAliveRate(-1.0);
m_eventQueue.removeHandler(m_stream->getInputReadyEvent(),
m_eventQueue->removeHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget());
}
@@ -80,14 +79,14 @@ void
CServerProxy::resetKeepAliveAlarm()
{
if (m_keepAliveAlarmTimer != NULL) {
m_eventQueue.removeHandler(CEvent::kTimer, m_keepAliveAlarmTimer);
m_eventQueue.deleteTimer(m_keepAliveAlarmTimer);
m_eventQueue->removeHandler(CEvent::kTimer, m_keepAliveAlarmTimer);
m_eventQueue->deleteTimer(m_keepAliveAlarmTimer);
m_keepAliveAlarmTimer = NULL;
}
if (m_keepAliveAlarm > 0.0) {
m_keepAliveAlarmTimer =
m_eventQueue.newOneShotTimer(m_keepAliveAlarm, NULL);
m_eventQueue.adoptHandler(CEvent::kTimer, m_keepAliveAlarmTimer,
m_eventQueue->newOneShotTimer(m_keepAliveAlarm, NULL);
m_eventQueue->adoptHandler(CEvent::kTimer, m_keepAliveAlarmTimer,
new TMethodEventJob<CServerProxy>(this,
&CServerProxy::handleKeepAliveAlarm));
}
@@ -306,6 +305,10 @@ CServerProxy::parseMessage(const UInt8* code)
gameDeviceTimingReq();
}
else if (memcmp(code, kMsgDCryptoIv, 4) == 0) {
cryptoIv();
}
else if (memcmp(code, kMsgCClose, 4) == 0) {
// server wants us to hangup
LOG((CLOG_DEBUG1 "recv close"));
@@ -826,6 +829,18 @@ CServerProxy::gameDeviceTimingReq()
m_client->gameDeviceTimingReq();
}
void
CServerProxy::cryptoIv()
{
// parse
CString s;
CProtocolUtil::readf(m_stream, kMsgDCryptoIv + 4, &s);
LOG((CLOG_DEBUG2 "recv crypto iv size=%i", s.size()));
// forward
m_client->setCryptoIv(reinterpret_cast<const UInt8*>(s.c_str()));
}
void
CServerProxy::screensaver()
{

View File

@@ -30,7 +30,6 @@ class CEventQueueTimer;
class IClipboard;
namespace synergy { class IStream; }
class IEventQueue;
class CCryptoStream;
//! Proxy for server
/*!
@@ -43,7 +42,7 @@ public:
Process messages from the server on \p stream and forward to
\p client.
*/
CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue& eventQueue);
CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue* eventQueue);
~CServerProxy();
//! @name manipulators
@@ -57,6 +56,10 @@ public:
//@}
#ifdef TEST_ENV
void handleDataForTest() { handleData(NULL, NULL); }
#endif
protected:
enum EResult { kOkay, kUnknown, kDisconnect };
EResult parseHandshakeMessage(const UInt8* code);
@@ -96,6 +99,7 @@ private:
void gameDeviceSticks();
void gameDeviceTriggers();
void gameDeviceTimingReq();
void cryptoIv();
void screensaver();
void resetOptions();
void setOptions();
@@ -107,7 +111,6 @@ private:
CClient* m_client;
synergy::IStream* m_stream;
CCryptoStream* m_cryptoStream;
UInt32 m_seqNum;
@@ -124,7 +127,7 @@ private:
CEventQueueTimer* m_keepAliveAlarmTimer;
MessageParser m_parser;
IEventQueue& m_eventQueue;
IEventQueue* m_eventQueue;
};
#endif

View File

@@ -24,21 +24,21 @@
// CStreamFilter
//
CStreamFilter::CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream) :
CStreamFilter::CStreamFilter(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream) :
IStream(eventQueue),
m_stream(stream),
m_adopted(adoptStream)
{
// replace handlers for m_stream
m_eventQueue.removeHandlers(m_stream->getEventTarget());
m_eventQueue.adoptHandler(CEvent::kUnknown, m_stream->getEventTarget(),
getEventQueue().removeHandlers(m_stream->getEventTarget());
getEventQueue().adoptHandler(CEvent::kUnknown, m_stream->getEventTarget(),
new TMethodEventJob<CStreamFilter>(this,
&CStreamFilter::handleUpstreamEvent));
}
CStreamFilter::~CStreamFilter()
{
m_eventQueue.removeHandler(CEvent::kUnknown, m_stream->getEventTarget());
getEventQueue().removeHandler(CEvent::kUnknown, m_stream->getEventTarget());
if (m_adopted) {
delete m_stream;
}
@@ -107,7 +107,7 @@ CStreamFilter::getStream() const
void
CStreamFilter::filterEvent(const CEvent& event)
{
m_eventQueue.dispatchEvent(CEvent(event.getType(),
getEventQueue().dispatchEvent(CEvent(event.getType(),
getEventTarget(), event.getData()));
}

View File

@@ -34,7 +34,7 @@ public:
this object takes ownership of the stream and will delete it in the
d'tor.
*/
CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream = true);
CStreamFilter(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream = true);
virtual ~CStreamFilter();
// IStream overrides

View File

@@ -34,34 +34,41 @@ CEvent::Type IStream::s_outputShutdownEvent = CEvent::kUnknown;
CEvent::Type
IStream::getInputReadyEvent()
{
return m_eventQueue.registerTypeOnce(s_inputReadyEvent,
return m_eventQueue->registerTypeOnce(s_inputReadyEvent,
"IStream::inputReady");
}
CEvent::Type
IStream::getOutputFlushedEvent()
{
return m_eventQueue.registerTypeOnce(s_outputFlushedEvent,
return m_eventQueue->registerTypeOnce(s_outputFlushedEvent,
"IStream::outputFlushed");
}
CEvent::Type
IStream::getOutputErrorEvent()
{
return m_eventQueue.registerTypeOnce(s_outputErrorEvent,
return m_eventQueue->registerTypeOnce(s_outputErrorEvent,
"IStream::outputError");
}
CEvent::Type
IStream::getInputShutdownEvent()
{
return m_eventQueue.registerTypeOnce(s_inputShutdownEvent,
return m_eventQueue->registerTypeOnce(s_inputShutdownEvent,
"IStream::inputShutdown");
}
CEvent::Type
IStream::getOutputShutdownEvent()
{
return m_eventQueue.registerTypeOnce(s_outputShutdownEvent,
return m_eventQueue->registerTypeOnce(s_outputShutdownEvent,
"IStream::outputShutdown");
}
IEventQueue&
IStream::getEventQueue() const
{
assert(m_eventQueue != NULL);
return *m_eventQueue;
}

View File

@@ -33,8 +33,8 @@ Defines the interface for all streams.
*/
class IStream : public IInterface {
public:
IStream() : m_eventQueue(*EVENTQUEUE) { }
IStream(IEventQueue& eventQueue) : m_eventQueue(eventQueue) { }
IStream() : m_eventQueue(EVENTQUEUE) { }
IStream(IEventQueue* eventQueue) : m_eventQueue(eventQueue) { }
//! @name manipulators
//@{
@@ -156,9 +156,10 @@ public:
*/
virtual CEvent::Type getOutputShutdownEvent();
//@}
//! Get the event queue
IEventQueue& getEventQueue() const;
IEventQueue& m_eventQueue;
//@}
private:
static CEvent::Type s_inputReadyEvent;
@@ -166,6 +167,8 @@ private:
static CEvent::Type s_outputErrorEvent;
static CEvent::Type s_inputShutdownEvent;
static CEvent::Type s_outputShutdownEvent;
IEventQueue* m_eventQueue;
};
}

View File

@@ -150,7 +150,7 @@ CClientListener::handleClientConnecting(const CEvent&, void*)
stream = new CPacketStreamFilter(stream, true);
if (s_cryptoEnabled) {
CCryptoStream* cryptoStream = new CCryptoStream(*EVENTQUEUE, stream, true);
CCryptoStream* cryptoStream = new CCryptoStream(EVENTQUEUE, stream, true);
cryptoStream->setKeyWithIv(g_key, sizeof(g_key), g_iv);
stream = cryptoStream;
}

View File

@@ -25,8 +25,6 @@
namespace synergy { class IStream; }
const int g_encryptionEnabled = true;
//! Generic proxy for client
class CClientProxy : public CBaseClientProxy {
public:
@@ -49,12 +47,6 @@ public:
//! @name accessors
//@{
//! Get stream (unmodified)
/*!
Returns the original stream passed to the c'tor.
*/
synergy::IStream* getStreamUnmodified() const;
//! Get stream
/*!
Returns a crypto stream if the user has this enabled,
@@ -125,6 +117,7 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2) = 0;
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2) = 0;
virtual void gameDeviceTimingReq() = 0;
virtual void cryptoIv(const UInt8* iv) = 0;
private:
synergy::IStream* m_stream;

View File

@@ -29,29 +29,30 @@
// CClientProxy1_0
//
CClientProxy1_0::CClientProxy1_0(const CString& name, synergy::IStream* stream) :
CClientProxy1_0::CClientProxy1_0(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy(name, stream),
m_heartbeatTimer(NULL),
m_parser(&CClientProxy1_0::parseHandshakeMessage)
m_parser(&CClientProxy1_0::parseHandshakeMessage),
m_eventQueue(eventQueue)
{
// install event handlers
EVENTQUEUE->adoptHandler(stream->getInputReadyEvent(),
m_eventQueue->adoptHandler(stream->getInputReadyEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleData, NULL));
EVENTQUEUE->adoptHandler(stream->getOutputErrorEvent(),
m_eventQueue->adoptHandler(stream->getOutputErrorEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleWriteError, NULL));
EVENTQUEUE->adoptHandler(stream->getInputShutdownEvent(),
m_eventQueue->adoptHandler(stream->getInputShutdownEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleDisconnect, NULL));
EVENTQUEUE->adoptHandler(stream->getOutputShutdownEvent(),
m_eventQueue->adoptHandler(stream->getOutputShutdownEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleWriteError, NULL));
EVENTQUEUE->adoptHandler(CEvent::kTimer, this,
m_eventQueue->adoptHandler(CEvent::kTimer, this,
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleFlatline, NULL));
@@ -71,22 +72,22 @@ CClientProxy1_0::disconnect()
{
removeHandlers();
getStream()->close();
EVENTQUEUE->addEvent(CEvent(getDisconnectedEvent(), getEventTarget()));
m_eventQueue->addEvent(CEvent(getDisconnectedEvent(), getEventTarget()));
}
void
CClientProxy1_0::removeHandlers()
{
// uninstall event handlers
EVENTQUEUE->removeHandler(getStream()->getInputReadyEvent(),
m_eventQueue->removeHandler(getStream()->getInputReadyEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(getStream()->getOutputErrorEvent(),
m_eventQueue->removeHandler(getStream()->getOutputErrorEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(getStream()->getInputShutdownEvent(),
m_eventQueue->removeHandler(getStream()->getInputShutdownEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(getStream()->getOutputShutdownEvent(),
m_eventQueue->removeHandler(getStream()->getOutputShutdownEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(CEvent::kTimer, this);
m_eventQueue->removeHandler(CEvent::kTimer, this);
// remove timer
removeHeartbeatTimer();
@@ -96,7 +97,7 @@ void
CClientProxy1_0::addHeartbeatTimer()
{
if (m_heartbeatAlarm > 0.0) {
m_heartbeatTimer = EVENTQUEUE->newOneShotTimer(m_heartbeatAlarm, this);
m_heartbeatTimer = m_eventQueue->newOneShotTimer(m_heartbeatAlarm, this);
}
}
@@ -104,7 +105,7 @@ void
CClientProxy1_0::removeHeartbeatTimer()
{
if (m_heartbeatTimer != NULL) {
EVENTQUEUE->deleteTimer(m_heartbeatTimer);
m_eventQueue->deleteTimer(m_heartbeatTimer);
m_heartbeatTimer = NULL;
}
}
@@ -171,7 +172,7 @@ CClientProxy1_0::parseHandshakeMessage(const UInt8* code)
// future messages get parsed by parseMessage
m_parser = &CClientProxy1_0::parseMessage;
if (recvInfo()) {
EVENTQUEUE->addEvent(CEvent(getReadyEvent(), getEventTarget()));
m_eventQueue->addEvent(CEvent(getReadyEvent(), getEventTarget()));
addHeartbeatTimer();
return true;
}
@@ -184,7 +185,7 @@ CClientProxy1_0::parseMessage(const UInt8* code)
{
if (memcmp(code, kMsgDInfo, 4) == 0) {
if (recvInfo()) {
EVENTQUEUE->addEvent(
m_eventQueue->addEvent(
CEvent(getShapeChangedEvent(), getEventTarget()));
return true;
}
@@ -385,6 +386,13 @@ CClientProxy1_0::gameDeviceTimingReq()
LOG((CLOG_DEBUG "gameDeviceTimingReq not supported"));
}
void
CClientProxy1_0::cryptoIv(const UInt8* iv)
{
// ignore -- not supported in protocol 1.0
LOG((CLOG_DEBUG "cryptoIv not supported"));
}
void
CClientProxy1_0::screensaver(bool on)
{
@@ -484,7 +492,7 @@ CClientProxy1_0::recvClipboard()
CClipboardInfo* info = new CClipboardInfo;
info->m_id = id;
info->m_sequenceNumber = seqNum;
EVENTQUEUE->addEvent(CEvent(getClipboardChangedEvent(),
m_eventQueue->addEvent(CEvent(getClipboardChangedEvent(),
getEventTarget(), info));
return true;
@@ -510,7 +518,7 @@ CClientProxy1_0::recvGrabClipboard()
CClipboardInfo* info = new CClipboardInfo;
info->m_id = id;
info->m_sequenceNumber = seqNum;
EVENTQUEUE->addEvent(CEvent(getClipboardGrabbedEvent(),
m_eventQueue->addEvent(CEvent(getClipboardGrabbedEvent(),
getEventTarget(), info));
return true;

View File

@@ -25,11 +25,12 @@
class CEvent;
class CEventQueueTimer;
class IEventQueue;
//! Proxy for client implementing protocol version 1.0
class CClientProxy1_0 : public CClientProxy {
public:
CClientProxy1_0(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_0(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_0();
// IScreen
@@ -62,6 +63,7 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
virtual void gameDeviceTimingReq();
virtual void cryptoIv(const UInt8* iv);
protected:
virtual bool parseHandshakeMessage(const UInt8* code);
@@ -103,6 +105,7 @@ private:
double m_heartbeatAlarm;
CEventQueueTimer* m_heartbeatTimer;
MessageParser m_parser;
IEventQueue* m_eventQueue;
};
#endif

View File

@@ -25,8 +25,8 @@
// CClientProxy1_1
//
CClientProxy1_1::CClientProxy1_1(const CString& name, synergy::IStream* stream) :
CClientProxy1_0(name, stream)
CClientProxy1_1::CClientProxy1_1(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy1_0(name, stream, eventQueue)
{
// do nothing
}

View File

@@ -24,7 +24,7 @@
//! Proxy for client implementing protocol version 1.1
class CClientProxy1_1 : public CClientProxy1_0 {
public:
CClientProxy1_1(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_1(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_1();
// IClient overrides

View File

@@ -24,8 +24,8 @@
// CClientProxy1_1
//
CClientProxy1_2::CClientProxy1_2(const CString& name, synergy::IStream* stream) :
CClientProxy1_1(name, stream)
CClientProxy1_2::CClientProxy1_2(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy1_1(name, stream, eventQueue)
{
// do nothing
}

View File

@@ -21,10 +21,12 @@
#include "CClientProxy1_1.h"
class IEventQueue;
//! Proxy for client implementing protocol version 1.2
class CClientProxy1_2 : public CClientProxy1_1 {
public:
CClientProxy1_2(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_2(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_2();
// IClient overrides

View File

@@ -28,8 +28,8 @@
// CClientProxy1_3
//
CClientProxy1_3::CClientProxy1_3(const CString& name, synergy::IStream* stream) :
CClientProxy1_2(name, stream),
CClientProxy1_3::CClientProxy1_3(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy1_2(name, stream, eventQueue),
m_keepAliveRate(kKeepAliveRate),
m_keepAliveTimer(NULL)
{

View File

@@ -24,7 +24,7 @@
//! Proxy for client implementing protocol version 1.3
class CClientProxy1_3 : public CClientProxy1_2 {
public:
CClientProxy1_3(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_3(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_3();
// IClient overrides

View File

@@ -24,13 +24,14 @@
#include <cstring>
#include <memory>
#include "CServer.h"
#include "CCryptoStream.h"
//
// CClientProxy1_4
//
CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server) :
CClientProxy1_3(name, stream), m_server(server)
CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server, IEventQueue* eventQueue) :
CClientProxy1_3(name, stream, eventQueue), m_server(server)
{
assert(m_server != NULL);
}
@@ -67,6 +68,43 @@ CClientProxy1_4::gameDeviceTimingReq()
CProtocolUtil::writef(getStream(), kMsgCGameTimingReq);
}
void
CClientProxy1_4::keyDown(KeyID key, KeyModifierMask mask, KeyButton button)
{
cryptoIv();
CClientProxy1_3::keyDown(key, mask, button);
}
void
CClientProxy1_4::keyRepeat(KeyID key, KeyModifierMask mask, SInt32 count, KeyButton button)
{
cryptoIv();
CClientProxy1_3::keyRepeat(key, mask, count, button);
}
void
CClientProxy1_4::keyUp(KeyID key, KeyModifierMask mask, KeyButton button)
{
cryptoIv();
CClientProxy1_3::keyUp(key, mask, button);
}
void
CClientProxy1_4::cryptoIv()
{
CCryptoStream* cryptoStream = dynamic_cast<CCryptoStream*>(getStream());
if (cryptoStream == NULL) {
return;
}
byte iv[CRYPTO_IV_SIZE];
cryptoStream->newIv(iv);
CString data(reinterpret_cast<const char*>(iv), CRYPTO_IV_SIZE);
LOG((CLOG_DEBUG2 "send crypto iv change to \"%s\"", getName().c_str()));
CProtocolUtil::writef(getStream(), kMsgDCryptoIv, &data);
}
bool
CClientProxy1_4::parseMessage(const UInt8* code)
{

View File

@@ -26,7 +26,7 @@ class CServer;
//! Proxy for client implementing protocol version 1.4
class CClientProxy1_4 : public CClientProxy1_3 {
public:
CClientProxy1_4(const CString& name, synergy::IStream* adoptedStream, CServer* server);
CClientProxy1_4(const CString& name, synergy::IStream* adoptedStream, CServer* server, IEventQueue* eventQueue);
~CClientProxy1_4();
// IClient overrides
@@ -34,6 +34,12 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
virtual void gameDeviceTimingReq();
virtual void keyDown(KeyID key, KeyModifierMask mask, KeyButton button);
virtual void keyRepeat(KeyID key, KeyModifierMask mask, SInt32 count, KeyButton button);
virtual void keyUp(KeyID key, KeyModifierMask mask, KeyButton button);
//! Send IV to make
void cryptoIv();
protected:
// CClientProxy overrides

View File

@@ -219,23 +219,23 @@ CClientProxyUnknown::handleData(const CEvent&, void*)
if (major == 1) {
switch (minor) {
case 0:
m_proxy = new CClientProxy1_0(name, m_stream);
m_proxy = new CClientProxy1_0(name, m_stream, EVENTQUEUE);
break;
case 1:
m_proxy = new CClientProxy1_1(name, m_stream);
m_proxy = new CClientProxy1_1(name, m_stream, EVENTQUEUE);
break;
case 2:
m_proxy = new CClientProxy1_2(name, m_stream);
m_proxy = new CClientProxy1_2(name, m_stream, EVENTQUEUE);
break;
case 3:
m_proxy = new CClientProxy1_3(name, m_stream);
m_proxy = new CClientProxy1_3(name, m_stream, EVENTQUEUE);
break;
case 4:
m_proxy = new CClientProxy1_4(name, m_stream, m_server);
m_proxy = new CClientProxy1_4(name, m_stream, m_server, EVENTQUEUE);
break;
}
}

View File

@@ -51,6 +51,7 @@ CEvent::Type CServer::s_lockCursorToScreen = CEvent::kUnknown;
CEvent::Type CServer::s_screenSwitched = CEvent::kUnknown;
CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen* screen) :
m_mock(false),
m_primaryClient(primaryClient),
m_active(primaryClient),
m_seqNum(0),
@@ -202,6 +203,10 @@ CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen*
CServer::~CServer()
{
if (m_mock) {
return;
}
// remove event handlers and timers
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
m_inputFilter);

View File

@@ -103,6 +103,10 @@ public:
*/
CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen* screen);
~CServer();
#ifdef TEST_ENV
CServer() { }
#endif
//! @name manipulators
//@{
@@ -394,6 +398,9 @@ private:
// force the cursor off of \p client
void forceLeaveClient(CBaseClientProxy* client);
public:
bool m_mock;
private:
class CClipboardInfo {

View File

@@ -396,7 +396,7 @@ CClient*
CClientApp::openClient(const CString& name, const CNetworkAddress& address, CScreen* screen)
{
CClient* client = new CClient(
*EVENTQUEUE, name, address, new CTCPSocketFactory, NULL, screen);
EVENTQUEUE, name, address, new CTCPSocketFactory, NULL, screen);
try {
EVENTQUEUE->adoptHandler(

View File

@@ -22,7 +22,7 @@
using namespace CryptoPP;
CCryptoStream::CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream) :
CCryptoStream::CCryptoStream(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream) :
CStreamFilter(eventQueue, stream, adoptStream),
m_key(NULL),
m_keyLength(0)

View File

@@ -32,7 +32,7 @@ Encrypts (on write) and decrypts (on read) to and from an underlying stream.
*/
class CCryptoStream : public CStreamFilter {
public:
CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream = true);
CCryptoStream(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream = true);
virtual ~CCryptoStream();
//! @name manipulators

View File

@@ -28,7 +28,7 @@
//
CPacketStreamFilter::CPacketStreamFilter(synergy::IStream* stream, bool adoptStream) :
CStreamFilter(*EVENTQUEUE, stream, adoptStream),
CStreamFilter(EVENTQUEUE, stream, adoptStream),
m_size(0),
m_inputShutdown(false)
{

View File

@@ -50,6 +50,7 @@ const char* kMsgDGameButtons = "DGBT%1i%2i";
const char* kMsgDGameSticks = "DGST%1i%2i%2i%2i%2i";
const char* kMsgDGameTriggers = "DGTR%1i%1i%1i";
const char* kMsgDGameFeedback = "DGFB%1i%2i%2i";
const char* kMsgDCryptoIv = "DCIV%s";
const char* kMsgQInfo = "QINF";
const char* kMsgEIncompatible = "EICV%2i%2i";
const char* kMsgEBusy = "EBSY";

View File

@@ -283,6 +283,11 @@ extern const char* kMsgDInfo;
// pairs.
extern const char* kMsgDSetOptions;
// crypto iv: primary -> secondary
// sends a new iv (initialization vector) to the client for the
// cryptography stream.
extern const char* kMsgDCryptoIv;
//
// query codes
//