diff options
| -rw-r--r-- | Swiften/Client/Client.cpp | 1 | ||||
| -rw-r--r-- | Swiften/Elements/S5BProxyRequest.h | 9 | ||||
| -rw-r--r-- | Swiften/FileTransfer/FileTransferManagerImpl.cpp | 3 | ||||
| -rw-r--r-- | Swiften/FileTransfer/FileTransferManagerImpl.h | 16 | ||||
| -rw-r--r-- | Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp | 109 | ||||
| -rw-r--r-- | Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h | 49 | ||||
| -rw-r--r-- | Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h | 11 | ||||
| -rw-r--r-- | Swiften/FileTransfer/UnitTest/IncomingJingleFileTransferTest.cpp | 8 | ||||
| -rw-r--r-- | Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp | 13 | ||||
| -rw-r--r-- | Swiften/Serializer/PayloadSerializers/S5BProxyRequestSerializer.h | 9 | 
10 files changed, 184 insertions, 44 deletions
| 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()) { | 
 Swift
 Swift