diff options
author | Tobias Markmann <tm@ayena.de> | 2016-11-08 14:29:17 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2016-11-18 08:49:39 (GMT) |
commit | 43479ef719ea8fc6abbf654730b47c4583140508 (patch) | |
tree | c0a05a837b8988c0875fedb6161c08f3dcb2ffb0 | |
parent | c82f95fd431e702137d5f2e3dda4cf0ae424e837 (diff) | |
download | swift-43479ef719ea8fc6abbf654730b47c4583140508.zip swift-43479ef719ea8fc6abbf654730b47c4583140508.tar.bz2 |
Improve string to HostAddress conversion API
Previously HostAddress had a constructor which allowed
initialisation via a std::string. This initialisation can
fail and this is heavily used for checking whether a string
is a valid IP address.
This constructor is removed in this commit and replaced by
a static method HostAddress::fromString, taking a string and
returning an optional HostAddress. This clearly communicates
that the conversion can fail.
Test-Information:
./scons test=all passes on macOS 10.12.1.
Change-Id: Idaafee6f84010ce541c55f267ac77ad6ac8f02b4
27 files changed, 150 insertions, 124 deletions
diff --git a/Swiften/Component/UnitTest/ComponentConnectorTest.cpp b/Swiften/Component/UnitTest/ComponentConnectorTest.cpp index 3515a0a..3b4fa83 100644 --- a/Swiften/Component/UnitTest/ComponentConnectorTest.cpp +++ b/Swiften/Component/UnitTest/ComponentConnectorTest.cpp @@ -6,62 +6,62 @@ #include <boost/bind.hpp> #include <boost/optional.hpp> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/Component/ComponentConnector.h> #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/Network/Connection.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/StaticDomainNameResolver.h> using namespace Swift; class ComponentConnectorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ComponentConnectorTest); CPPUNIT_TEST(testConnect); CPPUNIT_TEST(testConnect_FirstAddressHostFails); CPPUNIT_TEST(testConnect_NoHosts); CPPUNIT_TEST(testConnect_TimeoutDuringResolve); CPPUNIT_TEST(testConnect_TimeoutDuringConnect); CPPUNIT_TEST(testConnect_NoTimeout); CPPUNIT_TEST(testStop_Timeout); CPPUNIT_TEST_SUITE_END(); public: void setUp() { - host1 = HostAddress("1.1.1.1"); - host2 = HostAddress("2.2.2.2"); + host1 = HostAddress::fromString("1.1.1.1").get(); + host2 = HostAddress::fromString("2.2.2.2").get(); eventLoop = new DummyEventLoop(); resolver = new StaticDomainNameResolver(eventLoop); connectionFactory = new MockConnectionFactory(eventLoop); timerFactory = new DummyTimerFactory(); } void tearDown() { delete timerFactory; delete connectionFactory; delete resolver; delete eventLoop; } void testConnect() { ComponentConnector::ref testling(createConnector("foo.com", 1234)); resolver->addAddress("foo.com", host1); testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(HostAddressPort(host1, 1234) == *(connections[0]->hostAddressPort)); } void testConnect_FirstAddressHostFails() { ComponentConnector::ref testling(createConnector("foo.com", 1234)); resolver->addAddress("foo.com", host1); resolver->addAddress("foo.com", host2); connectionFactory->failingPorts.push_back(HostAddressPort(host1, 1234)); diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp index 2975193..09b664f 100644 --- a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp @@ -1,51 +1,50 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2013-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> #include <memory> #include <vector> #include <boost/bind.hpp> #include <Swiften/Base/Log.h> -#include <Swiften/Base/foreach.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h> static const unsigned int LOCAL_PREFERENCE = 0; namespace Swift { LocalJingleTransportCandidateGenerator::LocalJingleTransportCandidateGenerator( SOCKS5BytestreamServerManager* s5bServerManager, SOCKS5BytestreamProxiesManager* s5bProxy, const JID& ownJID, IDGenerator* idGenerator, const FileTransferOptions& options) : s5bServerManager(s5bServerManager), s5bProxy(s5bProxy), ownJID(ownJID), idGenerator(idGenerator), triedServerInit_(false), triedForwarding_(false), triedProxyDiscovery_(false), options_(options) { } LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator() { SWIFT_LOG_ASSERT(!s5bServerInitializeRequest, warning) << std::endl; } @@ -113,79 +112,80 @@ void LocalJingleTransportCandidateGenerator::handlePortForwardingSetup(bool /* s if (s5bServerPortForwardingUser_) { s5bServerPortForwardingUser_->onSetup.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handlePortForwardingSetup, this, _1)); } triedForwarding_ = true; checkS5BCandidatesReady(); } void LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged() { if (s5bProxy) { s5bProxy->onDiscoveredProxiesChanged.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this)); } triedProxyDiscovery_ = true; checkS5BCandidatesReady(); } void LocalJingleTransportCandidateGenerator::checkS5BCandidatesReady() { if ((!options_.isDirectAllowed() || (options_.isDirectAllowed() && triedServerInit_)) && (!options_.isProxiedAllowed() || (options_.isProxiedAllowed() && triedProxyDiscovery_)) && (!options_.isAssistedAllowed() || (options_.isAssistedAllowed() && triedForwarding_))) { emitOnLocalTransportCandidatesGenerated(); } } void LocalJingleTransportCandidateGenerator::emitOnLocalTransportCandidatesGenerated() { std::vector<JingleS5BTransportPayload::Candidate> candidates; if (options_.isDirectAllowed()) { // get direct candidates std::vector<HostAddressPort> directCandidates = s5bServerManager->getHostAddressPorts(); - foreach(HostAddressPort addressPort, directCandidates) { + for(auto&& addressPort : directCandidates) { if (addressPort.getAddress().getRawAddress().is_v6() && addressPort.getAddress().getRawAddress().to_v6().is_link_local()) { continue; } JingleS5BTransportPayload::Candidate candidate; candidate.type = JingleS5BTransportPayload::Candidate::DirectType; candidate.jid = ownJID; candidate.hostPort = addressPort; candidate.priority = 65536 * 126 + LOCAL_PREFERENCE; candidate.cid = idGenerator->generateID(); candidates.push_back(candidate); } } if (options_.isAssistedAllowed()) { // get assissted candidates std::vector<HostAddressPort> assisstedCandidates = s5bServerManager->getAssistedHostAddressPorts(); - foreach(HostAddressPort addressPort, assisstedCandidates) { + for (auto&& addressPort : assisstedCandidates) { JingleS5BTransportPayload::Candidate candidate; candidate.type = JingleS5BTransportPayload::Candidate::AssistedType; candidate.jid = ownJID; candidate.hostPort = addressPort; candidate.priority = 65536 * 120 + LOCAL_PREFERENCE; candidate.cid = idGenerator->generateID(); candidates.push_back(candidate); } } if (options_.isProxiedAllowed() && s5bProxy->getOrDiscoverS5BProxies().is_initialized()) { - foreach(S5BProxyRequest::ref proxy, s5bProxy->getOrDiscoverS5BProxies().get()) { + for (auto&& proxy : s5bProxy->getOrDiscoverS5BProxies().get()) { if (proxy->getStreamHost()) { // FIXME: Added this test, because there were cases where this wasn't initialized. Investigate this. (Remko) JingleS5BTransportPayload::Candidate candidate; candidate.type = JingleS5BTransportPayload::Candidate::ProxyType; candidate.jid = (*proxy->getStreamHost()).jid; - HostAddress address = (*proxy->getStreamHost()).host; - assert(address.isValid()); - candidate.hostPort = HostAddressPort(address, (*proxy->getStreamHost()).port); - candidate.priority = 65536 * 10 + LOCAL_PREFERENCE; - candidate.cid = idGenerator->generateID(); - candidates.push_back(candidate); + auto address = HostAddress::fromString((*proxy->getStreamHost()).host); + if (address) { + candidate.hostPort = HostAddressPort(address.get(), (*proxy->getStreamHost()).port); + candidate.priority = 65536 * 10 + LOCAL_PREFERENCE; + candidate.cid = idGenerator->generateID(); + candidates.push_back(candidate); + } } } } onLocalTransportCandidatesGenerated(candidates); } } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp index 367676b..cd4cfaa 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp @@ -1,179 +1,181 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2015-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h> #include <memory> #include <boost/bind.hpp> #include <Swiften/Base/Log.h> -#include <Swiften/Base/foreach.h> #include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/DomainNameAddressQuery.h> #include <Swiften/Network/DomainNameResolveError.h> #include <Swiften/Network/DomainNameResolver.h> #include <Swiften/Network/TimerFactory.h> namespace Swift { SOCKS5BytestreamProxiesManager::SOCKS5BytestreamProxiesManager(ConnectionFactory *connFactory, TimerFactory *timeFactory, DomainNameResolver* resolver, IQRouter* iqRouter, const JID& serviceRoot) : connectionFactory_(connFactory), timerFactory_(timeFactory), resolver_(resolver), iqRouter_(iqRouter), serviceRoot_(serviceRoot) { } SOCKS5BytestreamProxiesManager::~SOCKS5BytestreamProxiesManager() { if (proxyFinder_) { proxyFinder_->stop(); } - foreach (const ProxySessionsMap::value_type& sessionsForID, proxySessions_) { - foreach (const ProxyJIDClientSessionVector::value_type& session, sessionsForID.second) { + for (const auto& sessionsForID : proxySessions_) { + for (const auto& session : sessionsForID.second) { session.second->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionsForID.first, session.first, session.second, _1)); session.second->onFinished.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionsForID.first, session.first, session.second, _1)); } } } void SOCKS5BytestreamProxiesManager::addS5BProxy(S5BProxyRequest::ref proxy) { if (proxy) { - SWIFT_LOG_ASSERT(HostAddress(proxy->getStreamHost().get().host).isValid(), warning) << std::endl; + SWIFT_LOG_ASSERT(HostAddress::fromString(proxy->getStreamHost().get().host), warning) << std::endl; if (!localS5BProxies_) { localS5BProxies_ = std::vector<S5BProxyRequest::ref>(); } localS5BProxies_->push_back(proxy); } } const boost::optional<std::vector<S5BProxyRequest::ref> >& SOCKS5BytestreamProxiesManager::getOrDiscoverS5BProxies() { if (!localS5BProxies_ && !proxyFinder_) { queryForProxies(); } return localS5BProxies_; } void SOCKS5BytestreamProxiesManager::connectToProxies(const std::string& sessionID) { SWIFT_LOG(debug) << "session ID: " << sessionID << std::endl; ProxyJIDClientSessionVector clientSessions; if (localS5BProxies_) { - foreach(S5BProxyRequest::ref proxy, localS5BProxies_.get()) { - std::shared_ptr<Connection> conn = connectionFactory_->createConnection(); - - HostAddressPort addressPort = HostAddressPort(proxy->getStreamHost().get().host, proxy->getStreamHost().get().port); - SWIFT_LOG_ASSERT(addressPort.isValid(), warning) << std::endl; - std::shared_ptr<SOCKS5BytestreamClientSession> session = std::make_shared<SOCKS5BytestreamClientSession>(conn, addressPort, sessionID, timerFactory_); - JID proxyJid = proxy->getStreamHost().get().jid; - clientSessions.push_back(std::pair<JID, std::shared_ptr<SOCKS5BytestreamClientSession> >(proxyJid, session)); - session->onSessionReady.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionID, proxyJid, session, _1)); - session->onFinished.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionID, proxyJid, session, _1)); - session->start(); + for (auto&& proxy : localS5BProxies_.get()) { + auto proxyHostAddress = HostAddress::fromString(proxy->getStreamHost().get().host); + if (proxyHostAddress) { + std::shared_ptr<Connection> conn = connectionFactory_->createConnection(); + HostAddressPort addressPort = HostAddressPort(proxyHostAddress.get(), proxy->getStreamHost().get().port); + SWIFT_LOG_ASSERT(addressPort.isValid(), warning) << std::endl; + std::shared_ptr<SOCKS5BytestreamClientSession> session = std::make_shared<SOCKS5BytestreamClientSession>(conn, addressPort, sessionID, timerFactory_); + JID proxyJid = proxy->getStreamHost().get().jid; + clientSessions.push_back(std::pair<JID, std::shared_ptr<SOCKS5BytestreamClientSession> >(proxyJid, session)); + session->onSessionReady.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionID, proxyJid, session, _1)); + session->onFinished.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionID, proxyJid, session, _1)); + session->start(); + } } } proxySessions_[sessionID] = clientSessions; } std::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID) { // checking parameters if (proxySessions_.find(sessionID) == proxySessions_.end()) { return std::shared_ptr<SOCKS5BytestreamClientSession>(); } // get active session std::shared_ptr<SOCKS5BytestreamClientSession> activeSession; for (ProxyJIDClientSessionVector::iterator i = proxySessions_[sessionID].begin(); i != proxySessions_[sessionID].end(); i++) { i->second->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionID, proxyJID, i->second, _1)); i->second->onFinished.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionID, proxyJID, i->second, _1)); if (i->first == proxyJID && !activeSession) { activeSession = i->second; } else { i->second->stop(); } } SWIFT_LOG_ASSERT(activeSession, warning) << "No active session with matching ID found." << std::endl; proxySessions_.erase(sessionID); return activeSession; } std::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr) { SOCKS5BytestreamClientSession::ref connection = std::make_shared<SOCKS5BytestreamClientSession>(connectionFactory_->createConnection(), addressPort, destAddr, timerFactory_); return connection; } void SOCKS5BytestreamProxiesManager::handleProxiesFound(std::vector<S5BProxyRequest::ref> proxyHosts) { proxyFinder_->onProxiesFound.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxiesFound, this, _1)); - foreach(S5BProxyRequest::ref proxy, proxyHosts) { + for (auto&& proxy : proxyHosts) { if (proxy) { - if (HostAddress(proxy->getStreamHost().get().host).isValid()) { + auto proxyHostAddress = HostAddress::fromString(proxy->getStreamHost().get().host); + if (proxyHostAddress) { addS5BProxy(proxy); onDiscoveredProxiesChanged(); } else { DomainNameAddressQuery::ref resolveRequest = resolver_->createAddressQuery(proxy->getStreamHost().get().host); resolveRequest->onResult.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleNameLookupResult, this, _1, _2, proxy)); resolveRequest->run(); } } } proxyFinder_->stop(); proxyFinder_.reset(); if (proxyHosts.empty()) { onDiscoveredProxiesChanged(); } } void SOCKS5BytestreamProxiesManager::handleNameLookupResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> error, S5BProxyRequest::ref proxy) { if (error) { onDiscoveredProxiesChanged(); } else { if (addresses.empty()) { SWIFT_LOG(warning) << "S5B proxy hostname does not resolve." << std::endl; } else { // generate proxy per returned address - foreach (const HostAddress& address, addresses) { + for (const auto& address : addresses) { S5BProxyRequest::StreamHost streamHost = proxy->getStreamHost().get(); S5BProxyRequest::ref proxyForAddress = std::make_shared<S5BProxyRequest>(*proxy); streamHost.host = address.toString(); proxyForAddress->setStreamHost(streamHost); addS5BProxy(proxyForAddress); } } onDiscoveredProxiesChanged(); } } void SOCKS5BytestreamProxiesManager::queryForProxies() { proxyFinder_ = std::make_shared<SOCKS5BytestreamProxyFinder>(serviceRoot_, iqRouter_); proxyFinder_->onProxiesFound.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxiesFound, this, _1)); proxyFinder_->start(); } void SOCKS5BytestreamProxiesManager::handleProxySessionReady(const std::string& sessionID, const JID& jid, std::shared_ptr<SOCKS5BytestreamClientSession> session, bool error) { session->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this, boost::cref(sessionID), boost::cref(jid), session, _1)); if (!error) { // The SOCKS5 bytestream session to the proxy succeeded; stop and remove other sessions. if (proxySessions_.find(sessionID) != proxySessions_.end()) { for (ProxyJIDClientSessionVector::iterator i = proxySessions_[sessionID].begin(); i != proxySessions_[sessionID].end();) { if ((i->first == jid) && (i->second != session)) { i->second->stop(); i = proxySessions_[sessionID].erase(i); } else { i++; diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp index 33a5283..f749735 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp @@ -1,50 +1,49 @@ /* * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ #include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h> #include <memory> #include <boost/bind.hpp> #include <Swiften/Base/Log.h> -#include <Swiften/Base/foreach.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServer.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h> #include <Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h> #include <Swiften/Network/ConnectionServer.h> #include <Swiften/Network/ConnectionServerFactory.h> #include <Swiften/Network/NATTraversalForwardPortRequest.h> #include <Swiften/Network/NATTraversalGetPublicIPRequest.h> #include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> #include <Swiften/Network/NATTraverser.h> #include <Swiften/Network/NetworkEnvironment.h> using namespace Swift; static const int LISTEN_PORTS_BEGIN = 10000; static const int LISTEN_PORTS_END = 11000; SOCKS5BytestreamServerManager::SOCKS5BytestreamServerManager( SOCKS5BytestreamRegistry* bytestreamRegistry, ConnectionServerFactory* connectionServerFactory, NetworkEnvironment* networkEnvironment, NATTraverser* natTraverser) : bytestreamRegistry(bytestreamRegistry), connectionServerFactory(connectionServerFactory), networkEnvironment(networkEnvironment), natTraverser(natTraverser), state(Start), server(nullptr), attemptedPortMapping_(false) { } @@ -61,91 +60,91 @@ SOCKS5BytestreamServerManager::~SOCKS5BytestreamServerManager() { } std::shared_ptr<SOCKS5BytestreamServerResourceUser> SOCKS5BytestreamServerManager::aquireResourceUser() { std::shared_ptr<SOCKS5BytestreamServerResourceUser> resourceUser; if (s5bServerResourceUser_.expired()) { resourceUser = std::make_shared<SOCKS5BytestreamServerResourceUser>(this); s5bServerResourceUser_ = resourceUser; } else { resourceUser = s5bServerResourceUser_.lock(); } return resourceUser; } std::shared_ptr<SOCKS5BytestreamServerPortForwardingUser> SOCKS5BytestreamServerManager::aquirePortForwardingUser() { std::shared_ptr<SOCKS5BytestreamServerPortForwardingUser> portForwardingUser; if (s5bServerPortForwardingUser_.expired()) { portForwardingUser = std::make_shared<SOCKS5BytestreamServerPortForwardingUser>(this); s5bServerPortForwardingUser_ = portForwardingUser; } else { portForwardingUser = s5bServerPortForwardingUser_.lock(); } return portForwardingUser; } std::vector<HostAddressPort> SOCKS5BytestreamServerManager::getHostAddressPorts() const { std::vector<HostAddressPort> result; if (connectionServer) { std::vector<NetworkInterface> networkInterfaces = networkEnvironment->getNetworkInterfaces(); - foreach (const NetworkInterface& networkInterface, networkInterfaces) { - foreach (const HostAddress& address, networkInterface.getAddresses()) { + for (const auto& networkInterface : networkInterfaces) { + for (const auto& address : networkInterface.getAddresses()) { result.push_back(HostAddressPort(address, connectionServerPort)); } } } return result; } std::vector<HostAddressPort> SOCKS5BytestreamServerManager::getAssistedHostAddressPorts() const { std::vector<HostAddressPort> result; if (publicAddress && portMapping) { result.push_back(HostAddressPort(*publicAddress, portMapping->getPublicPort())); } return result; } bool SOCKS5BytestreamServerManager::isInitialized() const { return state == Initialized; } void SOCKS5BytestreamServerManager::initialize() { if (state == Start) { state = Initializing; // Find a port to listen on assert(!connectionServer); int port; for (port = LISTEN_PORTS_BEGIN; port < LISTEN_PORTS_END; ++port) { SWIFT_LOG(debug) << "Trying to start server on port " << port << std::endl; - connectionServer = connectionServerFactory->createConnectionServer(HostAddress("::"), port); + connectionServer = connectionServerFactory->createConnectionServer(HostAddress::fromString("::").get(), port); boost::optional<ConnectionServer::Error> error = connectionServer->tryStart(); if (!error) { break; } else if (*error != ConnectionServer::Conflict) { SWIFT_LOG(debug) << "Error starting server" << std::endl; onInitialized(false); return; } connectionServer.reset(); } if (!connectionServer) { SWIFT_LOG(debug) << "Unable to find an open port" << std::endl; onInitialized(false); return; } SWIFT_LOG(debug) << "Server started succesfully" << std::endl; connectionServerPort = port; // Start bytestream server. Should actually happen before the connectionserver is started // but that doesn't really matter here. assert(!server); server = new SOCKS5BytestreamServer(connectionServer, bytestreamRegistry); server->start(); checkInitializeFinished(); } } bool SOCKS5BytestreamServerManager::isPortForwardingReady() const { return attemptedPortMapping_ && !getPublicIPRequest && !forwardPortRequest; diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp index cb43d78..290dda5 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp @@ -26,61 +26,61 @@ #include <Swiften/Base/ByteArray.h> #include <Swiften/Base/Concat.h> #include <Swiften/Base/Log.h> #include <Swiften/Base/StartStopper.h> #include <Swiften/Crypto/CryptoProvider.h> #include <Swiften/Crypto/PlatformCryptoProvider.h> #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/FileTransfer/ByteArrayReadBytestream.h> #include <Swiften/FileTransfer/ByteArrayWriteBytestream.h> #include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h> #include <Swiften/JID/JID.h> #include <Swiften/Network/DummyConnection.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/StringCodecs/Hexify.h> using namespace Swift; static boost::mt19937 randomGen; class SOCKS5BytestreamClientSessionTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(SOCKS5BytestreamClientSessionTest); CPPUNIT_TEST(testForSessionReady); CPPUNIT_TEST(testErrorHandlingHello); CPPUNIT_TEST(testErrorHandlingRequest); CPPUNIT_TEST(testWriteBytestream); CPPUNIT_TEST(testReadBytestream); CPPUNIT_TEST_SUITE_END(); public: - SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress("127.0.0.1"), 8888)) {} + SOCKS5BytestreamClientSessionTest() : destinationAddressPort(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 8888)) {} void setUp() { crypto = std::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); destination = "092a44d859d19c9eed676b551ee80025903351c2"; randomGen.seed(static_cast<unsigned int>(time(nullptr))); eventLoop = std::unique_ptr<DummyEventLoop>(new DummyEventLoop()); timerFactory = std::unique_ptr<DummyTimerFactory>(new DummyTimerFactory()); connection = std::make_shared<MockeryConnection>(failingPorts, true, eventLoop.get()); //connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); //stream1 = std::make_shared<ByteArrayReadBytestream>(createByteArray("abcdefg"))); // connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamClientSessionTest::handleDataRead, this, _1)); } void tearDown() { //connection.reset(); } void testForSessionReady() { TestHelper helper; connection->onDataSent.connect(boost::bind(&TestHelper::handleConnectionDataWritten, &helper, _1)); SOCKS5BytestreamClientSession::ref clientSession = std::make_shared<SOCKS5BytestreamClientSession>(connection, destinationAddressPort, destination, timerFactory.get()); clientSession->onSessionReady.connect(boost::bind(&TestHelper::handleSessionReady, &helper, _1)); clientSession->start(); eventLoop->processEvents(); CPPUNIT_ASSERT(createByteArray("\x05\x01\x00", 3) == helper.unprocessedInput); helper.unprocessedInput.clear(); serverRespondHelloOK(); diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp index 3c5e098..85ae537 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp @@ -17,118 +17,118 @@ #include <Swiften/LinkLocal/LinkLocalService.h> #include <Swiften/Network/FakeConnection.h> using namespace Swift; class LinkLocalConnectorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(LinkLocalConnectorTest); CPPUNIT_TEST(testConnect); CPPUNIT_TEST(testConnect_UnableToResolve); CPPUNIT_TEST(testConnect_UnableToConnect); CPPUNIT_TEST(testCancel_DuringResolve); CPPUNIT_TEST(testCancel_DuringConnect); CPPUNIT_TEST_SUITE_END(); public: void setUp() { eventLoop = new DummyEventLoop(); querier = std::make_shared<FakeDNSSDQuerier>("rabbithole.local", eventLoop); connection = std::make_shared<FakeConnection>(eventLoop); connectFinished = false; } void tearDown() { querier->clearAllQueriesEverRun(); delete eventLoop; } void testConnect() { std::shared_ptr<LinkLocalConnector> testling(createConnector("rabbithole.local", 1234)); - querier->setAddress("rabbithole.local", HostAddress("192.168.1.1")); + querier->setAddress("rabbithole.local", HostAddress::fromString("192.168.1.1").get()); testling->connect(); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(!connectError); CPPUNIT_ASSERT(connection->connectedTo); CPPUNIT_ASSERT_EQUAL(std::string(connection->connectedTo->getAddress().toString()), std::string("192.168.1.1")); CPPUNIT_ASSERT_EQUAL(connection->connectedTo->getPort(), 1234); } void testConnect_UnableToResolve() { std::shared_ptr<LinkLocalConnector> testling(createConnector("rabbithole.local", 1234)); querier->setAddress("rabbithole.local", boost::optional<HostAddress>()); testling->connect(); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(connectError); CPPUNIT_ASSERT(!connection->connectedTo); } void testConnect_UnableToConnect() { std::shared_ptr<LinkLocalConnector> testling(createConnector("rabbithole.local", 1234)); - querier->setAddress("rabbithole.local", HostAddress("192.168.1.1")); + querier->setAddress("rabbithole.local", HostAddress::fromString("192.168.1.1").get()); connection->setError(Connection::ReadError); testling->connect(); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(connectError); CPPUNIT_ASSERT(!connection->connectedTo); } void testCancel_DuringResolve() { std::shared_ptr<LinkLocalConnector> testling(createConnector("rabbithole.local", 1234)); testling->connect(); eventLoop->processEvents(); CPPUNIT_ASSERT(!connectFinished); testling->cancel(); eventLoop->processEvents(); - querier->setAddress("rabbithole.local", HostAddress("192.168.1.1")); + querier->setAddress("rabbithole.local", HostAddress::fromString("192.168.1.1").get()); eventLoop->processEvents(); CPPUNIT_ASSERT(FakeConnection::Disconnected == connection->state); } void testCancel_DuringConnect() { std::shared_ptr<LinkLocalConnector> testling(createConnector("rabbithole.local", 1234)); - querier->setAddress("rabbithole.local", HostAddress("192.168.1.1")); + querier->setAddress("rabbithole.local", HostAddress::fromString("192.168.1.1").get()); connection->setDelayConnect(); testling->connect(); eventLoop->processEvents(); CPPUNIT_ASSERT(FakeConnection::Connecting == connection->state); testling->cancel(); eventLoop->processEvents(); CPPUNIT_ASSERT(FakeConnection::Disconnected == connection->state); } private: std::shared_ptr<LinkLocalConnector> createConnector(const std::string& hostname, int port) { LinkLocalService service( DNSSDServiceID("myname", "local."), DNSSDResolveServiceQuery::Result( "myname._presence._tcp.local", hostname, port, LinkLocalServiceInfo().toTXTRecord())); std::shared_ptr<LinkLocalConnector> result( new LinkLocalConnector(service, querier, connection)); result->onConnectFinished.connect( boost::bind(&LinkLocalConnectorTest::handleConnected, this, _1)); return result; } void handleConnected(bool e) { connectFinished = true; connectError = e; } diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp index 37cf35d..457d8a9 100644 --- a/Swiften/Network/Connector.cpp +++ b/Swiften/Network/Connector.cpp @@ -3,73 +3,74 @@ * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Network/Connector.h> #include <boost/bind.hpp> #include <Swiften/Base/Log.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/DomainNameAddressQuery.h> #include <Swiften/Network/DomainNameResolver.h> #include <Swiften/Network/HostAddress.h> #include <Swiften/Network/TimerFactory.h> namespace Swift { Connector::Connector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), port(port), serviceLookupPrefix(serviceLookupPrefix), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) { } void Connector::setTimeoutMilliseconds(int milliseconds) { timeoutMilliseconds = milliseconds; } void Connector::start() { SWIFT_LOG(debug) << "Starting connector for " << hostname << std::endl; assert(!currentConnection); assert(!serviceQuery); assert(!timer); queriedAllServices = false; + auto hostAddress = HostAddress::fromString(hostname); if (timeoutMilliseconds > 0) { timer = timerFactory->createTimer(timeoutMilliseconds); timer->onTick.connect(boost::bind(&Connector::handleTimeout, shared_from_this())); } if (serviceLookupPrefix) { serviceQuery = resolver->createServiceQuery(*serviceLookupPrefix, hostname); serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1)); serviceQuery->run(); } - else if (HostAddress(hostname).isValid()) { + else if (hostAddress) { // hostname is already a valid address; skip name lookup. foundSomeDNS = true; - addressQueryResults.push_back(HostAddress(hostname)); + addressQueryResults.push_back(hostAddress.get()); tryNextAddress(); } else { queryAddress(hostname); } } void Connector::stop() { if (currentConnection) { currentConnection->onConnectFinished.disconnect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1)); currentConnection->disconnect(); } finish(std::shared_ptr<Connection>()); } void Connector::queryAddress(const std::string& hostname) { assert(!addressQuery); addressQuery = resolver->createAddressQuery(hostname); addressQuery->onResult.connect(boost::bind(&Connector::handleAddressQueryResult, shared_from_this(), _1, _2)); addressQuery->run(); } void Connector::handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result) { SWIFT_LOG(debug) << result.size() << " SRV result(s)" << std::endl; serviceQueryResults = std::deque<DomainNameServiceQuery::Result>(result.begin(), result.end()); serviceQuery.reset(); if (!serviceQueryResults.empty()) { foundSomeDNS = true; } tryNextServiceOrFallback(); } diff --git a/Swiften/Network/EnvironmentProxyProvider.cpp b/Swiften/Network/EnvironmentProxyProvider.cpp index faf2e5b..8edb136 100644 --- a/Swiften/Network/EnvironmentProxyProvider.cpp +++ b/Swiften/Network/EnvironmentProxyProvider.cpp @@ -23,34 +23,34 @@ namespace Swift { EnvironmentProxyProvider::EnvironmentProxyProvider() { socksProxy = getFromEnv("all_proxy", "socks"); httpProxy = getFromEnv("http_proxy", "http"); SWIFT_LOG(debug) << "Environment: SOCKS5 => " << socksProxy.toString() << "; HTTP Connect => " << httpProxy.toString() << std::endl; } HostAddressPort EnvironmentProxyProvider::getHTTPConnectProxy() const { return httpProxy; } HostAddressPort EnvironmentProxyProvider::getSOCKS5Proxy() const { return socksProxy; } HostAddressPort EnvironmentProxyProvider::getFromEnv(const char* envVarName, std::string proxyProtocol) { char* envVar = nullptr; std::string address; int port = 0; envVar = getenv(envVarName); proxyProtocol += "://"; address = envVar != nullptr ? envVar : "0.0.0.0"; if(envVar != nullptr && address.compare(0, proxyProtocol.length(), proxyProtocol) == 0) { address = address.substr(proxyProtocol.length(), address.length()); port = atoi(address.substr(address.find(':') + 1, address.length()).c_str()); address = address.substr(0, address.find(':')); } - return HostAddressPort(HostAddress(address), port); + return HostAddressPort(HostAddress::fromString(address).get_value_or(HostAddress()), port); } } diff --git a/Swiften/Network/HostAddress.cpp b/Swiften/Network/HostAddress.cpp index 63cd3f2..6eca80b 100644 --- a/Swiften/Network/HostAddress.cpp +++ b/Swiften/Network/HostAddress.cpp @@ -1,72 +1,74 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Network/HostAddress.h> #include <cassert> #include <cstring> #include <string> #include <Swiften/Base/Log.h> static boost::asio::ip::address localhost4 = boost::asio::ip::address(boost::asio::ip::address_v4::loopback()); static boost::asio::ip::address localhost6 = boost::asio::ip::address(boost::asio::ip::address_v6::loopback()); namespace Swift { HostAddress::HostAddress() { } -HostAddress::HostAddress(const std::string& address) { - boost::system::error_code errorCode; - address_ = boost::asio::ip::address::from_string(address, errorCode); - if (errorCode) { - SWIFT_LOG(warning) << "error: " << errorCode.message() << " (" << errorCode << ")" << ", " << "address: " << address << std::endl; - } -} - HostAddress::HostAddress(const unsigned char* address, size_t length) { assert(length == 4 || length == 16); if (length == 4) { boost::asio::ip::address_v4::bytes_type data; std::memcpy(data.data(), address, length); address_ = boost::asio::ip::address(boost::asio::ip::address_v4(data)); } else { boost::asio::ip::address_v6::bytes_type data; std::memcpy(data.data(), address, length); address_ = boost::asio::ip::address(boost::asio::ip::address_v6(data)); } } HostAddress::HostAddress(const boost::asio::ip::address& address) : address_(address) { } std::string HostAddress::toString() const { std::string addressString; boost::system::error_code errorCode; addressString = address_.to_string(errorCode); if (errorCode) { SWIFT_LOG(debug) << "error: " << errorCode.message() << std::endl; } return addressString; } bool HostAddress::isValid() const { return !(address_.is_v4() && address_.to_v4().to_ulong() == 0); } boost::asio::ip::address HostAddress::getRawAddress() const { return address_; } bool HostAddress::isLocalhost() const { return address_ == localhost4 || address_ == localhost6; } +boost::optional<HostAddress> HostAddress::fromString(const std::string& addressString) { + boost::optional<HostAddress> hostAddress; + boost::system::error_code errorCode; + boost::asio::ip::address address = boost::asio::ip::address::from_string(addressString, errorCode); + if (!errorCode) { + hostAddress = HostAddress(address); + } + return hostAddress; +} + } diff --git a/Swiften/Network/HostAddress.h b/Swiften/Network/HostAddress.h index 00fe9bf..e4ddffb 100644 --- a/Swiften/Network/HostAddress.h +++ b/Swiften/Network/HostAddress.h @@ -1,35 +1,38 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ + #pragma once #include <string> #include <boost/asio/ip/address.hpp> +#include <boost/optional.hpp> #include <Swiften/Base/API.h> namespace Swift { class SWIFTEN_API HostAddress { public: HostAddress(); - HostAddress(const std::string&); HostAddress(const unsigned char* address, size_t length); HostAddress(const boost::asio::ip::address& address); std::string toString() const; boost::asio::ip::address getRawAddress() const; bool operator==(const HostAddress& o) const { return address_ == o.address_; } bool isValid() const; bool isLocalhost() const; + static boost::optional<HostAddress> fromString(const std::string& addressString); + private: boost::asio::ip::address address_; }; } diff --git a/Swiften/Network/MacOSXProxyProvider.cpp b/Swiften/Network/MacOSXProxyProvider.cpp index acea480..232fc60 100644 --- a/Swiften/Network/MacOSXProxyProvider.cpp +++ b/Swiften/Network/MacOSXProxyProvider.cpp @@ -1,100 +1,101 @@ /* * Copyright (c) 2010-2011 Thilo Cestonaro * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2013-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Base/Platform.h> #include <Swiften/Network/MacOSXProxyProvider.h> #include <stdio.h> #include <stdlib.h> #include <iostream> -#include <boost/numeric/conversion/cast.hpp> #include <utility> +#include <boost/numeric/conversion/cast.hpp> + #ifndef SWIFTEN_PLATFORM_IPHONE #include <SystemConfiguration/SystemConfiguration.h> #endif #pragma clang diagnostic ignored "-Wdisabled-macro-expansion" using namespace Swift; #ifndef SWIFTEN_PLATFORM_IPHONE static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey) { CFNumberRef numberValue = nullptr; HostAddressPort ret = HostAddressPort(HostAddress(), 0); if(CFDictionaryGetValueIfPresent(dict, reinterpret_cast<const void*> (enabledKey), reinterpret_cast<const void**> (&numberValue)) == true) { const int i = 0; CFNumberRef zero = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); CFComparisonResult result = CFNumberCompare(numberValue, zero, nullptr); CFRelease(zero); if(result != kCFCompareEqualTo) { int port = 0; std::string host = ""; try { CFNumberRef numberValue = reinterpret_cast<CFNumberRef> (CFDictionaryGetValue(dict, portKey)); if(numberValue != nullptr) { CFNumberGetValue(numberValue, kCFNumberIntType, &port); } CFStringRef stringValue = reinterpret_cast<CFStringRef> (CFDictionaryGetValue(dict, hostKey)); if(stringValue != nullptr) { std::vector<char> buffer; // length must be +1 for the ending zero; and the Docu of CFStringGetCString tells it like // if the string is toby the length must be at least 5. CFIndex length = CFStringGetLength(stringValue) + 1; buffer.resize(boost::numeric_cast<size_t>(length)); if(CFStringGetCString(stringValue, &buffer[0], length, kCFStringEncodingMacRoman)) { for(char& iter : buffer) { host += iter; } } } } catch(...) { std::cerr << "Exception caught ... " << std::endl; } if(host != "" && port != 0) { - ret = HostAddressPort(HostAddress(host), port); + ret = HostAddressPort(HostAddress::fromString(host).get(), port); } } } return ret; } #endif namespace Swift { MacOSXProxyProvider::MacOSXProxyProvider() { } HostAddressPort MacOSXProxyProvider::getHTTPConnectProxy() const { HostAddressPort result; #ifndef SWIFTEN_PLATFORM_IPHONE CFDictionaryRef proxies = SCDynamicStoreCopyProxies(nullptr); if(proxies != nullptr) { result = getFromDictionary(proxies, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); CFRelease(proxies); } #endif return result; } HostAddressPort MacOSXProxyProvider::getSOCKS5Proxy() const { HostAddressPort result; #ifndef SWIFTEN_PLATFORM_IPHONE CFDictionaryRef proxies = SCDynamicStoreCopyProxies(nullptr); if(proxies != nullptr) { result = getFromDictionary(proxies, kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort); CFRelease(proxies); diff --git a/Swiften/Network/MiniUPnPInterface.cpp b/Swiften/Network/MiniUPnPInterface.cpp index d63b69e..dbe8bcd 100644 --- a/Swiften/Network/MiniUPnPInterface.cpp +++ b/Swiften/Network/MiniUPnPInterface.cpp @@ -42,61 +42,61 @@ MiniUPnPInterface::MiniUPnPInterface() : p(new Private()) { #endif if (!p->deviceList) { return; } char lanAddress[64]; if (!UPNP_GetValidIGD(p->deviceList, &p->urls, &p->data, lanAddress, sizeof(lanAddress))) { return; } p->localAddress = std::string(lanAddress); p->isValid = true; } MiniUPnPInterface::~MiniUPnPInterface() { if (p->isValid) { FreeUPNPUrls(&p->urls); } freeUPNPDevlist(p->deviceList); } boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() { if (!p->isValid) { return boost::optional<HostAddress>(); } char externalIPAddress[40]; int ret = UPNP_GetExternalIPAddress(p->urls.controlURL, p->data.first.servicetype, externalIPAddress); if (ret != UPNPCOMMAND_SUCCESS) { return boost::optional<HostAddress>(); } else { - return HostAddress(std::string(externalIPAddress)); + return HostAddress::fromString(std::string(externalIPAddress)); } } boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLocalPort, int actualPublicPort) { if (!p->isValid) { return boost::optional<NATPortMapping>(); } NATPortMapping mapping(actualLocalPort, actualPublicPort, NATPortMapping::TCP); std::string publicPort = boost::lexical_cast<std::string>(mapping.getPublicPort()); std::string localPort = boost::lexical_cast<std::string>(mapping.getLocalPort()); std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds()); int ret = UPNP_AddPortMapping( p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), localPort.c_str(), p->localAddress.c_str(), "Swift", mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", nullptr, leaseSeconds.c_str()); if (ret == UPNPCOMMAND_SUCCESS) { return mapping; } else { return boost::optional<NATPortMapping>(); } diff --git a/Swiften/Network/ProxiedConnection.cpp b/Swiften/Network/ProxiedConnection.cpp index 16bab0d..aa6c4d2 100644 --- a/Swiften/Network/ProxiedConnection.cpp +++ b/Swiften/Network/ProxiedConnection.cpp @@ -1,59 +1,59 @@ /* * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Network/ProxiedConnection.h> #include <boost/bind.hpp> #include <Swiften/Base/ByteArray.h> #include <Swiften/Base/Log.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/HostAddressPort.h> using namespace Swift; ProxiedConnection::ProxiedConnection( DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort), - server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) { + server_(HostAddressPort(HostAddress::fromString("0.0.0.0").get(), 0)) { connected_ = false; } ProxiedConnection::~ProxiedConnection() { cancelConnector(); if (connection_) { connection_->onDataRead.disconnect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1)); connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1)); } if (connected_) { SWIFT_LOG(warning) << "Connection was still established." << std::endl; } } void ProxiedConnection::cancelConnector() { if (connector_) { connector_->onConnectFinished.disconnect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1)); connector_->stop(); connector_.reset(); } } void ProxiedConnection::connect(const HostAddressPort& server) { server_ = server; connector_ = Connector::create(proxyHost_, proxyPort_, boost::optional<std::string>(), resolver_, connectionFactory_, timerFactory_); connector_->onConnectFinished.connect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1)); connector_->start(); } diff --git a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp index 8dbd09e..5d6fedd 100644 --- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp +++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp @@ -42,61 +42,61 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture { CPPUNIT_TEST(testSession); CPPUNIT_TEST(testWrite_Empty); CPPUNIT_TEST_SUITE_END(); public: void setUp() { to = "wonderland.lit"; path = "/http-bind"; port = "5280"; sid = "MyShinySID"; initial = "<body wait='60' " "inactivity='30' " "polling='5' " "requests='2' " "hold='1' " "maxpause='120' " "sid='" + sid + "' " "ver='1.6' " "from='wonderland.lit' " "xmlns='http://jabber.org/protocol/httpbind'/>"; eventLoop = new DummyEventLoop(); connectionFactory = new MockConnectionFactory(eventLoop); boshURL = URL("http", to, 5280, path); sessionTerminated = 0; sessionStarted = 0; initialRID = 2349876; xmppDataRead.clear(); boshDataRead.clear(); boshDataWritten.clear(); resolver = new StaticDomainNameResolver(eventLoop); - resolver->addAddress(to, HostAddress("127.0.0.1")); + resolver->addAddress(to, HostAddress::fromString("127.0.0.1").get()); timerFactory = new DummyTimerFactory(); } void tearDown() { eventLoop->processEvents(); delete connectionFactory; delete resolver; delete timerFactory; delete eventLoop; } void testConnectionCount_OneWrite() { PoolRef testling = createTestling(); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, sessionStarted); readResponse(initial, connectionFactory->connections[0]); CPPUNIT_ASSERT_EQUAL(1, sessionStarted); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); testling->write(createSafeByteArray("<blah/>")); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); CPPUNIT_ASSERT_EQUAL(1, sessionStarted); } void testConnectionCount_TwoWrites() { PoolRef testling = createTestling(); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); eventLoop->processEvents(); readResponse(initial, connectionFactory->connections[0]); @@ -207,61 +207,61 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(c1->pending); CPPUNIT_ASSERT_EQUAL(st(4), boshDataWritten.size()); /* don't send empty in [0], still have [1] waiting */ CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size()); rid++; readResponse("<body xmlns='http://jabber.org/protocol/httpbind'><message><splatploing><blittlebarg/></splatploing></message></body>", c1); eventLoop->processEvents(); CPPUNIT_ASSERT(!c1->pending); CPPUNIT_ASSERT(c0->pending); CPPUNIT_ASSERT_EQUAL(st(5), boshDataWritten.size()); /* empty to make room */ CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size()); rid++; testling->write(createSafeByteArray("<bleh/>")); eventLoop->processEvents(); CPPUNIT_ASSERT(c0->pending); CPPUNIT_ASSERT(c1->pending); CPPUNIT_ASSERT_EQUAL(st(6), boshDataWritten.size()); /* data */ rid++; testling->write(createSafeByteArray("<bluh/>")); CPPUNIT_ASSERT(c0->pending); CPPUNIT_ASSERT(c1->pending); CPPUNIT_ASSERT_EQUAL(st(6), boshDataWritten.size()); /* Don't send data, no room */ eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size()); } void testSession() { to = "prosody.doomsong.co.uk"; - resolver->addAddress("prosody.doomsong.co.uk", HostAddress("127.0.0.1")); + resolver->addAddress("prosody.doomsong.co.uk", HostAddress::fromString("127.0.0.1").get()); path = "/http-bind/"; boshURL = URL("http", to, 5280, path); PoolRef testling = createTestling(); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); /* header*/ CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); std::string response = "<body authid='743da605-4c2e-4de1-afac-ac040dd4a940' xmpp:version='1.0' xmlns:stream='http://etherx.jabber.org/streams' xmlns:xmpp='urn:xmpp:xbosh' inactivity='60' wait='60' polling='5' secure='true' hold='1' from='prosody.doomsong.co.uk' ver='1.6' sid='743da605-4c2e-4de1-afac-ac040dd4a940' requests='2' xmlns='http://jabber.org/protocol/httpbind'><stream:features><auth xmlns='http://jabber.org/features/iq-auth'/><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>SCRAM-SHA-1</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features></body>"; readResponse(response, connectionFactory->connections[0]); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); std::string send = "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"SCRAM-SHA-1\">biwsbj1hZG1pbixyPWZhOWE5ZDhiLWZmMDctNGE4Yy04N2E3LTg4YWRiNDQxZGUwYg==</auth>"; testling->write(createSafeByteArray(send)); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(st(2), boshDataWritten.size()); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); response = "<body xmlns='http://jabber.org/protocol/httpbind' sid='743da605-4c2e-4de1-afac-ac040dd4a940' xmlns:stream = 'http://etherx.jabber.org/streams'><challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1mYTlhOWQ4Yi1mZjA3LTRhOGMtODdhNy04OGFkYjQ0MWRlMGJhZmZlMWNhMy1mMDJkLTQ5NzEtYjkyNS0yM2NlNWQ2MDQyMjYscz1OVGd5WkdWaFptTXRaVE15WXkwMFpXUmhMV0ZqTURRdFpqYzRNbUppWmpGa1pqWXgsaT00MDk2</challenge></body>"; readResponse(response, connectionFactory->connections[0]); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(st(2), boshDataWritten.size()); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); send = "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">Yz1iaXdzLHI9ZmE5YTlkOGItZmYwNy00YThjLTg3YTctODhhZGI0NDFkZTBiYWZmZTFjYTMtZjAyZC00OTcxLWI5MjUtMjNjZTVkNjA0MjI2LHA9aU11NWt3dDN2VWplU2RqL01Jb3VIRldkZjBnPQ==</response>"; testling->write(createSafeByteArray(send)); eventLoop->processEvents(); diff --git a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp index a791e96..99dd462 100644 --- a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp +++ b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp @@ -166,61 +166,61 @@ class BOSHConnectionTest : public CppUnit::TestFixture { "</body>")); connection->onDataRead(data1); connection->onDataRead(data2); CPPUNIT_ASSERT(dataRead.empty()); connection->onDataRead(data3); CPPUNIT_ASSERT_EQUAL(std::string("<blah/>"), byteArrayToString(dataRead)); } void testHTTPRequest() { std::string data = "<blah/>"; std::string sid = "wigglebloom"; std::string fullBody = "<body xmlns='http://jabber.org/protocol/httpbind' sid='" + sid + "' rid='20'>" + data + "</body>"; std::pair<SafeByteArray, size_t> http = BOSHConnection::createHTTPRequest(createSafeByteArray(data), false, false, 20, sid, URL()); CPPUNIT_ASSERT_EQUAL(fullBody.size(), http.second); } void testHTTPRequest_Empty() { std::string data = ""; std::string sid = "wigglebloomsickle"; std::string fullBody = "<body rid='42' sid='" + sid + "' xmlns='http://jabber.org/protocol/httpbind'>" + data + "</body>"; std::pair<SafeByteArray, size_t> http = BOSHConnection::createHTTPRequest(createSafeByteArray(data), false, false, 42, sid, URL()); CPPUNIT_ASSERT_EQUAL(fullBody.size(), http.second); std::string response = safeByteArrayToString(http.first); size_t bodyPosition = response.find("\r\n\r\n"); CPPUNIT_ASSERT_EQUAL(fullBody, response.substr(bodyPosition+4)); } private: BOSHConnection::ref createTestling() { - resolver->addAddress("wonderland.lit", HostAddress("127.0.0.1")); + resolver->addAddress("wonderland.lit", HostAddress::fromString("127.0.0.1").get()); Connector::ref connector = Connector::create("wonderland.lit", 5280, boost::optional<std::string>(), resolver, connectionFactory, timerFactory); BOSHConnection::ref c = BOSHConnection::create(URL("http", "wonderland.lit", 5280, "/http-bind"), connector, &parserFactory, tlsContextFactory, TLSOptions()); c->onConnectFinished.connect(boost::bind(&BOSHConnectionTest::handleConnectFinished, this, _1)); c->onDisconnected.connect(boost::bind(&BOSHConnectionTest::handleDisconnected, this, _1)); c->onXMPPDataRead.connect(boost::bind(&BOSHConnectionTest::handleDataRead, this, _1)); c->onSessionStarted.connect(boost::bind(&BOSHConnectionTest::handleSID, this, _1)); c->setRID(42); return c; } void handleConnectFinished(bool error) { connectFinished = true; connectFinishedWithError = error; } void handleDisconnected(bool e) { disconnected = true; disconnectedError = e; } void handleDataRead(const SafeByteArray& d) { append(dataRead, d); } void handleSID(const std::string& s) { sid = s; } struct MockConnection : public Connection { public: diff --git a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp index 3fad433..2d78cd7 100644 --- a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp +++ b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp @@ -7,61 +7,61 @@ #include <memory> #include <boost/bind.hpp> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/Network/ChainedConnector.h> #include <Swiften/Network/Connection.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/DomainNameResolveError.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/StaticDomainNameResolver.h> using namespace Swift; class ChainedConnectorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ChainedConnectorTest); CPPUNIT_TEST(testConnect_FirstConnectorSucceeds); CPPUNIT_TEST(testConnect_SecondConnectorSucceeds); CPPUNIT_TEST(testConnect_NoConnectorSucceeds); CPPUNIT_TEST(testConnect_NoDNS); CPPUNIT_TEST(testStop); CPPUNIT_TEST_SUITE_END(); public: void setUp() { error.reset(); - host = HostAddressPort(HostAddress("1.1.1.1"), 1234); + host = HostAddressPort(HostAddress::fromString("1.1.1.1").get(), 1234); eventLoop = new DummyEventLoop(); resolver = new StaticDomainNameResolver(eventLoop); resolver->addXMPPClientService("foo.com", host); connectionFactory1 = new MockConnectionFactory(eventLoop, 1); connectionFactory2 = new MockConnectionFactory(eventLoop, 2); timerFactory = new DummyTimerFactory(); } void tearDown() { delete timerFactory; delete connectionFactory2; delete connectionFactory1; delete resolver; delete eventLoop; } void testConnect_FirstConnectorSucceeds() { std::shared_ptr<ChainedConnector> testling(createConnector()); connectionFactory1->connects = true; connectionFactory2->connects = false; testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT_EQUAL(1, std::dynamic_pointer_cast<MockConnection>(connections[0])->id); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp index 20ad68d..8524439 100644 --- a/Swiften/Network/UnitTest/ConnectorTest.cpp +++ b/Swiften/Network/UnitTest/ConnectorTest.cpp @@ -16,63 +16,63 @@ #include <Swiften/Network/Connector.h> #include <Swiften/Network/DomainNameAddressQuery.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/StaticDomainNameResolver.h> using namespace Swift; class ConnectorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ConnectorTest); CPPUNIT_TEST(testConnect); CPPUNIT_TEST(testConnect_NoServiceLookups); CPPUNIT_TEST(testConnect_NoServiceLookups_DefaultPort); CPPUNIT_TEST(testConnect_FirstAddressHostFails); CPPUNIT_TEST(testConnect_NoSRVHost); CPPUNIT_TEST(testConnect_NoHosts); CPPUNIT_TEST(testConnect_FirstSRVHostFails); CPPUNIT_TEST(testConnect_AllSRVHostsFailWithoutFallbackHost); CPPUNIT_TEST(testConnect_AllSRVHostsFailWithFallbackHost); CPPUNIT_TEST(testConnect_SRVAndFallbackHostsFail); //CPPUNIT_TEST(testConnect_TimeoutDuringResolve); CPPUNIT_TEST(testConnect_TimeoutDuringConnectToOnlyCandidate); CPPUNIT_TEST(testConnect_TimeoutDuringConnectToCandidateFallsBack); CPPUNIT_TEST(testConnect_NoTimeout); CPPUNIT_TEST(testStop_DuringSRVQuery); CPPUNIT_TEST(testStop_Timeout); CPPUNIT_TEST_SUITE_END(); public: void setUp() { - host1 = HostAddressPort(HostAddress("1.1.1.1"), 1234); - host2 = HostAddressPort(HostAddress("2.2.2.2"), 2345); - host3 = HostAddressPort(HostAddress("3.3.3.3"), 5222); + host1 = HostAddressPort(HostAddress::fromString("1.1.1.1").get(), 1234); + host2 = HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345); + host3 = HostAddressPort(HostAddress::fromString("3.3.3.3").get(), 5222); eventLoop = new DummyEventLoop(); resolver = new StaticDomainNameResolver(eventLoop); connectionFactory = new MockConnectionFactory(eventLoop); timerFactory = new DummyTimerFactory(); } void tearDown() { delete timerFactory; delete connectionFactory; delete resolver; delete eventLoop; } void testConnect() { Connector::ref testling(createConnector()); resolver->addXMPPClientService("foo.com", host1); resolver->addXMPPClientService("foo.com", host2); resolver->addAddress("foo.com", host3.getAddress()); testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(host1 == *(connections[0]->hostAddressPort)); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_NoServiceLookups() { Connector::ref testling(createConnector(4321, boost::optional<std::string>())); @@ -95,62 +95,62 @@ class ConnectorTest : public CppUnit::TestFixture { resolver->addXMPPClientService("foo.com", host1); resolver->addXMPPClientService("foo.com", host2); resolver->addAddress("foo.com", host3.getAddress()); testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(host3.getAddress() == (*(connections[0]->hostAddressPort)).getAddress()); CPPUNIT_ASSERT_EQUAL(5222, (*(connections[0]->hostAddressPort)).getPort()); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_NoSRVHost() { Connector::ref testling(createConnector()); resolver->addAddress("foo.com", host3.getAddress()); testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(host3 == *(connections[0]->hostAddressPort)); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_FirstAddressHostFails() { Connector::ref testling(createConnector()); - HostAddress address1("1.1.1.1"); - HostAddress address2("2.2.2.2"); + auto address1 = HostAddress::fromString("1.1.1.1").get(); + auto address2 = HostAddress::fromString("2.2.2.2").get(); resolver->addXMPPClientService("foo.com", "host-foo.com", 1234); resolver->addAddress("host-foo.com", address1); resolver->addAddress("host-foo.com", address2); connectionFactory->failingPorts.push_back(HostAddressPort(address1, 1234)); testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(HostAddressPort(address2, 1234) == *(connections[0]->hostAddressPort)); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_NoHosts() { Connector::ref testling(createConnector()); testling->start(); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(!connections[0]); CPPUNIT_ASSERT(std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_FirstSRVHostFails() { Connector::ref testling(createConnector()); resolver->addXMPPClientService("foo.com", host1); resolver->addXMPPClientService("foo.com", host2); connectionFactory->failingPorts.push_back(host1); @@ -218,64 +218,64 @@ class ConnectorTest : public CppUnit::TestFixture { testling->start(); eventLoop->processEvents(); timerFactory->setTime(10); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(std::dynamic_pointer_cast<DomainNameResolveError>(error)); CPPUNIT_ASSERT(!connections[0]); }*/ void testConnect_TimeoutDuringConnectToOnlyCandidate() { Connector::ref testling(createConnector()); testling->setTimeoutMilliseconds(10); resolver->addXMPPClientService("foo.com", host1); connectionFactory->isResponsive = false; testling->start(); eventLoop->processEvents(); timerFactory->setTime(10); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(!connections[0]); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_TimeoutDuringConnectToCandidateFallsBack() { Connector::ref testling(createConnector()); testling->setTimeoutMilliseconds(10); + auto address2 = HostAddress::fromString("2.2.2.2").get(); + resolver->addXMPPClientService("foo.com", "host-foo.com", 1234); - HostAddress address1("1.1.1.1"); - resolver->addAddress("host-foo.com", address1); - HostAddress address2("2.2.2.2"); + resolver->addAddress("host-foo.com", HostAddress::fromString("1.1.1.1").get()); resolver->addAddress("host-foo.com", address2); connectionFactory->isResponsive = false; testling->start(); eventLoop->processEvents(); connectionFactory->isResponsive = true; timerFactory->setTime(10); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(HostAddressPort(address2, 1234) == *(connections[0]->hostAddressPort)); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } void testConnect_NoTimeout() { Connector::ref testling(createConnector()); testling->setTimeoutMilliseconds(10); resolver->addXMPPClientService("foo.com", host1); testling->start(); eventLoop->processEvents(); timerFactory->setTime(10); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size())); CPPUNIT_ASSERT(connections[0]); CPPUNIT_ASSERT(!std::dynamic_pointer_cast<DomainNameResolveError>(error)); } diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp index 232847b..1a160b7 100644 --- a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp +++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp @@ -1,331 +1,329 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <memory> #include <boost/algorithm/string.hpp> #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> #include <boost/optional.hpp> #include <QA/Checker/IO.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/Base/Algorithm.h> #include <Swiften/Base/Log.h> -#include <Swiften/Base/foreach.h> #include <Swiften/EventLoop/DummyEventLoop.h> #include <Swiften/Network/Connection.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/DummyTimerFactory.h> #include <Swiften/Network/HTTPConnectProxiedConnection.h> #include <Swiften/Network/HTTPTrafficFilter.h> #include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/StaticDomainNameResolver.h> using namespace Swift; namespace { class ExampleHTTPTrafficFilter : public HTTPTrafficFilter { public: ExampleHTTPTrafficFilter() {} virtual ~ExampleHTTPTrafficFilter() {} virtual std::vector<std::pair<std::string, std::string> > filterHTTPResponseHeader(const std::string& /* statusLine */, const std::vector<std::pair<std::string, std::string> >& response) { filterResponses.push_back(response); SWIFT_LOG(debug) << std::endl; return filterResponseReturn; } std::vector<std::vector<std::pair<std::string, std::string> > > filterResponses; std::vector<std::pair<std::string, std::string> > filterResponseReturn; }; class ProxyAuthenticationHTTPTrafficFilter : public HTTPTrafficFilter { static std::string to_lower(const std::string& str) { std::string lower = str; boost::algorithm::to_lower(lower); return lower; } public: ProxyAuthenticationHTTPTrafficFilter() {} virtual ~ProxyAuthenticationHTTPTrafficFilter() {} virtual std::vector<std::pair<std::string, std::string> > filterHTTPResponseHeader(const std::string& statusLine, const std::vector<std::pair<std::string, std::string> >& response) { std::vector<std::pair<std::string, std::string> > filterResponseReturn; std::vector<std::string> statusLineFields; boost::split(statusLineFields, statusLine, boost::is_any_of(" "), boost::token_compress_on); int statusCode = boost::lexical_cast<int>(statusLineFields[1]); if (statusCode == 407) { - typedef std::pair<std::string, std::string> StrPair; - foreach (const StrPair& field, response) { + for (const auto& field : response) { if (to_lower(field.first) == to_lower("Proxy-Authenticate")) { if (field.second.size() >= 6 && field.second.substr(0, 6) == " NTLM ") { filterResponseReturn.push_back(std::pair<std::string, std::string>("Proxy-Authorization", "NTLM TlRMTVNTUAADAAAAGAAYAHIAAAAYABgAigAAABIAEgBIAAAABgAGAFoAAAASABIVNTUAADAAYAAAABAAEACiAAAANYKI4gUBKAoAAAAPTABBAEIAUwBNAE8ASwBFADMAXwBxAGEATABBAEIAUwBNAE8ASwBFADMA0NKq8HYYhj8AAAAAAAAAAAAAAAAAAAAAOIiih3mR+AkyM4r99sy1mdFonCu2ILODro1WTTrJ4b4JcXEzUBA2Ig==")); return filterResponseReturn; } else if (field.second.size() >= 5 && field.second.substr(0, 5) == " NTLM") { filterResponseReturn.push_back(std::pair<std::string, std::string>("Proxy-Authorization", "NTLM TlRMTVNTUAABAAAAt7II4gkACQAxAAAACQAJACgAAAVNTUAADAAFASgKAAAAD0xBQlNNT0tFM1dPUktHUk9VUA==")); return filterResponseReturn; } } } return filterResponseReturn; } else { return std::vector<std::pair<std::string, std::string> >(); } } }; } class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(HTTPConnectProxiedConnectionTest); CPPUNIT_TEST(testConnect_CreatesConnectionToProxy); CPPUNIT_TEST(testConnect_SendsConnectRequest); CPPUNIT_TEST(testConnect_ReceiveConnectResponse); CPPUNIT_TEST(testConnect_ReceiveConnectChunkedResponse); CPPUNIT_TEST(testConnect_ReceiveMalformedConnectResponse); CPPUNIT_TEST(testConnect_ReceiveErrorConnectResponse); CPPUNIT_TEST(testConnect_ReceiveDataAfterConnect); CPPUNIT_TEST(testWrite_AfterConnect); CPPUNIT_TEST(testDisconnect_AfterConnectRequest); CPPUNIT_TEST(testDisconnect_AfterConnect); CPPUNIT_TEST(testTrafficFilter); CPPUNIT_TEST(testTrafficFilterNoConnectionReuse); CPPUNIT_TEST_SUITE_END(); public: void setUp() { proxyHost = "doo.bah"; proxyPort = 1234; - proxyHostAddress = HostAddressPort(HostAddress("1.1.1.1"), proxyPort); - host = HostAddressPort(HostAddress("2.2.2.2"), 2345); + proxyHostAddress = HostAddressPort(HostAddress::fromString("1.1.1.1").get(), proxyPort); + host = HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345); eventLoop = new DummyEventLoop(); resolver = new StaticDomainNameResolver(eventLoop); resolver->addAddress(proxyHost, proxyHostAddress.getAddress()); timerFactory = new DummyTimerFactory(); connectionFactory = new MockConnectionFactory(eventLoop); connectFinished = false; connectFinishedWithError = false; disconnected = false; } void tearDown() { delete timerFactory; delete connectionFactory; delete resolver; delete eventLoop; } void connect(HTTPConnectProxiedConnection::ref connection, const HostAddressPort& to) { connection->connect(to); eventLoop->processEvents(); eventLoop->processEvents(); eventLoop->processEvents(); } void testConnect_CreatesConnectionToProxy() { HTTPConnectProxiedConnection::ref testling(createTestling()); connect(testling, host); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connectionFactory->connections.size())); CPPUNIT_ASSERT(connectionFactory->connections[0]->hostAddressPort); CPPUNIT_ASSERT(proxyHostAddress == *connectionFactory->connections[0]->hostAddressPort); CPPUNIT_ASSERT(!connectFinished); } void testConnect_SendsConnectRequest() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); CPPUNIT_ASSERT_EQUAL(createByteArray("CONNECT 2.2.2.2:2345 HTTP/1.1\r\n\r\n"), connectionFactory->connections[0]->dataWritten); } void testConnect_ReceiveConnectResponse() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(!connectFinishedWithError); CPPUNIT_ASSERT(dataRead.empty()); } void testConnect_ReceiveConnectChunkedResponse() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 ")); eventLoop->processEvents(); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("200 Connection established\r\n\r\n")); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(!connectFinishedWithError); CPPUNIT_ASSERT(dataRead.empty()); } void testConnect_ReceiveMalformedConnectResponse() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("FLOOP")); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(connectFinishedWithError); CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); } void testConnect_ReceiveErrorConnectResponse() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 401 Unauthorized\r\n\r\n")); eventLoop->processEvents(); CPPUNIT_ASSERT(connectFinished); CPPUNIT_ASSERT(connectFinishedWithError); CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); } void testConnect_ReceiveDataAfterConnect() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); eventLoop->processEvents(); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("abcdef")); CPPUNIT_ASSERT_EQUAL(createByteArray("abcdef"), dataRead); } void testWrite_AfterConnect() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); eventLoop->processEvents(); connectionFactory->connections[0]->dataWritten.clear(); testling->write(createSafeByteArray("abcdef")); CPPUNIT_ASSERT_EQUAL(createByteArray("abcdef"), connectionFactory->connections[0]->dataWritten); } void testDisconnect_AfterConnectRequest() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); testling->disconnect(); CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); CPPUNIT_ASSERT(disconnected); CPPUNIT_ASSERT(!disconnectedError); } void testDisconnect_AfterConnect() { HTTPConnectProxiedConnection::ref testling(createTestling()); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n")); eventLoop->processEvents(); testling->disconnect(); CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); CPPUNIT_ASSERT(disconnected); CPPUNIT_ASSERT(!disconnectedError); } void testTrafficFilter() { HTTPConnectProxiedConnection::ref testling(createTestling()); std::shared_ptr<ExampleHTTPTrafficFilter> httpTrafficFilter = std::make_shared<ExampleHTTPTrafficFilter>(); testling->setHTTPTrafficFilter(httpTrafficFilter); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); // set a default response so the server response is answered by the traffic filter httpTrafficFilter->filterResponseReturn.clear(); httpTrafficFilter->filterResponseReturn.push_back(std::pair<std::string, std::string>("Authorization", "Negotiate a87421000492aa874209af8bc028")); connectionFactory->connections[0]->dataWritten.clear(); // test chunked response connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef( "HTTP/1.0 401 Unauthorized\r\n")); eventLoop->processEvents(); connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef( "WWW-Authenticate: Negotiate\r\n" "\r\n")); eventLoop->processEvents(); // verify that the traffic filter got called and answered with its response CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), httpTrafficFilter->filterResponses.size()); CPPUNIT_ASSERT_EQUAL(std::string("WWW-Authenticate"), httpTrafficFilter->filterResponses[0][0].first); // remove the default response from the traffic filter httpTrafficFilter->filterResponseReturn.clear(); eventLoop->processEvents(); // verify that the traffic filter answer is send over the wire CPPUNIT_ASSERT_EQUAL(createByteArray("CONNECT 2.2.2.2:2345 HTTP/1.1\r\nAuthorization: Negotiate a87421000492aa874209af8bc028\r\n\r\n"), connectionFactory->connections[1]->dataWritten); // verify that after without the default response, the traffic filter is skipped, authentication proceeds and traffic goes right through connectionFactory->connections[1]->dataWritten.clear(); testling->write(createSafeByteArray("abcdef")); CPPUNIT_ASSERT_EQUAL(createByteArray("abcdef"), connectionFactory->connections[1]->dataWritten); } void testTrafficFilterNoConnectionReuse() { HTTPConnectProxiedConnection::ref testling = createTestling(); std::shared_ptr<ProxyAuthenticationHTTPTrafficFilter> httpTrafficFilter = std::make_shared<ProxyAuthenticationHTTPTrafficFilter>(); testling->setHTTPTrafficFilter(httpTrafficFilter); - connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345)); + connect(testling, HostAddressPort(HostAddress::fromString("2.2.2.2").get(), 2345)); // First HTTP CONNECT request assumes the proxy will work. CPPUNIT_ASSERT_EQUAL(createByteArray("CONNECT 2.2.2.2:2345 HTTP/1.1\r\n" "\r\n"), connectionFactory->connections[0]->dataWritten); // First reply presents initiator with authentication options. connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef( "HTTP/1.0 407 ProxyAuthentication Required\r\n" "proxy-Authenticate: Negotiate\r\n" "Proxy-Authenticate: Kerberos\r\n" "proxy-Authenticate: NTLM\r\n" "\r\n")); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(false, connectFinished); CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError); // The HTTP proxy responds with code 407, so the traffic filter should inject the authentication response on a new connection. CPPUNIT_ASSERT_EQUAL(createByteArray("CONNECT 2.2.2.2:2345 HTTP/1.1\r\n" "Proxy-Authorization: NTLM TlRMTVNTUAABAAAAt7II4gkACQAxAAAACQAJACgAAAVNTUAADAAFASgKAAAAD0xBQlNNT0tFM1dPUktHUk9VUA==\r\n" "\r\n"), connectionFactory->connections[1]->dataWritten); // The proxy responds with another authentication step. connectionFactory->connections[1]->onDataRead(createSafeByteArrayRef( "HTTP/1.0 407 ProxyAuthentication Required\r\n" "Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAEAAQADgAAAA1goriluCDYHcYI/sAAAAAAAAAAFQAVABIAAAABQLODgAAAA9TAFAASQBSAEkAVAAxAEIAAgAQAFMAUABJAFIASQBUADEAQgABABAAUwBQAEkAUgBJAFQAMQBCAAQAEABzAHAAaQByAGkAdAAxAGIAAwAQAHMAcABpAHIAaQB0ADEAYgAAAAAA\r\n" "\r\n")); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(false, connectFinished); CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError); diff --git a/Swiften/Network/UnitTest/HostAddressTest.cpp b/Swiften/Network/UnitTest/HostAddressTest.cpp index aceb9be..226346b 100644 --- a/Swiften/Network/UnitTest/HostAddressTest.cpp +++ b/Swiften/Network/UnitTest/HostAddressTest.cpp @@ -1,67 +1,67 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <string> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/Network/HostAddress.h> using namespace Swift; class HostAddressTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(HostAddressTest); CPPUNIT_TEST(testConstructor); CPPUNIT_TEST(testConstructor_Invalid); CPPUNIT_TEST(testConstructor_InvalidString); CPPUNIT_TEST(testToString); CPPUNIT_TEST(testToString_IPv6); CPPUNIT_TEST(testToString_Invalid); CPPUNIT_TEST_SUITE_END(); public: void testConstructor() { - HostAddress testling("192.168.1.254"); + auto testling = HostAddress::fromString("192.168.1.254"); - CPPUNIT_ASSERT_EQUAL(std::string("192.168.1.254"), testling.toString()); - CPPUNIT_ASSERT(testling.isValid()); + CPPUNIT_ASSERT_EQUAL(std::string("192.168.1.254"), testling->toString()); + CPPUNIT_ASSERT(testling->isValid()); } void testConstructor_Invalid() { HostAddress testling; CPPUNIT_ASSERT(!testling.isValid()); } void testConstructor_InvalidString() { - HostAddress testling("invalid"); + auto testling = HostAddress::fromString("invalid"); - CPPUNIT_ASSERT(!testling.isValid()); + CPPUNIT_ASSERT(!testling); } void testToString() { unsigned char address[4] = {10, 0, 1, 253}; HostAddress testling(address, 4); CPPUNIT_ASSERT_EQUAL(std::string("10.0.1.253"), testling.toString()); } void testToString_IPv6() { unsigned char address[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17}; HostAddress testling(address, 16); CPPUNIT_ASSERT_EQUAL(std::string("102:304:506:708:90a:b0c:d0e:f11"), testling.toString()); } void testToString_Invalid() { HostAddress testling; CPPUNIT_ASSERT_EQUAL(std::string("0.0.0.0"), testling.toString()); } }; CPPUNIT_TEST_SUITE_REGISTRATION(HostAddressTest); diff --git a/Swiften/Network/WindowsProxyProvider.cpp b/Swiften/Network/WindowsProxyProvider.cpp index 75e087a..78bd72f 100644 --- a/Swiften/Network/WindowsProxyProvider.cpp +++ b/Swiften/Network/WindowsProxyProvider.cpp @@ -1,120 +1,124 @@ /* * Copyright (c) 2010-2011 Thilo Cestonaro * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Network/WindowsProxyProvider.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <boost/lexical_cast.hpp> #include <windows.h> #include <Swiften/Base/ByteArray.h> #include <Swiften/Base/Log.h> -#include <Swiften/Base/foreach.h> +#include <Swiften/Network/HostAddress.h> +#include <Swiften/Network/HostAddressPort.h> namespace Swift { WindowsProxyProvider::WindowsProxyProvider() : ProxyProvider() { HKEY hKey = (HKEY)INVALID_HANDLE_VALUE; long result; result = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ, &hKey); if (result == ERROR_SUCCESS && hKey != INVALID_HANDLE_VALUE && proxyEnabled(hKey)) { DWORD dataType = REG_SZ; DWORD dataSize = 0; ByteArray dataBuffer; result = RegQueryValueEx(hKey, "ProxyServer", NULL, &dataType, NULL, &dataSize); if(result != ERROR_SUCCESS) { return; } dataBuffer.resize(dataSize); result = RegQueryValueEx(hKey, "ProxyServer", NULL, &dataType, reinterpret_cast<BYTE*>(vecptr(dataBuffer)), &dataSize); if(result == ERROR_SUCCESS) { std::vector<std::string> proxies = String::split(byteArrayToString(dataBuffer), ';'); std::pair<std::string, std::string> protocolAndProxy; - foreach(std::string proxy, proxies) { + for(auto&& proxy : proxies) { if(proxy.find('=') != std::string::npos) { protocolAndProxy = String::getSplittedAtFirst(proxy, '='); SWIFT_LOG(debug) << "Found proxy: " << protocolAndProxy.first << " => " << protocolAndProxy.second << std::endl; if(protocolAndProxy.first.compare("socks") == 0) { socksProxy = getAsHostAddressPort(protocolAndProxy.second); } else if (protocolAndProxy.first.compare("http") == 0) { httpProxy = getAsHostAddressPort(protocolAndProxy.second); } } } } } } HostAddressPort WindowsProxyProvider::getHTTPConnectProxy() const { return httpProxy; } HostAddressPort WindowsProxyProvider::getSOCKS5Proxy() const { return socksProxy; } HostAddressPort WindowsProxyProvider::getAsHostAddressPort(std::string proxy) { HostAddressPort ret(HostAddress(), 0); try { std::pair<std::string, std::string> tmp; int port = 0; tmp = String::getSplittedAtFirst(proxy, ':'); // .c_str() is needed as tmp.second can include a \0 char which will end in an exception of the lexical cast. // with .c_str() the \0 will not be part of the string which is to be casted port = boost::lexical_cast<int> (tmp.second.c_str()); - ret = HostAddressPort(HostAddress(tmp.first), port); + ret = HostAddressPort(HostAddress::fromString(tmp.first).get(), port); } catch(...) { - SWIFT_LOG(error) << "Exception occured while parsing windows proxy \"getHostAddressPort\"." << std::endl; + SWIFT_LOG(error) << "Exception occured while parsing windows proxy \"getHostAddressPort\"." << std::endl; } return ret; } bool WindowsProxyProvider::proxyEnabled(HKEY hKey) const { bool ret = false; long result; DWORD dataType = REG_DWORD; DWORD dataSize = 0; DWORD data = 0; ByteArray dataBuffer; - if(hKey == INVALID_HANDLE_VALUE) + if(hKey == INVALID_HANDLE_VALUE) { return ret; + } result = RegQueryValueEx(hKey, "ProxyEnable", NULL, &dataType, NULL, &dataSize); - if(result != ERROR_SUCCESS) + if(result != ERROR_SUCCESS) { return ret; + } dataBuffer.resize(dataSize); result = RegQueryValueEx(hKey, "ProxyEnable", NULL, &dataType, reinterpret_cast<BYTE*>(vecptr(dataBuffer)), &dataSize); - if(result != ERROR_SUCCESS) + if(result != ERROR_SUCCESS) { return ret; + } for(size_t t = 0; t < dataBuffer.size(); t++) { data += static_cast<int> (dataBuffer[t]) * pow(256, static_cast<double>(t)); } return (data == 1); } } diff --git a/Swiften/Network/WindowsProxyProvider.h b/Swiften/Network/WindowsProxyProvider.h index ded5049..0ca897d 100644 --- a/Swiften/Network/WindowsProxyProvider.h +++ b/Swiften/Network/WindowsProxyProvider.h @@ -1,24 +1,31 @@ /* * Copyright (c) 2010-2011 Thilo Cestonaro * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + #pragma once #include <Swiften/Base/API.h> +#include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/ProxyProvider.h> namespace Swift { class SWIFTEN_API WindowsProxyProvider : public ProxyProvider { public: WindowsProxyProvider(); virtual HostAddressPort getHTTPConnectProxy() const; virtual HostAddressPort getSOCKS5Proxy() const; private: HostAddressPort getAsHostAddressPort(std::string proxy); bool proxyEnabled(HKEY hKey) const; HostAddressPort socksProxy; HostAddressPort httpProxy; }; } diff --git a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp index 859dcec..e639e20 100644 --- a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp +++ b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp @@ -17,79 +17,77 @@ #include <Swiften/Base/Log.h> namespace Swift { JingleS5BTransportMethodPayloadParser::JingleS5BTransportMethodPayloadParser() : level(0) { } void JingleS5BTransportMethodPayloadParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { if (level == 0) { getPayloadInternal()->setSessionID(attributes.getAttributeValue("sid").get_value_or("")); std::string mode = attributes.getAttributeValue("mode").get_value_or("tcp"); if (mode == "tcp") { getPayloadInternal()->setMode(JingleS5BTransportPayload::TCPMode); } else if(mode == "udp") { getPayloadInternal()->setMode(JingleS5BTransportPayload::UDPMode); } else { SWIFT_LOG(warning) << "Unknown S5B mode; falling back to defaul!"; getPayloadInternal()->setMode(JingleS5BTransportPayload::TCPMode); } getPayloadInternal()->setDstAddr(attributes.getAttributeValue("dstaddr").get_value_or("")); } else if (level == 1) { if (element == "candidate") { JingleS5BTransportPayload::Candidate candidate; candidate.cid = attributes.getAttributeValue("cid").get_value_or(""); int port = -1; try { port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get_value_or("-1")); } catch(boost::bad_lexical_cast &) { } - candidate.hostPort = HostAddressPort(HostAddress(attributes.getAttributeValue("host").get_value_or("")), port); + candidate.hostPort = HostAddressPort(HostAddress::fromString(attributes.getAttributeValue("host").get_value_or("")).get_value_or(HostAddress()), port); candidate.jid = JID(attributes.getAttributeValue("jid").get_value_or("")); int priority = -1; try { priority = boost::lexical_cast<int>(attributes.getAttributeValue("priority").get_value_or("-1")); } catch(boost::bad_lexical_cast &) { } candidate.priority = priority; candidate.type = stringToType(attributes.getAttributeValue("type").get_value_or("direct")); getPayloadInternal()->addCandidate(candidate); } else if (element == "candidate-used") { getPayloadInternal()->setCandidateUsed(attributes.getAttributeValue("cid").get_value_or("")); } else if (element == "candidate-error") { getPayloadInternal()->setCandidateError(true); } else if (element == "activated") { getPayloadInternal()->setActivated(attributes.getAttributeValue("cid").get_value_or("")); } else if (element == "proxy-error") { getPayloadInternal()->setProxyError(true); } } ++level; } void JingleS5BTransportMethodPayloadParser::handleEndElement(const std::string&, const std::string&) { --level; - - } void JingleS5BTransportMethodPayloadParser::handleCharacterData(const std::string&) { } JingleS5BTransportPayload::Candidate::Type JingleS5BTransportMethodPayloadParser::stringToType(const std::string &str) const { if (str == "direct") { return JingleS5BTransportPayload::Candidate::DirectType; } else if (str == "assisted") { return JingleS5BTransportPayload::Candidate::AssistedType; } else if (str == "tunnel") { return JingleS5BTransportPayload::Candidate::TunnelType; } else if (str == "proxy") { return JingleS5BTransportPayload::Candidate::ProxyType; } else { SWIFT_LOG(warning) << "Unknown candidate type; falling back to default!"; return JingleS5BTransportPayload::Candidate::DirectType; } } } diff --git a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp index 3bf79a5..c502c8a 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp @@ -1,38 +1,38 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2015 Isode Limited. + * Copyright (c) 2015-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <Swiften/Base/DateTime.h> #include <Swiften/Elements/JingleFileTransferDescription.h> #include <Swiften/Elements/JingleFileTransferHash.h> #include <Swiften/Elements/JingleIBBTransportPayload.h> #include <Swiften/Elements/JinglePayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> #include <Swiften/Elements/StreamInitiationFileInfo.h> #include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h> #include <Swiften/StringCodecs/Base64.h> using namespace Swift; class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(JingleParserTest); CPPUNIT_TEST(testParse_Xep0166_Example3); CPPUNIT_TEST(testParse_Xep0166_Example8); CPPUNIT_TEST(testParse_Xep0261_Example1); CPPUNIT_TEST(testParse_Xep0261_Example3); CPPUNIT_TEST(testParse_Xep0261_Example9); CPPUNIT_TEST(testParse_Xep0261_Example13); CPPUNIT_TEST(testParse_Xep0234_Example1); @@ -493,68 +493,68 @@ class JingleParserTest : public CppUnit::TestFixture { " priority='8258636'\n" " type='direct'/>\n" " </transport>\n" " </content>\n" "</jingle>\n" )); JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); CPPUNIT_ASSERT(jingle); CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction()); CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); CPPUNIT_ASSERT(content); JingleS5BTransportPayload::ref s5bPayload = content->getTransport<JingleS5BTransportPayload>(); CPPUNIT_ASSERT(s5bPayload); CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), s5bPayload->getSessionID()); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::TCPMode, s5bPayload->getMode()); CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasCandidateError()); CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasProxyError()); CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getActivated()); CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getCandidateUsed()); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), s5bPayload->getCandidates().size()); JingleS5BTransportPayload::Candidate candidate; candidate = s5bPayload->getCandidates()[0]; CPPUNIT_ASSERT_EQUAL(std::string("hft54dqy"), candidate.cid); CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), candidate.jid); - CPPUNIT_ASSERT(HostAddressPort(HostAddress("192.168.4.1"), 5086) == candidate.hostPort); + CPPUNIT_ASSERT(HostAddressPort(HostAddress::fromString("192.168.4.1").get(), 5086) == candidate.hostPort); CPPUNIT_ASSERT_EQUAL(8257636, candidate.priority); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); candidate = s5bPayload->getCandidates()[1]; CPPUNIT_ASSERT_EQUAL(std::string("hutr46fe"), candidate.cid); CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), candidate.jid); - CPPUNIT_ASSERT(HostAddressPort(HostAddress("24.24.24.1"), 5087) == candidate.hostPort); + CPPUNIT_ASSERT(HostAddressPort(HostAddress::fromString("24.24.24.1").get(), 5087) == candidate.hostPort); CPPUNIT_ASSERT_EQUAL(8258636, candidate.priority); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); } // http://xmpp.org/extensions/xep-0260.html#example-3 void testParse_Xep0260_Example3() { PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( "<jingle xmlns='urn:xmpp:jingle:1'\n" " action='session-accept'\n" " initiator='romeo@montague.lit/orchard'\n" " sid='a73sjjvkla37jfea'>\n" " <content creator='initiator' name='ex'>\n" " <description xmlns='urn:xmpp:example'/>\n" " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" " dstaddr='1a12fb7bc625e55f3ed5b29a53dbe0e4aa7d80ba'\n" " mode='tcp'\n" " sid='vj3hs98y'>\n" " <candidate cid='ht567dq'\n" " host='192.169.1.10'\n" " jid='juliet@capulet.lit/balcony'\n" " port='6539'\n" " priority='8257636'\n" " type='direct'/>\n" " <candidate cid='hr65dqyd'\n" " host='134.102.201.180'\n" " jid='juliet@capulet.lit/balcony'\n" " port='16453'\n" " priority='7929856'\n" " type='assisted'/>\n" @@ -567,51 +567,51 @@ class JingleParserTest : public CppUnit::TestFixture { " </transport>\n" " </content>\n" "</jingle>\n" )); JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); CPPUNIT_ASSERT(jingle); CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction()); CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); CPPUNIT_ASSERT(content); JingleS5BTransportPayload::ref s5bPayload = content->getTransport<JingleS5BTransportPayload>(); CPPUNIT_ASSERT(s5bPayload); CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), s5bPayload->getSessionID()); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::TCPMode, s5bPayload->getMode()); CPPUNIT_ASSERT_EQUAL(std::string("1a12fb7bc625e55f3ed5b29a53dbe0e4aa7d80ba"), s5bPayload->getDstAddr()); CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasCandidateError()); CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasProxyError()); CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getActivated()); CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getCandidateUsed()); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), s5bPayload->getCandidates().size()); JingleS5BTransportPayload::Candidate candidate; candidate = s5bPayload->getCandidates()[0]; CPPUNIT_ASSERT_EQUAL(std::string("ht567dq"), candidate.cid); CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid); - CPPUNIT_ASSERT(HostAddressPort(HostAddress("192.169.1.10"), 6539) == candidate.hostPort); + CPPUNIT_ASSERT(HostAddressPort(HostAddress::fromString("192.169.1.10").get(), 6539) == candidate.hostPort); CPPUNIT_ASSERT_EQUAL(8257636, candidate.priority); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); candidate = s5bPayload->getCandidates()[1]; CPPUNIT_ASSERT_EQUAL(std::string("hr65dqyd"), candidate.cid); CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid); - CPPUNIT_ASSERT(HostAddressPort(HostAddress("134.102.201.180"), 16453) == candidate.hostPort); + CPPUNIT_ASSERT(HostAddressPort(HostAddress::fromString("134.102.201.180").get(), 16453) == candidate.hostPort); CPPUNIT_ASSERT_EQUAL(7929856, candidate.priority); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::AssistedType, candidate.type); candidate = s5bPayload->getCandidates()[2]; CPPUNIT_ASSERT_EQUAL(std::string("grt654q2"), candidate.cid); CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid); - CPPUNIT_ASSERT(HostAddressPort(HostAddress("2001:638:708:30c9:219:d1ff:fea4:a17d"), 6539) == candidate.hostPort); + CPPUNIT_ASSERT(HostAddressPort(HostAddress::fromString("2001:638:708:30c9:219:d1ff:fea4:a17d").get(), 6539) == candidate.hostPort); CPPUNIT_ASSERT_EQUAL(8257606, candidate.priority); CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type); } }; CPPUNIT_TEST_SUITE_REGISTRATION(JingleParserTest); diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp index 11b0eb5..6982c0c 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp @@ -49,167 +49,167 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { void testConstructor_TwoServersOnSamePort() { BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); } void testStart_Conflict() { BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling->start(); BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling2->onStopped.connect( boost::bind(&BoostConnectionServerTest::handleStopped_, this, _1)); testling->stop(); } void testStop() { BoostConnectionServer::ref testling(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling->start(); testling->stop(); BoostConnectionServer::ref testling2(BoostConnectionServer::create(9999, boostIOServiceThread_->getIOService(), eventLoop_)); testling2->start(); testling2->stop(); } void testIPv4Server() { - BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress("127.0.0.1"), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("127.0.0.1").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); testling->start(); BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); - clientTestling->connect(HostAddressPort(HostAddress("127.0.0.1"), 9999)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 9999)); while (!connectFinished_) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); testling->stop(); } void testIPv6Server() { - BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress("::1"), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("::1").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); testling->start(); BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); - clientTestling->connect(HostAddressPort(HostAddress("::1"), 9999)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("::1").get(), 9999)); while (!connectFinished_) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); testling->stop(); } void testIPv4IPv6DualStackServer() { - BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress("::"), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("::").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); testling->start(); // Test IPv4. BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); - clientTestling->connect(HostAddressPort(HostAddress("127.0.0.1"), 9999)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 9999)); while (!connectFinished_) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); receivedNewConnection_ = false; connectFinished_ = false; // Test IPv6. clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); - clientTestling->connect(HostAddressPort(HostAddress("::1"), 9999)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("::1").get(), 9999)); while (!connectFinished_) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); testling->stop(); } void testIPv6DualStackServerPeerAddress() { - BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress("::"), 9999, boostIOServiceThread_->getIOService(), eventLoop_); + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress::fromString("::").get(), 9999, boostIOServiceThread_->getIOService(), eventLoop_); testling->onNewConnection.connect(boost::bind(&BoostConnectionServerTest::handleNewConnection, this, _1)); testling->start(); // Test IPv4. BoostConnection::ref clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); - clientTestling->connect(HostAddressPort(HostAddress("127.0.0.1"), 9999)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("127.0.0.1").get(), 9999)); while (!connectFinished_) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); // The IPv4 localhost mapped to a IPv6 address is expected here. - CPPUNIT_ASSERT(HostAddress("::ffff:127.0.0.1") == remoteAddress_.get().getAddress()); + CPPUNIT_ASSERT(HostAddress::fromString("::ffff:127.0.0.1").get() == remoteAddress_.get().getAddress()); receivedNewConnection_ = false; connectFinished_ = false; remoteAddress_ = boost::optional<HostAddressPort>(); // Test IPv6. clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); - clientTestling->connect(HostAddressPort(HostAddress("::1"), 9999)); + clientTestling->connect(HostAddressPort(HostAddress::fromString("::1").get(), 9999)); while (!connectFinished_) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(true, receivedNewConnection_); // The IPv6 local host is expected here. - CPPUNIT_ASSERT(HostAddress("::1") == remoteAddress_.get().getAddress()); + CPPUNIT_ASSERT(HostAddress::fromString("::1").get() == remoteAddress_.get().getAddress()); testling->stop(); } void handleStopped_(boost::optional<BoostConnectionServer::Error> e) { stopped_ = true; stoppedError_ = e; } void handleNewConnection(std::shared_ptr<Connection> connection) { receivedNewConnection_ = true; remoteAddress_ = connection->getRemoteAddress(); } void handleConnectFinished(bool /*error*/) { connectFinished_ = true; } private: BoostIOServiceThread* boostIOServiceThread_; DummyEventLoop* eventLoop_; bool stopped_; bool receivedNewConnection_; bool connectFinished_; boost::optional<BoostConnectionServer::Error> stoppedError_; boost::optional<HostAddressPort> remoteAddress_; }; CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionServerTest); diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp index 12c4a77..e0890bf 100755 --- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp @@ -26,118 +26,129 @@ class BoostConnectionTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(BoostConnectionTest); CPPUNIT_TEST(testDestructor); CPPUNIT_TEST(testDestructor_PendingEvents); CPPUNIT_TEST(testWrite); CPPUNIT_TEST(testWriteMultipleSimultaniouslyQueuesWrites); #ifdef TEST_IPV6 CPPUNIT_TEST(testWrite_IPv6); #endif CPPUNIT_TEST_SUITE_END(); public: void setUp() { eventLoop_ = new DummyEventLoop(); boostIOServiceThread_ = new BoostIOServiceThread(); boostIOService_ = std::make_shared<boost::asio::io_service>(); disconnected_ = false; connectFinished_ = false; } void tearDown() { delete boostIOServiceThread_; while (eventLoop_->hasEvents()) { eventLoop_->processEvents(); } delete eventLoop_; } void testDestructor() { { BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); - testling->connect(HostAddressPort(HostAddress(getenv("SWIFT_NETWORK_TEST_IPV4")), 5222)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); } } void testDestructor_PendingEvents() { { BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); - testling->connect(HostAddressPort(HostAddress(getenv("SWIFT_NETWORK_TEST_IPV4")), 5222)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); while (!eventLoop_->hasEvents()) { Swift::sleep(10); } } eventLoop_->processEvents(); } void testWrite() { using namespace boost::posix_time; BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); - testling->connect(HostAddressPort(HostAddress(getenv("SWIFT_NETWORK_TEST_IPV4")), 5222)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); boost::posix_time::ptime start = second_clock::local_time(); while (receivedData_.empty() && ((second_clock::local_time() - start) < seconds(60))) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(false, receivedData_.empty()); testling->disconnect(); } void testWrite_IPv6() { using namespace boost::posix_time; BoostConnection::ref testling(BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_)); testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::doWrite, this, testling.get())); testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); - testling->connect(HostAddressPort(HostAddress(getenv("SWIFT_NETWORK_TEST_IPV6")), 5222)); + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV6")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); boost::posix_time::ptime start = second_clock::local_time(); while (receivedData_.empty() && ((second_clock::local_time() - start) < seconds(60))) { Swift::sleep(10); eventLoop_->processEvents(); } CPPUNIT_ASSERT_EQUAL(false, receivedData_.empty()); testling->disconnect(); } void testWriteMultipleSimultaniouslyQueuesWrites() { BoostConnection::ref testling(BoostConnection::create(boostIOService_, eventLoop_)); testling->onConnectFinished.connect(boost::bind(&BoostConnectionTest::handleConnectFinished, this)); testling->onDataRead.connect(boost::bind(&BoostConnectionTest::handleDataRead, this, _1)); testling->onDisconnected.connect(boost::bind(&BoostConnectionTest::handleDisconnected, this)); - testling->connect(HostAddressPort(HostAddress(getenv("SWIFT_NETWORK_TEST_IPV4")), 5222)); + + auto hostAddress = HostAddress::fromString(getenv("SWIFT_NETWORK_TEST_IPV4")); + CPPUNIT_ASSERT_EQUAL(true, hostAddress.is_initialized()); + testling->connect(HostAddressPort(hostAddress.get(), 5222)); while (!connectFinished_) { boostIOService_->run_one(); eventLoop_->processEvents(); } testling->write(createSafeByteArray("<stream:strea")); testling->write(createSafeByteArray("m")); testling->write(createSafeByteArray(">")); // Check that we only did one write event, the others are queued /*int runHandlers = */boostIOService_->poll(); // Disabling this test, because poll runns all handlers that are added during poll() as well, so // this test doesn't really work any more. We'll have to trust that things are queued. //CPPUNIT_ASSERT_EQUAL(1, runHandlers); // Process the other events while (receivedData_.empty()) { boostIOService_->run_one(); eventLoop_->processEvents(); } // Disconnect & clean up testling->disconnect(); while (!disconnected_) { boostIOService_->run_one(); eventLoop_->processEvents(); } } void doWrite(BoostConnection* connection) { connection->write(createSafeByteArray("<stream:stream>")); diff --git a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp index d45d118..95ebb6d 100644 --- a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp +++ b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp @@ -115,61 +115,61 @@ class DomainNameResolverTest : public CppUnit::TestFixture { void testResolveAddress_IPv4and6() { std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("xmpp-ipv46.test.swift.im")); query->run(); waitForResults(); CPPUNIT_ASSERT(!addressQueryError); CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(addressQueryResult.size())); CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.7"), addressQueryResult[0].toString()); CPPUNIT_ASSERT_EQUAL(std::string("1234:5678:9abc:def0:fed:cba9:8765:4321"), addressQueryResult[1].toString()); } void testResolveAddress_International() { std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("tron\xc3\xa7on.test.swift.im")); query->run(); waitForResults(); CPPUNIT_ASSERT(!addressQueryError); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addressQueryResult.size())); CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), addressQueryResult[0].toString()); } void testResolveAddress_Localhost() { std::shared_ptr<DomainNameAddressQuery> query(createAddressQuery("localhost")); query->run(); waitForResults(); CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT(std::find(addressQueryResult.begin(), addressQueryResult.end(), HostAddress("127.0.0.1")) != addressQueryResult.end()); + CPPUNIT_ASSERT(std::find(addressQueryResult.begin(), addressQueryResult.end(), HostAddress::fromString("127.0.0.1").get()) != addressQueryResult.end()); } void testResolveAddress_Parallel() { std::vector<DomainNameAddressQuery::ref> queries; static const size_t numQueries = 100; for (size_t i = 0; i < numQueries; ++i) { DomainNameAddressQuery::ref query(createAddressQuery("xmpp.test.swift.im")); queries.push_back(query); query->run(); } eventLoop->processEvents(); int ticks = 0; while (allAddressQueryResults.size() < numQueries) { ticks++; if (ticks > 1000) { CPPUNIT_ASSERT(false); } Swift::sleep(10); eventLoop->processEvents(); } CPPUNIT_ASSERT_EQUAL(numQueries, allAddressQueryResults.size()); for (size_t i = 0; i < numQueries; ++i) { CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), allAddressQueryResults[i].toString()); } } void testResolveService() { std::shared_ptr<DomainNameServiceQuery> query(createServiceQuery("_xmpp-client._tcp.", "xmpp-srv.test.swift.im")); diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp index 00d79b3..c259cce 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp @@ -352,57 +352,57 @@ class JingleSerializersTest : public CppUnit::TestFixture { " jid=\"romeo@montague.lit/orchard\"" " port=\"5086\"" " priority=\"8257636\"" " type=\"direct\"/>" "<candidate cid=\"hutr46fe\"" " host=\"24.24.24.1\"" " jid=\"romeo@montague.lit/orchard\"" " port=\"5087\"" " priority=\"8258636\"" " type=\"direct\"/>" "</transport>" "</content>" "</jingle>"; JinglePayload::ref payload = std::make_shared<JinglePayload>(); payload->setAction(JinglePayload::SessionInitiate); payload->setInitiator(JID("romeo@montague.lit/orchard")); payload->setSessionID("a73sjjvkla37jfea"); JingleContentPayload::ref content = std::make_shared<JingleContentPayload>(); content->setCreator(JingleContentPayload::InitiatorCreator); content->setName("ex"); JingleS5BTransportPayload::ref transport = std::make_shared<JingleS5BTransportPayload>(); transport->setMode(JingleS5BTransportPayload::TCPMode); transport->setDstAddr("1a12fb7bc625e55f3ed5b29a53dbe0e4aa7d80ba"); transport->setSessionID("vj3hs98y"); JingleS5BTransportPayload::Candidate candidate1; candidate1.cid = "hft54dqy"; - candidate1.hostPort = HostAddressPort(HostAddress("192.168.4.1"), 5086); + candidate1.hostPort = HostAddressPort(HostAddress::fromString("192.168.4.1").get(), 5086); candidate1.jid = JID("romeo@montague.lit/orchard"); candidate1.priority = 8257636; candidate1.type = JingleS5BTransportPayload::Candidate::DirectType; transport->addCandidate(candidate1); JingleS5BTransportPayload::Candidate candidate2; candidate2.cid = "hutr46fe"; - candidate2.hostPort = HostAddressPort(HostAddress("24.24.24.1"), 5087); + candidate2.hostPort = HostAddressPort(HostAddress::fromString("24.24.24.1").get(), 5087); candidate2.jid = JID("romeo@montague.lit/orchard"); candidate2.priority = 8258636; candidate2.type = JingleS5BTransportPayload::Candidate::DirectType; transport->addCandidate(candidate2); content->addTransport(transport); payload->addPayload(content); CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); } private: FullPayloadSerializerCollection collection; }; CPPUNIT_TEST_SUITE_REGISTRATION(JingleSerializersTest); |