From e314293415c9691bb98188b514f6b13e33994d86 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Sun, 10 Jan 2016 00:44:03 +0100
Subject: Fix IPv6 DNS resolution issues on Windows

Use values instead of define names for _WIN32_WINNT and
NTDDI_VERSION defined needed for Windows.h configuration.
Using the names boost fails to correctly detect getaddrinfo()
support on Windows.

Only run IPv6 related test cases in DomainNameResolverTest on
Windows, if test_ipv6=1 is passed to the scons arguments.

This is because on Windows getaddrinfo() will not return
IPv6 related results when called with the AF_UNSPEC hint,
unless the Windows host has global IPv6 connectivity.

Changed the BoostConnectionTest to time out and not endlessly
wait on a response from the remote host.

Test-Information:

Ran the following test configurations:

* (SUCCESS) On Windows 8 with HE.net IPv6 tunnel to provide
  full IPv6 connectiviy:
  scons.bat test=system test_ipv6=1 Swiften/QA/NetworkTest

* (SUCCESS) On Windows 8 with HE.net IPv6 tunnel to provide
  full IPv6 connectiviy:
  scons.bat test=system Swiften/QA/NetworkTest

* (EXPECTED FAIL) On Windows 8 with no IPv6 connectiviy:
  scons.bat test=system test_ipv6=1 Swiften/QA/NetworkTest

* (SUCCESS) On Windows 8 with no IPv6 connectiviy:
  scons.bat test=system Swiften/QA/NetworkTest

Change-Id: I5adcd28e09e22acf61f7cca40b614e71df75dd70

diff --git a/3rdParty/Boost/SConscript b/3rdParty/Boost/SConscript
index c1eac82..d56f5e3 100644
--- a/3rdParty/Boost/SConscript
+++ b/3rdParty/Boost/SConscript
@@ -40,7 +40,8 @@ elif env.get("BOOST_BUNDLED", False) :
 				"LIBS": ["Swiften_Boost"]
 			}
 		if env["PLATFORM"] == "win32" :
-			env["BOOST_FLAGS"]["CPPDEFINES"] += [("_WIN32_WINNT", "_WIN32_WINNT_VISTA")]
+			# 0x0600 = _WIN32_WINNT_VISTA
+			env["BOOST_FLAGS"]["CPPDEFINES"] += [("_WIN32_WINNT", "0x0600")]
 			if env["PLATFORM"] == "cygwin" :
 				env["BOOST_FLAGS"]["CPPDEFINES"] += ["__USE_W32_SOCKETS"]
 		elif env["PLATFORM"] == "posix" :
diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
old mode 100644
new mode 100755
index 484c5e3..a122686
--- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
+++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
 #include <string>
 
+#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/smart_ptr/make_shared.hpp>
 
@@ -69,28 +70,38 @@ class BoostConnectionTest : public CppUnit::TestFixture {
 		}
 
 		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));
-			while (receivedData_.empty()) {
+			
+			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")), 80));
-			while (receivedData_.empty()) {
+			testling->connect(HostAddressPort(HostAddress(getenv("SWIFT_NETWORK_TEST_IPV6")), 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();
 		}
 
diff --git a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp
index 09e6e66..baa42f9 100644
--- a/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp
+++ b/Swiften/QA/NetworkTest/DomainNameResolverTest.cpp
@@ -1,30 +1,33 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
+#include <algorithm>
+#include <string>
+
+#include <boost/bind.hpp>
+
 #include <cppunit/extensions/HelperMacros.h>
 #include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/bind.hpp>
 
-#include <algorithm>
-#include <Swiften/Base/sleep.h>
-#include <string>
 #include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/Platform.h>
+#include <Swiften/Base/sleep.h>
+#include <Swiften/EventLoop/DummyEventLoop.h>
+#include <Swiften/IDN/IDNConverter.h>
+#include <Swiften/IDN/PlatformIDNConverter.h>
+#include <Swiften/Network/BoostIOServiceThread.h>
+#include <Swiften/Network/BoostTimerFactory.h>
+#include <Swiften/Network/DomainNameAddressQuery.h>
+#include <Swiften/Network/DomainNameServiceQuery.h>
+#include <Swiften/Network/NetworkFactories.h>
 #ifdef USE_UNBOUND
 #include <Swiften/Network/UnboundDomainNameResolver.h>
 #else
 #include <Swiften/Network/PlatformDomainNameResolver.h>
 #endif
-#include <Swiften/Network/BoostTimerFactory.h>
-#include <Swiften/Network/NetworkFactories.h>
-#include <Swiften/Network/BoostIOServiceThread.h>
-#include <Swiften/Network/DomainNameAddressQuery.h>
-#include <Swiften/Network/DomainNameServiceQuery.h>
-#include <Swiften/EventLoop/DummyEventLoop.h>
-#include <Swiften/IDN/IDNConverter.h>
-#include <Swiften/IDN/PlatformIDNConverter.h>
 
 using namespace Swift;
 
@@ -39,8 +42,17 @@ class DomainNameResolverTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST(testResolveAddress);
 		CPPUNIT_TEST(testResolveAddress_Error);
 #ifndef USE_UNBOUND
+		/**
+		 * The native DNS resolver of Windows behaves oddly if the system has no global IPv6
+		 * routed address and no IPv6 reachability. It will not return IPv6 records from DNS 
+		 * requests for an unspecified protocol (IPv6 or IPv4).
+		 * The following tests are only enabled on Windows if scons is run with the 'test_ipv6=1'
+		 * argument, indicating working IPv6 on the test machine.
+		 */
+#if !defined(SWIFTEN_PLATFORM_WINDOWS) || defined(TEST_IPV6)
 		CPPUNIT_TEST(testResolveAddress_IPv6);
 		CPPUNIT_TEST(testResolveAddress_IPv4and6);
+#endif
 		CPPUNIT_TEST(testResolveAddress_International);
 #endif
 		CPPUNIT_TEST(testResolveAddress_Localhost);
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 97dc39c..e017376 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -77,7 +77,8 @@ if env["SCONS_STAGE"] == "flags" :
 			}
 
 	if env["PLATFORM"] == "win32" :
-		env.Append(CPPDEFINES = [("_WIN32_WINNT","_WIN32_WINNT_VISTA") , ("NTDDI_VERSION","NTDDI_VISTA")])
+		# 0x0600 = _WIN32_WINNT_VISTA, 0x06000000 = NTDDI_VISTA
+		env.Append(CPPDEFINES = [("_WIN32_WINNT","0x0600") , ("NTDDI_VERSION","0x06000000")])
 
 ################################################################################
 # Build
-- 
cgit v0.10.2-6-g49f6