From 779f0d57bc9d90300aad0b1386dc937612ac35f4 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Fri, 9 Jan 2015 17:39:11 +0100
Subject: Support domain names in S5B proxy <streamhost> tags.

S5BProxyManager now resolves DNS names of proxy entries discovered via
service discovery.

Test-Information:

Tested against a XMPP installation that uses domain names in proxy entires.

Change-Id: I728243333ec6e62e86f088f2a7b6e222c629757b

diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index d2f8b7a..613249b 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -137,6 +137,7 @@ void Client::handleConnected() {
 			getNetworkFactories()->getConnectionFactory(), 
 			getNetworkFactories()->getConnectionServerFactory(), 
 			getNetworkFactories()->getTimerFactory(), 
+			getNetworkFactories()->getDomainNameResolver(),
 			getNetworkFactories()->getNetworkEnvironment(),
 			getNetworkFactories()->getNATTraverser(),
 			getNetworkFactories()->getCryptoProvider());
diff --git a/Swiften/Elements/S5BProxyRequest.h b/Swiften/Elements/S5BProxyRequest.h
index fcd0cb2..b7541fc 100644
--- a/Swiften/Elements/S5BProxyRequest.h
+++ b/Swiften/Elements/S5BProxyRequest.h
@@ -4,6 +4,12 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
 #pragma once
 
 #include <string>
@@ -22,7 +28,8 @@ public:
 
 public:
 	struct StreamHost {
-		HostAddressPort addressPort;
+		std::string host;
+		int port;
 		JID jid;
 	};
 
diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp
index f439197..ab4cb5c 100644
--- a/Swiften/FileTransfer/FileTransferManagerImpl.cpp
+++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp
@@ -48,6 +48,7 @@ FileTransferManagerImpl::FileTransferManagerImpl(
 		ConnectionFactory* connectionFactory, 
 		ConnectionServerFactory* connectionServerFactory, 
 		TimerFactory* timerFactory, 
+		DomainNameResolver* domainNameResolver,
 		NetworkEnvironment* networkEnvironment,
 		NATTraverser* natTraverser,
 		CryptoProvider* crypto) : 
