summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Network/CAresDomainNameResolver.cpp11
-rw-r--r--Swiften/Network/Connector.cpp10
-rw-r--r--Swiften/Network/Connector.h2
-rw-r--r--Swiften/Network/DomainNameAddressQuery.h2
-rw-r--r--Swiften/Network/PlatformDomainNameResolver.cpp12
-rw-r--r--Swiften/Network/StaticDomainNameResolver.cpp6
-rw-r--r--Swiften/QA/NetworkTest/DomainNameResolverTest.cpp32
7 files changed, 50 insertions, 25 deletions
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<DomainNameResolveError>()), boost::dynamic_pointer_cast<CAresDomainNameAddressQuery>(shared_from_this()));
+
+ std::vector<HostAddress> results;
+ results.push_back(HostAddress(inet_ntoa(addr)));
+
+ MainEventLoop::postEvent(boost::bind(boost::ref(onResult), results, boost::optional<DomainNameResolveError>()), boost::dynamic_pointer_cast<CAresDomainNameAddressQuery>(shared_from_this()));
ares_free_hostent(hosts);
}
else {
- MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), shared_from_this());
+ MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), shared_from_this());
}
}
else if (status != ARES_EDESTRUCTION) {
- MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), shared_from_this());
+ MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(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<DomainNameResolveError> error) {
+void Connector::handleAddressQueryResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> 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<DomainNameServiceQuery::Result>& result);
- void handleAddressQueryResult(const HostAddress& address, boost::optional<DomainNameResolveError> error);
+ void handleAddressQueryResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> 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<void (const HostAddress&, boost::optional<DomainNameResolveError>)> onResult;
+ boost::signal<void (const std::vector<HostAddress>&, boost::optional<DomainNameResolveError>)> 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<HostAddress> 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<DomainNameResolveError>()),
+ boost::bind(boost::ref(onResult), results, boost::optional<DomainNameResolveError>()),
shared_from_this());
}
}
@@ -67,7 +71,7 @@ namespace {
}
void emitError() {
- MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), shared_from_this());
+ MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(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<HostAddress> result;
+ result.push_back(i->second);
MainEventLoop::postEvent(
- boost::bind(boost::ref(onResult), i->second, boost::optional<DomainNameResolveError>()));
+ boost::bind(boost::ref(onResult), result, boost::optional<DomainNameResolveError>()));
}
else {
- MainEventLoop::postEvent(boost::bind(boost::ref(onResult), HostAddress(), boost::optional<DomainNameResolveError>(DomainNameResolveError())));
+ MainEventLoop::postEvent(boost::bind(boost::ref(onResult), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(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<int>(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<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("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<int>(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<int>(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<DomainNameResolveError> error) {
- addressQueryResult = address;
+ void handleAddressQueryResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> 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<HostAddress> addressQueryResult;
boost::optional<DomainNameResolveError> addressQueryError;
std::vector<DomainNameServiceQuery::Result> serviceQueryResult;
PlatformDomainNameResolver* resolver;