From 33ebe61ef21d13fea7a6c6c9858ad2303d595540 Mon Sep 17 00:00:00 2001 From: "Jerry (Xinyu Hou)" Date: Fri, 14 Oct 2016 12:43:01 +0100 Subject: [PATCH 1/7] #5657 Counted expiring within 1 day as 1 day left --- src/lib/shared/SerialKey.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib/shared/SerialKey.cpp b/src/lib/shared/SerialKey.cpp index 54a45f86..38ca8725 100644 --- a/src/lib/shared/SerialKey.cpp +++ b/src/lib/shared/SerialKey.cpp @@ -101,13 +101,16 @@ unsigned long long SerialKey::dayLeft(unsigned long long currentTime) const { unsigned long long timeLeft = 0; + unsigned long long day = 60 * 60 * 24; + if (m_expireTime > currentTime) { timeLeft = m_expireTime - currentTime; } - unsigned long long day = 60 * 60 * 24; + unsigned long long dayLeft = 0; + dayLeft = timeLeft % day != 0 ? 1 : 0; - return timeLeft / day; + return timeLeft / day + dayLeft; } std::string From dce4b382e676ff5df2810d57b79bb968f3f67e32 Mon Sep 17 00:00:00 2001 From: "Jerry (Xinyu Hou)" Date: Fri, 14 Oct 2016 12:43:33 +0100 Subject: [PATCH 2/7] #5657 Fixed passing in the raw serial key --- src/lib/shared/SerialKey.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/shared/SerialKey.cpp b/src/lib/shared/SerialKey.cpp index 38ca8725..23d92b2e 100644 --- a/src/lib/shared/SerialKey.cpp +++ b/src/lib/shared/SerialKey.cpp @@ -34,7 +34,7 @@ SerialKey::SerialKey(std::string serial) : { string plainText = decode(serial); if (!plainText.empty()) { - parse(serial); + parse(plainText); } } From 1e5dfd3cb5f267874520289591a36b068846e0e3 Mon Sep 17 00:00:00 2001 From: "Jerry (Xinyu Hou)" Date: Fri, 14 Oct 2016 12:43:58 +0100 Subject: [PATCH 3/7] #5657 Added more unit tests for member functions in SerialKey --- src/test/unittests/shared/SerialKeyTests.cpp | 121 +++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/src/test/unittests/shared/SerialKeyTests.cpp b/src/test/unittests/shared/SerialKeyTests.cpp index 59199435..40fb479a 100644 --- a/src/test/unittests/shared/SerialKeyTests.cpp +++ b/src/test/unittests/shared/SerialKeyTests.cpp @@ -78,3 +78,124 @@ TEST(SerialKeyTests, parse_validV2Serial_valid) EXPECT_EQ(true, serial.isExpiring(1)); EXPECT_EQ(true, serial.isTrial()); } + +TEST(SerialKeyTests, isValid_validV1BasicSerial_valid) +{ + // {v1;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76313B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isValid(0)); + EXPECT_EQ(kBasic, serial.edition()); +} + +TEST(SerialKeyTests, isValid_expiredV1ProSerial_valid) +{ + // {v1;pro;Bob;1;email;company name;0;86400} + SerialKey serial("7B76313B70726F3B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isValid(0)); + EXPECT_EQ(kPro, serial.edition()); +} + +TEST(SerialKeyTests, isValid_validV2LifetimeBasicSerial_valid) +{ + // {v2;lifetime;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B6C69666574696D653B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isValid(0)); + EXPECT_EQ(kBasic, serial.edition()); +} + +TEST(SerialKeyTests, isValid_validV2LifetimeProSerial_valid) +{ + // {v2;lifetime;pro;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B6C69666574696D653B70726F3B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isValid(0)); + EXPECT_EQ(kPro, serial.edition()); +} + +TEST(SerialKeyTests, isValid_validV2TrialBasicSerial_valid) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isValid(0)); + EXPECT_EQ(kBasic, serial.edition()); + +} + +TEST(SerialKeyTests, isValid_expiredV2TrialProSerial_invalid) +{ + // {v2;trial;pro;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B70726F3B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isValid(86401)); + EXPECT_EQ(kPro, serial.edition()); +} + +TEST(SerialKeyTests, isExpiring_validV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpiring(0)); + EXPECT_EQ(kBasic, serial.edition()); +} + +TEST(SerialKeyTests, isExpiring_expiringV2TrialBasicSerial_returnTrue) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isExpiring(1)); +} + +TEST(SerialKeyTests, isExpiring_expiredV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpiring(86401)); +} + +TEST(SerialKeyTests, isExpired_validV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpired(0)); +} + +TEST(SerialKeyTests, isExpired_expiringV2TrialBasicSerial_returnFalse) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_FALSE(serial.isExpired(1)); +} + +TEST(SerialKeyTests, isExpired_expiredV2TrialBasicSerial_returnTrue) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(true, serial.isTrial()); + EXPECT_EQ(true, serial.isExpired(86401)); +} + +TEST(SerialKeyTests, dayLeft_validExactlyOneDayV2TrialBasicSerial_returnOne) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(1, serial.dayLeft(0)); +} + +TEST(SerialKeyTests, dayLeft_validWithinOneDayV2TrialBasicSerial_returnOne) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(1, serial.dayLeft(1)); +} + +TEST(SerialKeyTests, dayLeft_expiredV2TrialBasicSerial_returnZero) +{ + // {v2;trial;basic;Bob;1;email;company name;0;86400} + SerialKey serial("7B76323B747269616C3B62617369633B426F623B313B656D61696C3B636F6D70616E79206E616D653B303B38363430307D"); + EXPECT_EQ(0, serial.dayLeft(86401)); +} From 92b29276d0ab586c03c94b57733419028c035098 Mon Sep 17 00:00:00 2001 From: "Jerry (Xinyu Hou)" Date: Fri, 14 Oct 2016 13:51:27 +0100 Subject: [PATCH 4/7] #5657 Added serial argument in core --- src/lib/synergy/ArgParser.cpp | 3 +++ src/lib/synergy/ServerArgs.cpp | 1 + src/lib/synergy/ServerArgs.h | 1 + 3 files changed, 5 insertions(+) diff --git a/src/lib/synergy/ArgParser.cpp b/src/lib/synergy/ArgParser.cpp index 11adc2d5..d16a6fa9 100644 --- a/src/lib/synergy/ArgParser.cpp +++ b/src/lib/synergy/ArgParser.cpp @@ -70,6 +70,9 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv) else if (isArg(i, argc, argv, "", "--prm-hc", 1)) { DpiHelper::s_primaryHeightCenter = synergy::string::stringToSizeType(argv[++i]); } + else if (isArg(i, argc, argv, "", "--serial-key", 1)) { + args.m_serial = argv[++i]; + } else { LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname)); return false; diff --git a/src/lib/synergy/ServerArgs.cpp b/src/lib/synergy/ServerArgs.cpp index f56f6e8d..52166f2a 100644 --- a/src/lib/synergy/ServerArgs.cpp +++ b/src/lib/synergy/ServerArgs.cpp @@ -19,6 +19,7 @@ ServerArgs::ServerArgs() : m_configFile(), + m_serial(), m_config(NULL) { } diff --git a/src/lib/synergy/ServerArgs.h b/src/lib/synergy/ServerArgs.h index 54310f8e..7c69fae6 100644 --- a/src/lib/synergy/ServerArgs.h +++ b/src/lib/synergy/ServerArgs.h @@ -28,5 +28,6 @@ public: public: String m_configFile; + String m_serial; Config* m_config; }; From 2b1b0640eac3aa5f9a20b4aa1a98be72cb759937 Mon Sep 17 00:00:00 2001 From: "Jerry (Xinyu Hou)" Date: Fri, 14 Oct 2016 13:51:46 +0100 Subject: [PATCH 5/7] #5657 Added serial argument parsing unit test --- .../unittests/synergy/ServerArgsParsingTests.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/unittests/synergy/ServerArgsParsingTests.cpp b/src/test/unittests/synergy/ServerArgsParsingTests.cpp index 5ae18b94..92db8c0d 100644 --- a/src/test/unittests/synergy/ServerArgsParsingTests.cpp +++ b/src/test/unittests/synergy/ServerArgsParsingTests.cpp @@ -64,3 +64,17 @@ TEST(ServerArgsParsingTests, parseServerArgs_configArg_setConfigFile) EXPECT_EQ("mock_configFile", serverArgs.m_configFile); } + +TEST(ServerArgsParsingTests, parseServerArgs_serialArg_setSerial) +{ + NiceMock argParser; + ON_CALL(argParser, parseGenericArgs(_, _, _)).WillByDefault(Invoke(server_stubParseGenericArgs)); + ON_CALL(argParser, checkUnexpectedArgs()).WillByDefault(Invoke(server_stubCheckUnexpectedArgs)); + ServerArgs serverArgs; + const int argc = 3; + const char* kSerialCmd[argc] = { "stub", "--serial-key", "mock_serial" }; + + argParser.parseServerArgs(serverArgs, argc, kSerialCmd); + + EXPECT_EQ("mock_serial", serverArgs.m_serial); +} From 89851fddc32b181129e0db229c117302890ba9c8 Mon Sep 17 00:00:00 2001 From: "Jerry (Xinyu Hou)" Date: Fri, 14 Oct 2016 17:14:21 +0100 Subject: [PATCH 6/7] #5657 Exited server if trial is expired --- src/lib/server/CMakeLists.txt | 2 ++ src/lib/server/Server.cpp | 27 ++++++++++++++++++++------- src/lib/server/Server.h | 5 +++-- src/lib/synergy/ServerApp.cpp | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/lib/server/CMakeLists.txt b/src/lib/server/CMakeLists.txt index 2c34af07..3cb582ec 100644 --- a/src/lib/server/CMakeLists.txt +++ b/src/lib/server/CMakeLists.txt @@ -35,6 +35,8 @@ endif() add_library(server STATIC ${sources}) +target_link_libraries(server shared) + if (UNIX) target_link_libraries(server synergy) endif() diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index d9394ed5..a202648e 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -45,11 +45,13 @@ #include "base/Log.h" #include "base/TMethodEventJob.h" #include "common/stdexcept.h" +#include "shared/SerialKey.h" #include #include #include #include +#include // // Server @@ -60,7 +62,7 @@ Server::Server( PrimaryClient* primaryClient, synergy::Screen* screen, IEventQueue* events, - bool enableDragDrop) : + ServerArgs const& args) : m_mock(false), m_primaryClient(primaryClient), m_active(primaryClient), @@ -91,10 +93,10 @@ Server::Server( m_sendFileThread(NULL), m_writeToDropDirThread(NULL), m_ignoreFileTransfer(false), - m_enableDragDrop(enableDragDrop), m_enableClipboard(true), m_sendDragInfoThread(NULL), - m_waitDragInfoThread(true) + m_waitDragInfoThread(true), + m_args(args) { // must have a primary client and it must have a canonical name assert(m_primaryClient != NULL); @@ -184,7 +186,7 @@ Server::Server( new TMethodEventJob(this, &Server::handleFakeInputEndEvent)); - if (m_enableDragDrop) { + if (m_args.m_enableDragDrop) { m_events->adoptHandler(m_events->forFile().fileChunkSending(), this, new TMethodEventJob(this, @@ -451,6 +453,17 @@ Server::switchScreen(BaseClientProxy* dst, SInt32 x, SInt32 y, bool forScreensaver) { assert(dst != NULL); + + // if trial is expired, exit the process + if (!m_args.m_serial.empty()) { + SerialKey serial(m_args.m_serial); + if (!serial.isValid(std::time(0))) { + LOG((CLOG_ERR "trial is expired, aborting server")); + exit(kExitSuccess); + return; + } + } + #ifndef NDEBUG { SInt32 dx, dy, dw, dh; @@ -1706,7 +1719,7 @@ Server::onMouseUp(ButtonID id) return; } - if (m_enableDragDrop) { + if (m_args.m_enableDragDrop) { if (!m_screen->isOnScreen()) { String& file = m_screen->getDraggingFilename(); if (!file.empty()) { @@ -1791,7 +1804,7 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y) // should we switch or not? if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) { - if (m_enableDragDrop + if (m_args.m_enableDragDrop && m_screen->isDraggingStarted() && m_active != newScreen && m_waitDragInfoThread) { @@ -2393,7 +2406,7 @@ Server::sendFileThread(void* data) void Server::dragInfoReceived(UInt32 fileNum, String content) { - if (!m_enableDragDrop) { + if (!m_args.m_enableDragDrop) { LOG((CLOG_DEBUG "drag drop not enabled, ignoring drag info.")); return; } diff --git a/src/lib/server/Server.h b/src/lib/server/Server.h index 7681487a..d1e48bd5 100644 --- a/src/lib/server/Server.h +++ b/src/lib/server/Server.h @@ -25,6 +25,7 @@ #include "synergy/mouse_types.h" #include "synergy/INode.h" #include "synergy/DragInformation.h" +#include "synergy/ServerArgs.h" #include "base/Event.h" #include "base/Stopwatch.h" #include "base/EventTypes.h" @@ -106,7 +107,7 @@ public: ownership of \p primaryClient. */ Server(Config& config, PrimaryClient* primaryClient, - synergy::Screen* screen, IEventQueue* events, bool enableDragDrop); + synergy::Screen* screen, IEventQueue* events, ServerArgs const& args); ~Server(); #ifdef TEST_ENV @@ -472,11 +473,11 @@ private: Thread* m_writeToDropDirThread; String m_dragFileExt; bool m_ignoreFileTransfer; - bool m_enableDragDrop; bool m_enableClipboard; Thread* m_sendDragInfoThread; bool m_waitDragInfoThread; ClientListener* m_clientListener; + ServerArgs m_args; }; diff --git a/src/lib/synergy/ServerApp.cpp b/src/lib/synergy/ServerApp.cpp index 23884aec..ae1a2077 100644 --- a/src/lib/synergy/ServerApp.cpp +++ b/src/lib/synergy/ServerApp.cpp @@ -647,7 +647,7 @@ ServerApp::openClientListener(const NetworkAddress& address) Server* ServerApp::openServer(Config& config, PrimaryClient* primaryClient) { - Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args().m_enableDragDrop); + Server* server = new Server(config, primaryClient, m_serverScreen, m_events, args()); try { m_events->adoptHandler( m_events->forServer().disconnected(), server, From dc31f395cc87c06eef3e6313a9c449e7a9b566ad Mon Sep 17 00:00:00 2001 From: XinyuHou Date: Fri, 14 Oct 2016 09:44:02 -0700 Subject: [PATCH 7/7] #5657 Fixed integtests using the old server constructor --- src/test/integtests/net/NetworkTests.cpp | 48 ++++++++++++++---------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/test/integtests/net/NetworkTests.cpp b/src/test/integtests/net/NetworkTests.cpp index 79ef7c99..dbb3dd1e 100644 --- a/src/test/integtests/net/NetworkTests.cpp +++ b/src/test/integtests/net/NetworkTests.cpp @@ -129,7 +129,9 @@ TEST_F(NetworkTests, sendToClient_mockData) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -142,10 +144,10 @@ TEST_F(NetworkTests, sendToClient_mockData) ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forFile().fileRecieveCompleted(), &client, @@ -185,7 +187,9 @@ TEST_F(NetworkTests, sendToClient_mockFile) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -198,10 +202,10 @@ TEST_F(NetworkTests, sendToClient_mockFile) ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forFile().fileRecieveCompleted(), &client, @@ -235,7 +239,9 @@ TEST_F(NetworkTests, sendToServer_mockData) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -247,10 +253,10 @@ TEST_F(NetworkTests, sendToServer_mockData) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forClientListener().connected(), &listener, @@ -290,7 +296,9 @@ TEST_F(NetworkTests, sendToServer_mockFile) ON_CALL(serverConfig, isScreen(_)).WillByDefault(Return(true)); ON_CALL(serverConfig, getInputFilter()).WillByDefault(Return(&serverInputFilter)); - Server server(serverConfig, &primaryClient, &serverScreen, &m_events, true); + ServerArgs serverArgs; + serverArgs.m_enableDragDrop = true; + Server server(serverConfig, &primaryClient, &serverScreen, &m_events, serverArgs); server.m_mock = true; listener.setServer(&server); @@ -302,10 +310,10 @@ TEST_F(NetworkTests, sendToServer_mockFile) ON_CALL(clientScreen, getShape(_, _, _, _)).WillByDefault(Invoke(getScreenShape)); ON_CALL(clientScreen, getCursorPos(_, _)).WillByDefault(Invoke(getCursorPos)); - ClientArgs args; - args.m_enableDragDrop = true; - args.m_enableCrypto = false; - Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, args); + ClientArgs clientArgs; + clientArgs.m_enableDragDrop = true; + clientArgs.m_enableCrypto = false; + Client client(&m_events, "stub", serverAddress, clientSocketFactory, &clientScreen, clientArgs); m_events.adoptHandler( m_events.forClientListener().connected(), &listener,