From 725c4e1ad0710606421f9705d994688116a9fc1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Mon, 5 Apr 2010 14:10:17 +0200 Subject: Refactored DomainNameAddressQuery. Result can now consist of multiple addresses. diff --git a/Swiften/Network/CAresDomainNameResolver.cpp b/Swiften/Network/CAresDomainNameResolver.cpp index c0bf8a0..bf860f2 100644 --- a/Swiften/Network/CAresDomainNameResolver.cpp +++ b/Swiften/Network/CAresDomainNameResolver.cpp @@ -95,16 +95,19 @@ class CAresDomainNameAddressQuery : public DomainNameAddressQuery, public CAresQ // Check whether the different fields are what we expect them to be struct in_addr addr; addr.s_addr = *(unsigned int*)hosts->h_addr_list[0]; - HostAddress result(inet_ntoa(addr)); - MainEventLoop::postEvent(boost::bind(boost::ref(onResult), result, boost::optional()), boost::dynamic_pointer_cast(shared_from_this())); + + std::vector results; + results.push_back(HostAddress(inet_ntoa(addr))); + + MainEventLoop::postEvent(boost::bind(boost::ref(onResult), results, boost::optional()), boost::dynamic_pointer_cast(shared_from_this())); ares_free_hostent(hosts); } else { - MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional(DomainNameResolveError())), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector(), boost::optional(DomainNameResolveError())), shared_from_this()); } } else if (status != ARES_EDESTRUCTION) { - MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional(DomainNameResolveError())), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector(), boost::optional(DomainNameResolveError())), shared_from_this()); } } }; diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp index d372bf2..ff45481 100644 --- a/Swiften/Network/Connector.cpp +++ b/Swiften/Network/Connector.cpp @@ -64,22 +64,22 @@ void Connector::tryNextHostname() { } } -void Connector::handleAddressQueryResult(const HostAddress& address, boost::optional error) { +void Connector::handleAddressQueryResult(const std::vector& addresses, boost::optional error) { //std::cout << "Connector::handleAddressQueryResult(): Start" << std::endl; addressQuery.reset(); if (!serviceQueryResults.empty()) { DomainNameServiceQuery::Result serviceQueryResult = serviceQueryResults.front(); serviceQueryResults.pop_front(); - if (error) { + if (error || addresses.empty()) { //std::cout << "Connector::handleAddressQueryResult(): A lookup for SRV host " << serviceQueryResult.hostname << " failed." << std::endl; tryNextHostname(); } else { //std::cout << "Connector::handleAddressQueryResult(): A lookup for SRV host " << serviceQueryResult.hostname << " succeeded: " << address.toString() << std::endl; - tryConnect(HostAddressPort(address, serviceQueryResult.port)); + tryConnect(HostAddressPort(addresses[0], serviceQueryResult.port)); } } - else if (error) { + else if (error || addresses.empty()) { //std::cout << "Connector::handleAddressQueryResult(): Fallback address query failed. Giving up" << std::endl; // The fallback address query failed assert(queriedAllHosts); @@ -88,7 +88,7 @@ void Connector::handleAddressQueryResult(const HostAddress& address, boost::opti else { //std::cout << "Connector::handleAddressQueryResult(): Fallback address query succeeded: " << address.toString() << std::endl; // The fallback query succeeded - tryConnect(HostAddressPort(address, 5222)); + tryConnect(HostAddressPort(addresses[0], 5222)); } } diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h index 507f085..32dd9ab 100644 --- a/Swiften/Network/Connector.h +++ b/Swiften/Network/Connector.h @@ -28,7 +28,7 @@ namespace Swift { private: void handleServiceQueryResult(const std::vector& result); - void handleAddressQueryResult(const HostAddress& address, boost::optional error); + void handleAddressQueryResult(const std::vector& address, boost::optional error); void queryAddress(const String& hostname); void tryNextHostname(); diff --git a/Swiften/Network/DomainNameAddressQuery.h b/Swiften/Network/DomainNameAddressQuery.h index 66a79db..53d0abf 100644 --- a/Swiften/Network/DomainNameAddressQuery.h +++ b/Swiften/Network/DomainNameAddressQuery.h @@ -14,6 +14,6 @@ namespace Swift { virtual void run() = 0; - boost::signal)> onResult; + boost::signal&, boost::optional)> onResult; }; } diff --git a/Swiften/Network/PlatformDomainNameResolver.cpp b/Swiften/Network/PlatformDomainNameResolver.cpp index 7b8a6d5..636eac9 100644 --- a/Swiften/Network/PlatformDomainNameResolver.cpp +++ b/Swiften/Network/PlatformDomainNameResolver.cpp @@ -51,11 +51,15 @@ namespace { emitError(); } else { - boost::asio::ip::address address = (*endpointIterator).endpoint().address(); - HostAddress result = (address.is_v4() ? HostAddress(&address.to_v4().to_bytes()[0], 4) : HostAddress(&address.to_v6().to_bytes()[0], 16)); + std::vector results; + for ( ; endpointIterator != boost::asio::ip::tcp::resolver::iterator(); ++endpointIterator) { + boost::asio::ip::address address = (*endpointIterator).endpoint().address(); + results.push_back(address.is_v4() ? HostAddress(&address.to_v4().to_bytes()[0], 4) : HostAddress(&address.to_v6().to_bytes()[0], 16)); + } + //std::cout << "PlatformDomainNameResolver::doRun(): Success" << std::endl; MainEventLoop::postEvent( - boost::bind(boost::ref(onResult), result, boost::optional()), + boost::bind(boost::ref(onResult), results, boost::optional()), shared_from_this()); } } @@ -67,7 +71,7 @@ namespace { } void emitError() { - MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional(DomainNameResolveError())), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector(), boost::optional(DomainNameResolveError())), shared_from_this()); } boost::asio::io_service ioService; diff --git a/Swiften/Network/StaticDomainNameResolver.cpp b/Swiften/Network/StaticDomainNameResolver.cpp index a7275d2..a751fdd 100644 --- a/Swiften/Network/StaticDomainNameResolver.cpp +++ b/Swiften/Network/StaticDomainNameResolver.cpp @@ -38,11 +38,13 @@ namespace { } StaticDomainNameResolver::AddressesMap::const_iterator i = resolver->getAddresses().find(host); if (i != resolver->getAddresses().end()) { + std::vector result; + result.push_back(i->second); MainEventLoop::postEvent( - boost::bind(boost::ref(onResult), i->second, boost::optional())); + boost::bind(boost::ref(onResult), result, boost::optional())); } else { - MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional(DomainNameResolveError()))); + MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector(), boost::optional(DomainNameResolveError()))); } } diff --git a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp index 09837d6..ec9d555 100644 --- a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp +++ b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp @@ -16,7 +16,8 @@ class DomainNameResolverTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(DomainNameResolverTest); CPPUNIT_TEST(testResolveAddress); CPPUNIT_TEST(testResolveAddress_Error); - //CPPUNIT_TEST(testResolveAddress_IPv6); + CPPUNIT_TEST(testResolveAddress_IPv6); + CPPUNIT_TEST(testResolveAddress_IPv4and6); CPPUNIT_TEST(testResolveAddress_International); CPPUNIT_TEST(testResolveAddress_Localhost); CPPUNIT_TEST(testResolveService); @@ -44,7 +45,8 @@ class DomainNameResolverTest : public CppUnit::TestFixture { waitForResults(); CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), addressQueryResult.toString()); + CPPUNIT_ASSERT_EQUAL(1, static_cast(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.0"), addressQueryResult[0].toString()); } void testResolveAddress_Error() { @@ -63,7 +65,19 @@ class DomainNameResolverTest : public CppUnit::TestFixture { waitForResults(); CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(std::string("0000:0000:0000:0000:0000:ffff:0a00:0104"), addressQueryResult.toString()); + CPPUNIT_ASSERT_EQUAL(std::string("0000:0000:0000:0000:0000:ffff:0a00:0104"), addressQueryResult[0].toString()); + } + + void testResolveAddress_IPv4and6() { + boost::shared_ptr query(createAddressQuery("xmpp-ipv46.test.swift.im")); + + query->run(); + waitForResults(); + + CPPUNIT_ASSERT(!addressQueryError); + CPPUNIT_ASSERT_EQUAL(2, static_cast(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("1234:5678:9abc:def0:0fed:cba9:8765:4321"), addressQueryResult[0].toString()); + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.7"), addressQueryResult[1].toString()); } void testResolveAddress_International() { @@ -73,7 +87,8 @@ class DomainNameResolverTest : public CppUnit::TestFixture { waitForResults(); CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), addressQueryResult.toString()); + CPPUNIT_ASSERT_EQUAL(1, static_cast(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("10.0.0.3"), addressQueryResult[0].toString()); } void testResolveAddress_Localhost() { @@ -83,7 +98,8 @@ class DomainNameResolverTest : public CppUnit::TestFixture { waitForResults(); CPPUNIT_ASSERT(!addressQueryError); - CPPUNIT_ASSERT_EQUAL(std::string("127.0.0.1"), addressQueryResult.toString()); + CPPUNIT_ASSERT_EQUAL(1, static_cast(addressQueryResult.size())); + CPPUNIT_ASSERT_EQUAL(std::string("127.0.0.1"), addressQueryResult[0].toString()); } @@ -126,8 +142,8 @@ class DomainNameResolverTest : public CppUnit::TestFixture { return result; } - void handleAddressQueryResult(const HostAddress& address, boost::optional error) { - addressQueryResult = address; + void handleAddressQueryResult(const std::vector& addresses, boost::optional error) { + addressQueryResult = addresses; addressQueryError = error; resultsAvailable = true; } @@ -159,7 +175,7 @@ class DomainNameResolverTest : public CppUnit::TestFixture { private: DummyEventLoop* eventLoop; bool resultsAvailable; - HostAddress addressQueryResult; + std::vector addressQueryResult; boost::optional addressQueryError; std::vector serviceQueryResult; PlatformDomainNameResolver* resolver; -- cgit v0.10.2-6-g49f6