@@ -60,7 +61,7 @@ FileTransferManagerImpl::FileTransferManagerImpl(
 	bytestreamRegistry = new SOCKS5BytestreamRegistry();
 	s5bServerManager = new SOCKS5BytestreamServerManager(
 			bytestreamRegistry, connectionServerFactory, networkEnvironment, natTraverser);
-	bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory);
+	bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory, domainNameResolver, iqRouter, JID(ownFullJID.getDomain()));
 
 	transporterFactory = new DefaultFileTransferTransporterFactory(
 			bytestreamRegistry,
diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.h b/Swiften/FileTransfer/FileTransferManagerImpl.h
index 678261a..de6e857 100644
--- a/Swiften/FileTransfer/FileTransferManagerImpl.h
+++ b/Swiften/FileTransfer/FileTransferManagerImpl.h
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -33,21 +33,22 @@
 namespace Swift {
 	class ConnectionFactory;
 	class ConnectionServerFactory;
-	class SOCKS5BytestreamServerManager;
+	class CryptoProvider;
+	class DomainNameResolver;
 	class EntityCapsProvider;
+	class FileTransferTransporterFactory;
 	class IQRouter;
 	class IncomingFileTransferManager;
 	class JingleSessionManager;
-	class OutgoingFileTransferManager;
 	class NATTraverser;
+	class NetworkEnvironment;
+	class OutgoingFileTransferManager;
 	class PresenceOracle;
 	class ReadBytestream;
-	class FileTransferTransporterFactory;
-	class SOCKS5BytestreamRegistry;
 	class SOCKS5BytestreamProxiesManager;
+	class SOCKS5BytestreamRegistry;
+	class SOCKS5BytestreamServerManager;
 	class TimerFactory;
-	class CryptoProvider;
-	class NetworkEnvironment;
 
 	class SWIFTEN_API FileTransferManagerImpl : public FileTransferManager {
 		public:
@@ -60,6 +61,7 @@ namespace Swift {
 					ConnectionFactory* connectionFactory,
 					ConnectionServerFactory* connectionServerFactory,
 					TimerFactory* timerFactory, 
+					DomainNameResolver* domainNameResolver,
 					NetworkEnvironment* networkEnvironment,
 					NATTraverser* natTraverser,
 					CryptoProvider* crypto);
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp
index 0b94763..ef0a733 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp
+++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp
@@ -4,69 +4,144 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+
 #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
 
 #include <boost/smart_ptr/make_shared.hpp>
+#include <boost/bind.hpp>
 
 #include <Swiften/Base/foreach.h>
 #include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h>
 #include <Swiften/Base/Log.h>
+#include <Swiften/Network/DomainNameResolver.h>
+#include <Swiften/Network/ConnectionFactory.h>
+#include <Swiften/Network/TimerFactory.h>
+#include <Swiften/Network/DomainNameAddressQuery.h>
+#include <Swiften/Network/DomainNameResolveError.h>
 
 namespace Swift {
 
-SOCKS5BytestreamProxiesManager::SOCKS5BytestreamProxiesManager(ConnectionFactory *connFactory, TimerFactory *timeFactory) : connectionFactory(connFactory), timerFactory(timeFactory) {
+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();
+	}
 }
 
 void SOCKS5BytestreamProxiesManager::addS5BProxy(S5BProxyRequest::ref proxy) {
-	localS5BProxies.push_back(proxy);
+	if (proxy) {
+		SWIFT_LOG_ASSERT(HostAddress(proxy->getStreamHost().get().host).isValid(), warning) << std::endl;
+		if (!localS5BProxies_) {
+			localS5BProxies_ = std::vector<S5BProxyRequest::ref>();
+		}
+		localS5BProxies_->push_back(proxy);
+		onDiscoveredProxiesChanged();
+	}
 }
 
-const std::vector<S5BProxyRequest::ref>& SOCKS5BytestreamProxiesManager::getS5BProxies() const {
-	return localS5BProxies;
+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;
 	ProxyJIDClientSessionMap clientSessions;
 
-	foreach(S5BProxyRequest::ref proxy, localS5BProxies) {
-		boost::shared_ptr<Connection> conn = connectionFactory->createConnection();
+	if (localS5BProxies_) {
+		foreach(S5BProxyRequest::ref proxy, localS5BProxies_.get()) {
+			boost::shared_ptr<Connection> conn = connectionFactory_->createConnection();
 
-		boost::shared_ptr<SOCKS5BytestreamClientSession> session = boost::make_shared<SOCKS5BytestreamClientSession>(conn, proxy->getStreamHost().get().addressPort, sessionID, timerFactory);
-		clientSessions[proxy->getStreamHost().get().jid] = session;
-		session->start();
+			HostAddressPort addressPort = HostAddressPort(proxy->getStreamHost().get().host, proxy->getStreamHost().get().port);
+			SWIFT_LOG_ASSERT(addressPort.isValid(), warning) << std::endl;
+			boost::shared_ptr<SOCKS5BytestreamClientSession> session = boost::make_shared<SOCKS5BytestreamClientSession>(conn, addressPort, sessionID, timerFactory_);
+			clientSessions[proxy->getStreamHost().get().jid] = session;
+			session->start();
+		}
 	}
 
-	proxySessions[sessionID] = clientSessions;
+	proxySessions_[sessionID] = clientSessions;
 }
 
 boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID) {
 	// checking parameters
-	if (proxySessions.find(sessionID) == proxySessions.end()) {
+	if (proxySessions_.find(sessionID) == proxySessions_.end()) {
 		return boost::shared_ptr<SOCKS5BytestreamClientSession>();
 	}
-	if (proxySessions[sessionID].find(proxyJID) == proxySessions[sessionID].end()) {
+	if (proxySessions_[sessionID].find(proxyJID) == proxySessions_[sessionID].end()) {
 		return boost::shared_ptr<SOCKS5BytestreamClientSession>();
 	}
 
 	// get active session
-	boost::shared_ptr<SOCKS5BytestreamClientSession> activeSession = proxySessions[sessionID][proxyJID];
-	proxySessions[sessionID].erase(proxyJID);
+	boost::shared_ptr<SOCKS5BytestreamClientSession> activeSession = proxySessions_[sessionID][proxyJID];
+	proxySessions_[sessionID].erase(proxyJID);
 
 	// close other sessions
-	foreach(const ProxyJIDClientSessionMap::value_type& myPair, proxySessions[sessionID]) {
+	foreach(const ProxyJIDClientSessionMap::value_type& myPair, proxySessions_[sessionID]) {
 		myPair.second->stop();
 	}
 
-	proxySessions.erase(sessionID);
+	proxySessions_.erase(sessionID);
 
 	return activeSession;
 }
 
 boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr) {
-	SOCKS5BytestreamClientSession::ref connection = boost::make_shared<SOCKS5BytestreamClientSession>(connectionFactory->createConnection(), addressPort, destAddr, timerFactory);
+	SOCKS5BytestreamClientSession::ref connection = boost::make_shared<SOCKS5BytestreamClientSession>(connectionFactory_->createConnection(), addressPort, destAddr, timerFactory_);
 	return connection;
 }
 
+void SOCKS5BytestreamProxiesManager::handleProxyFound(S5BProxyRequest::ref proxy) {
+	if (proxy) {
+		if (HostAddress(proxy->getStreamHost().get().host).isValid()) {
+			addS5BProxy(proxy);
+		}
+		else {
+			DomainNameAddressQuery::ref resolveRequest = resolver_->createAddressQuery(proxy->getStreamHost().get().host);
+			resolveRequest->onResult.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleNameLookupResult, this, _1, _2, proxy));
+			resolveRequest->run();
+		}
+	}
+	else {
+		onDiscoveredProxiesChanged();
+	}
+	proxyFinder_->stop();
+}
+
+void SOCKS5BytestreamProxiesManager::handleNameLookupResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error, S5BProxyRequest::ref proxy) {
+	if (error) {
+		onDiscoveredProxiesChanged();
+	}
+	else {
+		if (address.empty()) {
+			SWIFT_LOG(warning) << "S5B proxy hostname does not resolve." << std::endl;
+			onDiscoveredProxiesChanged();
+		}
+		else {
+			S5BProxyRequest::StreamHost streamHost = proxy->getStreamHost().get();
+			streamHost.host = address[0].toString();
+			proxy->setStreamHost(streamHost);
+			addS5BProxy(proxy);
+		}
+	}
+}
+
+void SOCKS5BytestreamProxiesManager::queryForProxies() {
+	proxyFinder_ = boost::make_shared<SOCKS5BytestreamProxyFinder>(serviceRoot_, iqRouter_);
+
+	proxyFinder_->onProxyFound.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxyFound, this, _1));
+	proxyFinder_->start();
+}
+
 }
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h
index f3fed80..06db76c 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h
+++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h
@@ -4,6 +4,13 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+
 #pragma once
 
 #include <string>
