diff --git a/ChangeLog b/ChangeLog index 79f173024..a6cb0573f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +1.14.7 +====== + +Enhancements: +- #7254 Ability to bind synergy client to a network interface. + 1.14.6 ====== diff --git a/cmake/Version.cmake b/cmake/Version.cmake index e64b29de4..1753e9e03 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -6,7 +6,7 @@ cmake_minimum_required (VERSION 3.4) set (SYNERGY_VERSION_MAJOR 1) set (SYNERGY_VERSION_MINOR 14) -set (SYNERGY_VERSION_PATCH 6) +set (SYNERGY_VERSION_PATCH 7) set (SYNERGY_VERSION_BUILD 1) set (SYNERGY_VERSION_STAGE "snapshot") diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index c84fdafef..7201a0024 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -158,6 +158,8 @@ Client::connect(size_t addressIndex) // create the socket IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork, ARCH->getAddrFamily(m_serverAddress.getAddress())); + bindNetworkInterface(socket); + // filter socket messages, including a packetizing filter m_stream = new PacketStreamFilter(m_events, socket, true); @@ -836,6 +838,24 @@ Client::onFileRecieveCompleted() } } +void Client::bindNetworkInterface(IDataSocket *socket) const +{ + try { + if (!m_args.m_synergyAddress.empty()) { + LOG((CLOG_DEBUG1 "bind to network interface: %s", m_args.m_synergyAddress.c_str())); + + NetworkAddress bindAddress(m_args.m_synergyAddress); + bindAddress.resolve(); + + socket->bind(bindAddress); + } + } + catch(XBase& e) { + LOG((CLOG_WARN "%s", e.what())); + LOG((CLOG_WARN "operating system will select network interface automatically")); + } +} + void Client::handleStopRetry(const Event&, void*) { diff --git a/src/lib/client/Client.h b/src/lib/client/Client.h index 3994e7543..7c5f14147 100644 --- a/src/lib/client/Client.h +++ b/src/lib/client/Client.h @@ -210,6 +210,7 @@ private: void handleStopRetry(const Event&, void*); void onFileRecieveCompleted(); void sendClipboardThread(void*); + void bindNetworkInterface(IDataSocket* socket) const; public: bool m_mock; diff --git a/src/lib/net/NetworkAddress.cpp b/src/lib/net/NetworkAddress.cpp index 687668d7d..ca44be813 100644 --- a/src/lib/net/NetworkAddress.cpp +++ b/src/lib/net/NetworkAddress.cpp @@ -238,7 +238,7 @@ void NetworkAddress::checkPort() { // check port number - if (m_port <= 0 || m_port > 65535) { + if (m_port < 0 || m_port > 65535) { throw XSocketAddress(XSocketAddress::kBadPort, m_hostname, m_port); } } diff --git a/src/lib/net/NetworkAddress.h b/src/lib/net/NetworkAddress.h index 317775ea0..129d883ee 100644 --- a/src/lib/net/NetworkAddress.h +++ b/src/lib/net/NetworkAddress.h @@ -49,7 +49,7 @@ public: is thrown with an error of \c XSocketAddress::kBadPort. The hostname is not resolved by the c'tor; use \c resolve to do that. */ - NetworkAddress(const String& hostname, int port); + NetworkAddress(const String& hostname, int port = 0); NetworkAddress(const NetworkAddress&); diff --git a/src/lib/synergy/ArgParser.cpp b/src/lib/synergy/ArgParser.cpp index a9bf1055d..d8e6abd49 100644 --- a/src/lib/synergy/ArgParser.cpp +++ b/src/lib/synergy/ArgParser.cpp @@ -56,10 +56,6 @@ ArgParser::parseServerArgs(lib::synergy::ServerArgs& args, int argc, const char* ++i; continue; } - else if (isArg(i, argc, argv, "-a", "--address", 1)) { - // save listen address - args.m_synergyAddress = argv[++i]; - } else if (isArg(i, argc, argv, "-c", "--config", 1)) { // save configuration file path args.m_configFile = argv[++i]; @@ -130,7 +126,7 @@ ArgParser::parseClientArgs(lib::synergy::ClientArgs& args, int argc, const char* } else { if (i + 1 == argc) { - args.m_synergyAddress = argv[i]; + args.m_serverAddress = argv[i]; return true; } @@ -223,7 +219,10 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv) bool ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i) { - if (isArg(i, argc, argv, "-d", "--debug", 1)) { + if (isArg(i, argc, argv, "-a", "--address", 1)) { + argsBase().m_synergyAddress = argv[++i]; + } + else if (isArg(i, argc, argv, "-d", "--debug", 1)) { // change logging level argsBase().m_logFilter = argv[++i]; } diff --git a/src/lib/synergy/ArgsBase.h b/src/lib/synergy/ArgsBase.h index dba7a7651..cb8a99ca0 100644 --- a/src/lib/synergy/ArgsBase.h +++ b/src/lib/synergy/ArgsBase.h @@ -52,7 +52,7 @@ namespace lib { bool m_enableDragDrop = false; /// @brief Should drag drop support be enabled bool m_shouldExit = false; /// @brief Will cause the application to exit when set to true - String m_synergyAddress; /// @brief Bind to this address //TODO This really should be a ServerArgs + String m_synergyAddress; /// @brief Bind to this address bool m_enableCrypto = false; /// @brief Should the connections be TLS encrypted String m_profileDirectory; /// @brief The profile DIR to use for the application String m_pluginDirectory; /// @brief //TODO Plugins? Get set in ARCH but doesn't seem to get used diff --git a/src/lib/synergy/ClientApp.cpp b/src/lib/synergy/ClientApp.cpp index 7ca723d7f..fd57824d0 100644 --- a/src/lib/synergy/ClientApp.cpp +++ b/src/lib/synergy/ClientApp.cpp @@ -59,7 +59,7 @@ #endif #include -#include +#include #include #define RETRY_TIME 1.0 @@ -87,9 +87,9 @@ ClientApp::parseArgs(int argc, const char* const* argv) } else { // save server address - if (!args().m_synergyAddress.empty()) { + if (!args().m_serverAddress.empty()) { try { - *m_serverAddress = NetworkAddress(args().m_synergyAddress, kDefaultPort); + *m_serverAddress = NetworkAddress(args().m_serverAddress, kDefaultPort); m_serverAddress->resolve(); } catch (XSocketAddress& e) { @@ -117,45 +117,41 @@ ClientApp::help() " --display connect to the X server at \n" \ " --no-xinitthreads do not call XInitThreads()\n" #else -# define WINAPI_ARG -# define WINAPI_INFO +# define WINAPI_ARG "" +# define WINAPI_INFO "" #endif - static const int buffer_size = 2000; - char buffer[buffer_size]; - snprintf( - buffer, - buffer_size, - "Usage: %s" - " [--yscroll ]" - " [--sync-language]" - " [--invert-scroll]" - " [--host]" - WINAPI_ARG - HELP_SYS_ARGS - HELP_COMMON_ARGS - " " - "\n\n" - "Connect to a synergy mouse/keyboard sharing server.\n" - "\n" - HELP_COMMON_INFO_1 - WINAPI_INFO - HELP_SYS_INFO - " --yscroll defines the vertical scrolling delta, which is\n" - " 120 by default.\n" - " --sync-language set this parameter to enable language synchronization.\n" - " --invert-scroll invert scroll direction on this computer.\n" - " --host client starts a listener and waits for a server connection.\n" - HELP_COMMON_INFO_2 - "\n" - "* marks defaults.\n" - "\n" - "The server address is of the form: [][:]. The hostname\n" - "must be the address or hostname of the server. The port overrides the\n" - "default port, %d.\n", - args().m_pname, kDefaultPort - ); + std::stringstream help; + help<< "Usage: " << args().m_pname + <<" [--address
]" + <<" [--yscroll ]" + <<" [--sync-language]" + <<" [--invert-scroll]" + <<" [--host]" + <" + <<"\n\n" + <<"Connect to a synergy mouse/keyboard sharing server.\n" + <<"\n" + <<" -a, --address
local network interface address.\n" + < defines the vertical scrolling delta, which is\n" + <<" 120 by default.\n" + <<" --sync-language set this parameter to enable language synchronization.\n" + <<" --invert-scroll invert scroll direction on this computer.\n" + <<" --host client starts a listener and waits for a server connection.\n" + <][:]. The hostname\n" + <<"must be the address or hostname of the server. The port overrides the\n" + <<"default port, " << kDefaultPort <<".\n"; - LOG((CLOG_PRINT "%s", buffer)); + LOG((CLOG_PRINT "%s", help.str().c_str())); } const char* diff --git a/src/lib/synergy/ClientArgs.h b/src/lib/synergy/ClientArgs.h index f2f2976ff..3d59be399 100644 --- a/src/lib/synergy/ClientArgs.h +++ b/src/lib/synergy/ClientArgs.h @@ -52,6 +52,11 @@ namespace lib { */ bool m_hostMode = false; + /** + * @brief m_serverAddress stores synergy server address + */ + std::string m_serverAddress; + }; } } diff --git a/src/test/unittests/synergy/ClientArgsParsingTests.cpp b/src/test/unittests/synergy/ClientArgsParsingTests.cpp index 9c9a725fc..f16e090e0 100644 --- a/src/test/unittests/synergy/ClientArgsParsingTests.cpp +++ b/src/test/unittests/synergy/ClientArgsParsingTests.cpp @@ -111,7 +111,7 @@ TEST(ClientArgsParsingTests, parseClientArgs_addressArg_setSynergyAddress) bool result = argParser.parseClientArgs(clientArgs, argc, kAddressCmd); - EXPECT_EQ("mock_address", clientArgs.m_synergyAddress); + EXPECT_EQ("mock_address", clientArgs.m_serverAddress); EXPECT_EQ(true, result); }