diff options
Diffstat (limited to 'Swiften/FileTransfer')
4 files changed, 54 insertions, 27 deletions
| diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp index 1036e12..25a12ea 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp @@ -109,27 +109,26 @@ boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager:  boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr) {  	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); -			onDiscoveredProxiesChanged(); -		} -		else { -			DomainNameAddressQuery::ref resolveRequest = resolver_->createAddressQuery(proxy->getStreamHost().get().host); -			resolveRequest->onResult.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleNameLookupResult, this, _1, _2, proxy)); -			resolveRequest->run(); +void SOCKS5BytestreamProxiesManager::handleProxiesFound(std::vector<S5BProxyRequest::ref> proxyHosts) { +	foreach(S5BProxyRequest::ref proxy, proxyHosts) { +		if (proxy) { +			if (HostAddress(proxy->getStreamHost().get().host).isValid()) { +				addS5BProxy(proxy); +				onDiscoveredProxiesChanged(); +			} +			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();  	proxyFinder_.reset();  }  void SOCKS5BytestreamProxiesManager::handleNameLookupResult(const std::vector<HostAddress>& addresses, boost::optional<DomainNameResolveError> error, S5BProxyRequest::ref proxy) {  	if (error) { @@ -154,18 +153,18 @@ void SOCKS5BytestreamProxiesManager::handleNameLookupResult(const std::vector<Ho  	}  }  void SOCKS5BytestreamProxiesManager::queryForProxies() {  	proxyFinder_ = boost::make_shared<SOCKS5BytestreamProxyFinder>(serviceRoot_, iqRouter_); -	proxyFinder_->onProxyFound.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxyFound, this, _1)); +	proxyFinder_->onProxiesFound.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxiesFound, this, _1));  	proxyFinder_->start();  }  void SOCKS5BytestreamProxiesManager::handleProxySessionReady(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, bool error) { -	session->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, boost::cref(sessionID), boost::cref(jid), session, _1)); +	session->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this, boost::cref(sessionID), boost::cref(jid), session, _1));  	if (!error) {  		// The SOCKS5 bytestream session to the proxy succeeded; stop and remove other sessions.  		if (proxySessions_.find(sessionID) != proxySessions_.end()) {  			for (ProxyJIDClientSessionVector::iterator i = proxySessions_[sessionID].begin(); i != proxySessions_[sessionID].end();) {  				if ((i->first == jid) && (i->second != session)) {  					i->second->stop(); diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h index e4bf1d9..c7daee7 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h @@ -26,12 +26,13 @@  namespace Swift {  	class TimerFactory;  	class ConnectionFactory;  	class DomainNameResolver;  	class DomainNameResolveError; +	class IQRouter;  	/**  	 *	- manages list of working S5B proxies  	 *	- creates initial connections (for the candidates you provide)  	 */  	class SWIFTEN_API SOCKS5BytestreamProxiesManager { @@ -53,13 +54,13 @@ namespace Swift {  			boost::shared_ptr<SOCKS5BytestreamClientSession> createSOCKS5BytestreamClientSession(HostAddressPort addressPort, const std::string& destAddr);  		public:  			boost::signal<void ()> onDiscoveredProxiesChanged;  		private: -			void handleProxyFound(S5BProxyRequest::ref proxy); +			void handleProxiesFound(std::vector<S5BProxyRequest::ref> proxyHosts);  			void handleNameLookupResult(const std::vector<HostAddress>&, boost::optional<DomainNameResolveError>, S5BProxyRequest::ref proxy);  			void queryForProxies();  			void handleProxySessionReady(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, bool error);  			void handleProxySessionFinished(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, boost::optional<FileTransferError> error); diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp index 9d7505b..78cf2e6 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.cpp @@ -1,18 +1,25 @@  /*   * Copyright (c) 2011 Tobias Markmann   * Licensed under the simplified BSD license.   * 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/SOCKS5BytestreamProxyFinder.h> -#include <boost/smart_ptr/make_shared.hpp>  #include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp>  #include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h>  #include <Swiften/Elements/S5BProxyRequest.h>  #include <Swiften/Queries/GenericRequest.h>  #include <Swiften/Queries/IQRouter.h>  namespace Swift { @@ -22,41 +29,59 @@ SOCKS5BytestreamProxyFinder::SOCKS5BytestreamProxyFinder(const JID& service, IQR  SOCKS5BytestreamProxyFinder::~SOCKS5BytestreamProxyFinder() {  }  void SOCKS5BytestreamProxyFinder::start() {  	serviceWalker = boost::make_shared<DiscoServiceWalker>(service, iqRouter);  	serviceWalker->onServiceFound.connect(boost::bind(&SOCKS5BytestreamProxyFinder::handleServiceFound, this, _1, _2)); +	serviceWalker->onWalkComplete.connect(boost::bind(&SOCKS5BytestreamProxyFinder::handleWalkEnded, this));  	serviceWalker->beginWalk();  }  void SOCKS5BytestreamProxyFinder::stop() { +	typedef boost::shared_ptr<GenericRequest<S5BProxyRequest> > S5BProxyRequestGenericRequest; +	foreach (S5BProxyRequestGenericRequest requester, pendingRequests) { +		requester->onResponse.disconnect(boost::bind(&SOCKS5BytestreamProxyFinder::handleProxyResponse, this, requester, _1, _2)); +	} +  	serviceWalker->endWalk();  	serviceWalker->onServiceFound.disconnect(boost::bind(&SOCKS5BytestreamProxyFinder::handleServiceFound, this, _1, _2)); +	serviceWalker->onWalkComplete.disconnect(boost::bind(&SOCKS5BytestreamProxyFinder::handleWalkEnded, this));  	serviceWalker.reset();  }  void SOCKS5BytestreamProxyFinder::sendBytestreamQuery(const JID& jid) {  	S5BProxyRequest::ref proxyRequest = boost::make_shared<S5BProxyRequest>();  	boost::shared_ptr<GenericRequest<S5BProxyRequest> > request = boost::make_shared<GenericRequest<S5BProxyRequest> >(IQ::Get, jid, proxyRequest, iqRouter); -	request->onResponse.connect(boost::bind(&SOCKS5BytestreamProxyFinder::handleProxyResponse, this, _1, _2)); +	request->onResponse.connect(boost::bind(&SOCKS5BytestreamProxyFinder::handleProxyResponse, this, request, _1, _2)); +	pendingRequests.insert(request);  	request->send();  }  void SOCKS5BytestreamProxyFinder::handleServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> discoInfo) {  	if (discoInfo->hasFeature(DiscoInfo::Bytestream)) {  		sendBytestreamQuery(jid);  	}  } -void SOCKS5BytestreamProxyFinder::handleProxyResponse(boost::shared_ptr<S5BProxyRequest> request, ErrorPayload::ref error) { +void SOCKS5BytestreamProxyFinder::handleWalkEnded() { +	if (pendingRequests.empty()) { +		onProxiesFound(proxyHosts); +	} +} + +void SOCKS5BytestreamProxyFinder::handleProxyResponse(boost::shared_ptr<GenericRequest<S5BProxyRequest> > requester, boost::shared_ptr<S5BProxyRequest> request, ErrorPayload::ref error) { +	requester->onResponse.disconnect(boost::bind(&SOCKS5BytestreamProxyFinder::handleProxyResponse, this, requester, _1, _2)); +	pendingRequests.erase(requester);  	if (error) {  		SWIFT_LOG(debug) << "ERROR" << std::endl;  	} else {  		if (request) { -			onProxyFound(request); -		} else { -			//assert(false); +			SWIFT_LOG(debug) << "add request" << std::endl; +			proxyHosts.push_back(request);  		}  	} +	if (pendingRequests.empty() && !serviceWalker->isActive()) { +		onProxiesFound(proxyHosts); +	}  }  } diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h index c5ad72a..1c24497 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h @@ -14,13 +14,12 @@  #pragma once  #include <boost/shared_ptr.hpp>  #include <Swiften/Base/API.h>  #include <Swiften/Disco/DiscoServiceWalker.h> -#include <Swiften/Network/HostAddressPort.h>  #include <Swiften/Elements/S5BProxyRequest.h>  namespace Swift {  class JID;  class IQRouter; @@ -34,21 +33,24 @@ class SWIFTEN_API SOCKS5BytestreamProxyFinder {  		SOCKS5BytestreamProxyFinder(const JID& service, IQRouter *iqRouter);  		~SOCKS5BytestreamProxyFinder();  		void start();  		void stop(); -		boost::signal<void(boost::shared_ptr<S5BProxyRequest>)> onProxyFound; +		boost::signal<void(std::vector<boost::shared_ptr<S5BProxyRequest> >)> onProxiesFound;  	private:  		void sendBytestreamQuery(const JID&);  		void handleServiceFound(const JID&, boost::shared_ptr<DiscoInfo>); -		void handleProxyResponse(boost::shared_ptr<S5BProxyRequest>, ErrorPayload::ref); +		void handleProxyResponse(boost::shared_ptr<GenericRequest<S5BProxyRequest> > requester, boost::shared_ptr<S5BProxyRequest>, ErrorPayload::ref); +		void handleWalkEnded(); +  	private:  		JID service;  		IQRouter* iqRouter;  		boost::shared_ptr<DiscoServiceWalker> serviceWalker; -		std::vector<boost::shared_ptr<GenericRequest<S5BProxyRequest> > > requests; -	}; +		std::vector<S5BProxyRequest::ref> proxyHosts; +		std::set<boost::shared_ptr<GenericRequest<S5BProxyRequest> > > pendingRequests; +};  } | 
 Swift
 Swift