@@ -13,11 +20,13 @@
 #include <Swiften/Elements/S5BProxyRequest.h>
 #include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h>
 #include <Swiften/JID/JID.h>
-#include <Swiften/Network/ConnectionFactory.h>
-#include <Swiften/Network/TimerFactory.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h>
 
 namespace Swift {
-	class SOCKS5BytestreamProxiesDiscoverRequest;
+	class TimerFactory;
+	class ConnectionFactory;
+	class DomainNameResolver;
+	class DomainNameResolveError;
 
 	/**
 	 *	- manages list of working S5B proxies
@@ -25,26 +34,44 @@ namespace Swift {
 	 */
 	class SWIFTEN_API SOCKS5BytestreamProxiesManager {
 		public:
-			SOCKS5BytestreamProxiesManager(ConnectionFactory*, TimerFactory*);
-
-			boost::shared_ptr<SOCKS5BytestreamProxiesDiscoverRequest> createDiscoverProxiesRequest();
+			SOCKS5BytestreamProxiesManager(ConnectionFactory*, TimerFactory*, DomainNameResolver*, IQRouter*, const JID&);
+			~SOCKS5BytestreamProxiesManager();
 
 			void addS5BProxy(S5BProxyRequest::ref);
-			const std::vector<S5BProxyRequest::ref>& getS5BProxies() const;
+
+			/*
+			 * Returns a list of external S5B proxies. If the optinal return value is not initialized a discovery process has been started and
+			 * onDiscoveredProxiesChanged signal will be emitted when it is finished.
+			 */
+			const boost::optional<std::vector<S5BProxyRequest::ref> >& getOrDiscoverS5BProxies();
 
 			void connectToProxies(const std::string& sessionID);
 			boost::shared_ptr<SOCKS5BytestreamClientSession> getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID);
 
 			boost::shared_ptr<SOCKS5BytestreamClientSession> createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr);
 
