diff options
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 @@ -112,21 +112,20 @@ boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager: 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(); } @@ -157,12 +156,12 @@ 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()) { 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 @@ -29,6 +29,7 @@ namespace Swift { class ConnectionFactory; class DomainNameResolver; class DomainNameResolveError; + class IQRouter; /** * - manages list of working S5B proxies @@ -56,7 +57,7 @@ namespace Swift { 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(); 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 @@ -4,12 +4,19 @@ * 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> @@ -25,19 +32,27 @@ 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(); } @@ -47,16 +62,26 @@ void SOCKS5BytestreamProxyFinder::handleServiceFound(const JID& jid, boost::shar } } -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 @@ -17,7 +17,6 @@ #include <Swiften/Base/API.h> #include <Swiften/Disco/DiscoServiceWalker.h> -#include <Swiften/Network/HostAddressPort.h> #include <Swiften/Elements/S5BProxyRequest.h> namespace Swift { @@ -37,18 +36,21 @@ class SWIFTEN_API 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; +}; } |