From 13801557b6664426cac26384441ab0b19ff9abb5 Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Wed, 9 Dec 2015 16:24:23 +0100 Subject: Listen to IPv6 any address instead of only IPv4 This should enable IPv4/IPv6 dual-stack support for Swift(-en) Jingle file-transfer support. Add Connection::getRemoteAddress() method. Test-Information: Tested IPv6 file-transfer and IPv4 file-transfer between two Swift instances. Added integration test verifying IPv4 only, IPv6 only and IPv4/IPv6 dual-stack support on the running platform. Additionally added test to verify remote addresses on dual-stack server. Change-Id: Ie384a71833eacca554f69e6f12a1c8330d0d747f diff --git a/Swiften/Component/UnitTest/ComponentConnectorTest.cpp b/Swiften/Component/UnitTest/ComponentConnectorTest.cpp index 94da1b1..3968c2c 100644 --- a/Swiften/Component/UnitTest/ComponentConnectorTest.cpp +++ b/Swiften/Component/UnitTest/ComponentConnectorTest.cpp @@ -1,22 +1,22 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ +#include +#include + #include #include -#include -#include - #include +#include #include #include +#include #include #include -#include -#include using namespace Swift; @@ -176,6 +176,7 @@ class ComponentConnectorTest : public CppUnit::TestFixture { void disconnect() { assert(false); } void write(const SafeByteArray&) { assert(false); } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } EventLoop* eventLoop; boost::optional hostAddressPort; diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp index f531856..7b97698 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp @@ -117,7 +117,7 @@ void SOCKS5BytestreamServerManager::initialize() { 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("0.0.0.0"), port); + connectionServer = connectionServerFactory->createConnectionServer(HostAddress("::"), port); boost::optional error = connectionServer->tryStart(); if (!error) { break; diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp index 78ea8ed..a0f6033 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp @@ -4,11 +4,11 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ -#include -#include - -#include -#include +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ #include #include @@ -16,11 +16,18 @@ #include #include +#include + +#include +#include + #include #include #include #include #include +#include +#include #include #include #include @@ -30,8 +37,6 @@ #include #include #include -#include -#include using namespace Swift; @@ -278,6 +283,9 @@ private: } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } + void disconnect() { disconnectCalled = true; } diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp index 6e90815..f495795 100644 --- a/Swiften/Network/BoostConnection.cpp +++ b/Swiften/Network/BoostConnection.cpp @@ -1,28 +1,29 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include +#include #include #include -#include -#include -#include + #include #include -#include +#include #include +#include +#include -#include #include -#include #include -#include -#include +#include #include +#include +#include +#include namespace Swift { @@ -169,5 +170,9 @@ HostAddressPort BoostConnection::getLocalAddress() const { return HostAddressPort(socket_.local_endpoint()); } +HostAddressPort BoostConnection::getRemoteAddress() const { + return HostAddressPort(socket_.remote_endpoint()); +} + } diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h index 8e89263..f933cd8 100644 --- a/Swiften/Network/BoostConnection.h +++ b/Swiften/Network/BoostConnection.h @@ -48,7 +48,8 @@ namespace Swift { return socket_; } - HostAddressPort getLocalAddress() const; + virtual HostAddressPort getLocalAddress() const; + virtual HostAddressPort getRemoteAddress() const; bool setClientCertificate(CertificateWithKey::ref cert); diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp index 2a4a51b..48b323d 100644 --- a/Swiften/Network/BoostConnectionServer.cpp +++ b/Swiften/Network/BoostConnectionServer.cpp @@ -1,17 +1,20 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include -#include -#include +#include #include +#include #include #include +#include +#include +#include #include namespace Swift { @@ -32,15 +35,18 @@ void BoostConnectionServer::start() { boost::optional BoostConnectionServer::tryStart() { try { assert(!acceptor_); + boost::asio::ip::tcp::endpoint endpoint; if (address_.isValid()) { - acceptor_ = new boost::asio::ip::tcp::acceptor( - *ioService_, - boost::asio::ip::tcp::endpoint(address_.getRawAddress(), boost::numeric_cast(port_))); + endpoint = boost::asio::ip::tcp::endpoint(address_.getRawAddress(), boost::numeric_cast(port_)); } else { - acceptor_ = new boost::asio::ip::tcp::acceptor( - *ioService_, - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), boost::numeric_cast(port_))); + endpoint = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), boost::numeric_cast(port_)); + } + acceptor_ = new boost::asio::ip::tcp::acceptor(*ioService_, endpoint); + if (endpoint.protocol() == boost::asio::ip::tcp::v6()) { + boost::system::error_code ec; + acceptor_->set_option(boost::asio::ip::v6_only(false), ec); + SWIFT_LOG_ASSERT(ec, warning) << "IPv4/IPv6 dual-stack support is not supported on this platform." << std::endl; } acceptNextConnection(); } diff --git a/Swiften/Network/Connection.h b/Swiften/Network/Connection.h index 91fc40d..39b63d4 100644 --- a/Swiften/Network/Connection.h +++ b/Swiften/Network/Connection.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -7,10 +7,10 @@ #pragma once #include -#include #include #include +#include namespace Swift { class HostAddressPort; @@ -33,6 +33,7 @@ namespace Swift { virtual void write(const SafeByteArray& data) = 0; virtual HostAddressPort getLocalAddress() const = 0; + virtual HostAddressPort getRemoteAddress() const = 0; public: boost::signal onConnectFinished; diff --git a/Swiften/Network/DummyConnection.h b/Swiften/Network/DummyConnection.h index ef99c32..edc2473 100644 --- a/Swiften/Network/DummyConnection.h +++ b/Swiften/Network/DummyConnection.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -9,10 +9,10 @@ #include #include -#include -#include #include #include +#include +#include namespace Swift { class SWIFTEN_API DummyConnection : public Connection, public EventOwner, public boost::enable_shared_from_this { @@ -37,9 +37,14 @@ namespace Swift { return localAddress; } + HostAddressPort getRemoteAddress() const { + return remoteAddress; + } + boost::signal onDataSent; EventLoop* eventLoop; HostAddressPort localAddress; + HostAddressPort remoteAddress; }; } diff --git a/Swiften/Network/FakeConnection.h b/Swiften/Network/FakeConnection.h index 33a7fd9..ec62ad7 100644 --- a/Swiften/Network/FakeConnection.h +++ b/Swiften/Network/FakeConnection.h @@ -1,20 +1,21 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include -#include #include +#include +#include + #include +#include +#include #include #include -#include -#include namespace Swift { class SWIFTEN_API FakeConnection : @@ -31,12 +32,15 @@ namespace Swift { }; FakeConnection(EventLoop* eventLoop); - ~FakeConnection(); + virtual ~FakeConnection(); virtual void listen(); virtual HostAddressPort getLocalAddress() const { return HostAddressPort(); } + virtual HostAddressPort getRemoteAddress() const { + return HostAddressPort(); + } void setError(const Error& e); virtual void connect(const HostAddressPort& address); diff --git a/Swiften/Network/ProxiedConnection.cpp b/Swiften/Network/ProxiedConnection.cpp index 17f7e09..c44c1f5 100644 --- a/Swiften/Network/ProxiedConnection.cpp +++ b/Swiften/Network/ProxiedConnection.cpp @@ -104,6 +104,10 @@ HostAddressPort ProxiedConnection::getLocalAddress() const { return connection_->getLocalAddress(); } +HostAddressPort ProxiedConnection::getRemoteAddress() const { + return connection_->getRemoteAddress(); +} + void ProxiedConnection::setProxyInitializeFinished(bool success) { connected_ = success; if (!success) { diff --git a/Swiften/Network/ProxiedConnection.h b/Swiften/Network/ProxiedConnection.h index f301e84..f03c7ae 100644 --- a/Swiften/Network/ProxiedConnection.h +++ b/Swiften/Network/ProxiedConnection.h @@ -36,6 +36,7 @@ namespace Swift { virtual void write(const SafeByteArray& data); virtual HostAddressPort getLocalAddress() const; + virtual HostAddressPort getRemoteAddress() const; private: void handleConnectFinished(Connection::ref connection); diff --git a/Swiften/Network/TLSConnection.cpp b/Swiften/Network/TLSConnection.cpp index c69547d..c7087ae 100644 --- a/Swiften/Network/TLSConnection.cpp +++ b/Swiften/Network/TLSConnection.cpp @@ -66,6 +66,10 @@ HostAddressPort TLSConnection::getLocalAddress() const { return connection->getLocalAddress(); } +HostAddressPort TLSConnection::getRemoteAddress() const { + return connection->getRemoteAddress(); +} + TLSContext* TLSConnection::getTLSContext() const { return context; } diff --git a/Swiften/Network/TLSConnection.h b/Swiften/Network/TLSConnection.h index a037eb1..b3acffc 100644 --- a/Swiften/Network/TLSConnection.h +++ b/Swiften/Network/TLSConnection.h @@ -32,6 +32,7 @@ namespace Swift { virtual void write(const SafeByteArray& data); virtual HostAddressPort getLocalAddress() const; + virtual HostAddressPort getRemoteAddress() const; TLSContext* getTLSContext() const; diff --git a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp index 83ad548..e8d8c4a 100644 --- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp +++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp @@ -381,6 +381,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture { } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } void disconnect() { disconnected = true; diff --git a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp index 349c282..8d26a09 100644 --- a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp +++ b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp @@ -236,6 +236,7 @@ class BOSHConnectionTest : public CppUnit::TestFixture { } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } void disconnect() { disconnected = true; diff --git a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp index 1fc19ba..3bafbf1 100644 --- a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp +++ b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp @@ -1,23 +1,23 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include -#include - #include #include +#include +#include + +#include #include #include #include +#include +#include #include #include -#include -#include -#include using namespace Swift; @@ -151,6 +151,7 @@ class ChainedConnectorTest : public CppUnit::TestFixture { } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } void disconnect() { assert(false); } void write(const SafeByteArray&) { assert(false); } diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp index 161b114..a091074 100644 --- a/Swiften/Network/UnitTest/ConnectorTest.cpp +++ b/Swiften/Network/UnitTest/ConnectorTest.cpp @@ -1,23 +1,23 @@ /* - * Copyright (c) 2010-2014 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ +#include +#include + #include #include -#include -#include - -#include +#include #include #include +#include +#include +#include #include #include -#include -#include -#include using namespace Swift; @@ -341,6 +341,7 @@ class ConnectorTest : public CppUnit::TestFixture { } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } void disconnect() { assert(false); } void write(const SafeByteArray&) { assert(false); } diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp index 56ace5c..1d01214 100644 --- a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp +++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp @@ -386,6 +386,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture { } HostAddressPort getLocalAddress() const { return HostAddressPort(); } + HostAddressPort getRemoteAddress() const { return HostAddressPort(); } void disconnect() { disconnected = true; diff --git a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp index abe2f05..67b4bfa 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionServerTest.cpp @@ -26,6 +26,7 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { CPPUNIT_TEST(testIPv4Server); CPPUNIT_TEST(testIPv6Server); CPPUNIT_TEST(testIPv4IPv6DualStackServer); + CPPUNIT_TEST(testIPv6DualStackServerPeerAddress); CPPUNIT_TEST_SUITE_END(); public: @@ -36,6 +37,7 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { stoppedError_.reset(); receivedNewConnection_ = false; connectFinished_ = false; + remoteAddress_ = boost::optional(); } void tearDown() { @@ -147,13 +149,54 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { testling->stop(); } + void testIPv6DualStackServerPeerAddress() { + BoostConnectionServer::ref testling = BoostConnectionServer::create(HostAddress("::"), 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)); + + 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()); + + receivedNewConnection_ = false; + connectFinished_ = false; + remoteAddress_ = boost::optional(); + + // Test IPv6. + clientTestling = BoostConnection::create(boostIOServiceThread_->getIOService(), eventLoop_); + clientTestling->onConnectFinished.connect(boost::bind(&BoostConnectionServerTest::handleConnectFinished, this, _1)); + clientTestling->connect(HostAddressPort(HostAddress("::1"), 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()); + + testling->stop(); + } + void handleStopped_(boost::optional e) { stopped_ = true; stoppedError_ = e; } - void handleNewConnection(boost::shared_ptr /*connection*/) { + void handleNewConnection(boost::shared_ptr connection) { receivedNewConnection_ = true; + remoteAddress_ = connection->getRemoteAddress(); } void handleConnectFinished(bool /*error*/) { @@ -167,6 +210,7 @@ class BoostConnectionServerTest : public CppUnit::TestFixture { bool receivedNewConnection_; bool connectFinished_; boost::optional stoppedError_; + boost::optional remoteAddress_; }; CPPUNIT_TEST_SUITE_REGISTRATION(BoostConnectionServerTest); -- cgit v0.10.2-6-g49f6