+		public:
+			boost::signal<void ()> onDiscoveredProxiesChanged;
+
+		private:
+			void handleProxyFound(S5BProxyRequest::ref proxy);
+			void handleNameLookupResult(const std::vector<HostAddress>&, boost::optional<DomainNameResolveError>, S5BProxyRequest::ref proxy);
+
+			void queryForProxies();
+
 		private:
-			ConnectionFactory* connectionFactory;
-			TimerFactory* timerFactory;
+			ConnectionFactory* connectionFactory_;
+			TimerFactory* timerFactory_;
+			DomainNameResolver* resolver_;
+			IQRouter* iqRouter_;
+			JID serviceRoot_;
 
 			typedef std::map<JID, boost::shared_ptr<SOCKS5BytestreamClientSession> > ProxyJIDClientSessionMap;
-			std::map<std::string, ProxyJIDClientSessionMap> proxySessions;
+			std::map<std::string, ProxyJIDClientSessionMap> proxySessions_;
+
+			boost::shared_ptr<SOCKS5BytestreamProxyFinder> proxyFinder_;
 
-			std::vector<S5BProxyRequest::ref> localS5BProxies;
+			boost::optional<std::vector<S5BProxyRequest::ref> > localS5BProxies_;
 	};
 
 }
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h
index 8265157..54c2075 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h
+++ b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h
@@ -4,6 +4,13 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+
 #pragma once
 
 #include <boost/shared_ptr.hpp>
@@ -17,6 +24,10 @@ namespace Swift {
 class JID;
 class IQRouter;
 
+/*
+ * This class is designed to find possible SOCKS5 bytestream proxies which are used for peer-to-peer data transfers in
+ * restrictive environments.
+ */
 class SOCKS5BytestreamProxyFinder {
 	public:
 		SOCKS5BytestreamProxyFinder(const JID& service, IQRouter *iqRouter);
diff --git a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp
index 207f590..aaf90ea 100644
--- a/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp
+++ b/Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013-2014 Isode Limited.
+ * Copyright (c) 2013-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -28,6 +28,7 @@
 #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h>
 #include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
 #include <Swiften/Network/PlatformNetworkEnvironment.h>
+#include <Swiften/Network/StaticDomainNameResolver.h>
 #include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
 #include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
 #include <Swiften/Jingle/FakeJingleSession.h>
@@ -67,6 +68,7 @@ public:
 		void setUp() {
 			crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
 			eventLoop = new DummyEventLoop();
+			resolver = new StaticDomainNameResolver(eventLoop);
 			session = boost::make_shared<FakeJingleSession>("foo@bar.com/baz", "mysession");
 			jingleContentPayload = make_shared<JingleContentPayload>();
 			// fakeRJTCSF = make_shared<FakeRemoteJingleTransportCandidateSelectorFactory>();
@@ -81,7 +83,7 @@ public:
 			bytestreamServerManager = new SOCKS5BytestreamServerManager(bytestreamRegistry, serverConnectionFactory, networkEnvironment, natTraverser);
 			idGenerator = new SimpleIDGenerator();
 			timerFactory = new DummyTimerFactory();
-			bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory);
+			bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory, resolver, iqRouter, "bar.com");
 			ftTransporterFactory = new DefaultFileTransferTransporterFactory(bytestreamRegistry, bytestreamServerManager, bytestreamProxy, idGenerator, connectionFactory, timerFactory, crypto.get(), iqRouter);
 		}
 
@@ -94,6 +96,7 @@ public:
 			delete bytestreamRegistry;
 			delete iqRouter;
 			delete stanzaChannel;
+			delete resolver;
 			delete eventLoop;
 			Log::setLogLevel(Log::error);
 		}
@@ -232,6 +235,7 @@ private:
 	NetworkEnvironment* networkEnvironment;
 	NATTraverser* natTraverser;
 	IDGenerator* idGenerator;
+	DomainNameResolver* resolver;
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(IncomingJingleFileTransferTest);
diff --git a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp
index 6e33f16..5cfd28d 100644
--- a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp
+++ b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp
@@ -4,6 +4,12 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
 #include "S5BProxyRequestParser.h"
 
 #include <boost/lexical_cast.hpp>
@@ -20,7 +26,7 @@ S5BProxyRequestParser::~S5BProxyRequestParser() {
 void S5BProxyRequestParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
 	if (element == "streamhost") {
 		if (attributes.getAttributeValue("host") && attributes.getAttributeValue("jid") && attributes.getAttributeValue("port")) {
-			HostAddress address = attributes.getAttributeValue("host").get_value_or("");
+			std::string host = attributes.getAttributeValue("host").get_value_or("");
 			int port = -1;
 			JID jid = attributes.getAttributeValue("jid").get_value_or("");
 
@@ -29,9 +35,10 @@ void S5BProxyRequestParser::handleStartElement(const std::string& element, const
 			} catch (boost::bad_lexical_cast &) {
 				port = -1;
 			}
-			if (address.isValid() && port != -1 && jid.isValid()) {
+			if (!host.empty() && port != -1 && jid.isValid()) {
 				S5BProxyRequest::StreamHost streamHost;
-				streamHost.addressPort = HostAddressPort(address, port);
+				streamHost.host = host;
+				streamHost.port = port;
 				streamHost.jid = jid;
 				getPayloadInternal()->setStreamHost(streamHost);
 			}
diff --git a/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h b/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h
index b523588..e7cdbe8 100644
--- a/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h
@@ -4,6 +4,11 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
 
 #pragma once
 
@@ -23,8 +28,8 @@ namespace Swift {
 				XMLElement queryElement("query", "http://jabber.org/protocol/bytestreams");
 				if (s5bProxyRequest && s5bProxyRequest->getStreamHost()) {
 					boost::shared_ptr<XMLElement> streamHost = boost::make_shared<XMLElement>("streamhost");
-					streamHost->setAttribute("host", s5bProxyRequest->getStreamHost().get().addressPort.getAddress().toString());
-					streamHost->setAttribute("port", boost::lexical_cast<std::string>(s5bProxyRequest->getStreamHost().get().addressPort.getPort()));
+					streamHost->setAttribute("host", s5bProxyRequest->getStreamHost().get().host);
+					streamHost->setAttribute("port", boost::lexical_cast<std::string>(s5bProxyRequest->getStreamHost().get().port));
 					streamHost->setAttribute("jid", s5bProxyRequest->getStreamHost().get().jid.toString());
 					queryElement.addNode(streamHost);
 				} else if (s5bProxyRequest && s5bProxyRequest->getActivate()) {
-- 
cgit v0.10.2-6-g49f6