summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp70
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h12
2 files changed, 68 insertions, 14 deletions
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp
index 2956ff7..1036e12 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp
+++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.cpp
@@ -33,10 +33,17 @@ SOCKS5BytestreamProxiesManager::SOCKS5BytestreamProxiesManager(ConnectionFactory
33 33
34SOCKS5BytestreamProxiesManager::~SOCKS5BytestreamProxiesManager() { 34SOCKS5BytestreamProxiesManager::~SOCKS5BytestreamProxiesManager() {
35 if (proxyFinder_) { 35 if (proxyFinder_) {
36 proxyFinder_->stop(); 36 proxyFinder_->stop();
37 } 37 }
38
39 foreach (const ProxySessionsMap::value_type& sessionsForID, proxySessions_) {
40 foreach (const ProxyJIDClientSessionVector::value_type& session, sessionsForID.second) {
41 session.second->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionsForID.first, session.first, session.second, _1));
42 session.second->onFinished.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionsForID.first, session.first, session.second, _1));
43 }
44 }
38} 45}
39 46
40void SOCKS5BytestreamProxiesManager::addS5BProxy(S5BProxyRequest::ref proxy) { 47void SOCKS5BytestreamProxiesManager::addS5BProxy(S5BProxyRequest::ref proxy) {
41 if (proxy) { 48 if (proxy) {
42 SWIFT_LOG_ASSERT(HostAddress(proxy->getStreamHost().get().host).isValid(), warning) << std::endl; 49 SWIFT_LOG_ASSERT(HostAddress(proxy->getStreamHost().get().host).isValid(), warning) << std::endl;
@@ -54,20 +61,23 @@ const boost::optional<std::vector<S5BProxyRequest::ref> >& SOCKS5BytestreamProxi
54 return localS5BProxies_; 61 return localS5BProxies_;
55} 62}
56 63
57void SOCKS5BytestreamProxiesManager::connectToProxies(const std::string& sessionID) { 64void SOCKS5BytestreamProxiesManager::connectToProxies(const std::string& sessionID) {
58 SWIFT_LOG(debug) << "session ID: " << sessionID << std::endl; 65 SWIFT_LOG(debug) << "session ID: " << sessionID << std::endl;
59 ProxyJIDClientSessionMap clientSessions; 66 ProxyJIDClientSessionVector clientSessions;
60 67
61 if (localS5BProxies_) { 68 if (localS5BProxies_) {
62 foreach(S5BProxyRequest::ref proxy, localS5BProxies_.get()) { 69 foreach(S5BProxyRequest::ref proxy, localS5BProxies_.get()) {
63 boost::shared_ptr<Connection> conn = connectionFactory_->createConnection(); 70 boost::shared_ptr<Connection> conn = connectionFactory_->createConnection();
64 71
65 HostAddressPort addressPort = HostAddressPort(proxy->getStreamHost().get().host, proxy->getStreamHost().get().port); 72 HostAddressPort addressPort = HostAddressPort(proxy->getStreamHost().get().host, proxy->getStreamHost().get().port);
66 SWIFT_LOG_ASSERT(addressPort.isValid(), warning) << std::endl; 73 SWIFT_LOG_ASSERT(addressPort.isValid(), warning) << std::endl;
67 boost::shared_ptr<SOCKS5BytestreamClientSession> session = boost::make_shared<SOCKS5BytestreamClientSession>(conn, addressPort, sessionID, timerFactory_); 74 boost::shared_ptr<SOCKS5BytestreamClientSession> session = boost::make_shared<SOCKS5BytestreamClientSession>(conn, addressPort, sessionID, timerFactory_);
68 clientSessions[proxy->getStreamHost().get().jid] = session; 75 JID proxyJid = proxy->getStreamHost().get().jid;
76 clientSessions.push_back(std::pair<JID, boost::shared_ptr<SOCKS5BytestreamClientSession> >(proxyJid, session));
77 session->onSessionReady.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionID, proxyJid, session, _1));
78 session->onFinished.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionID, proxyJid, session, _1));
69 session->start(); 79 session->start();
70 } 80 }
71 } 81 }
72 82
73 proxySessions_[sessionID] = clientSessions; 83 proxySessions_[sessionID] = clientSessions;
@@ -76,21 +86,22 @@ void SOCKS5BytestreamProxiesManager::connectToProxies(const std::string& session
76boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID) { 86boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager::getProxySessionAndCloseOthers(const JID& proxyJID, const std::string& sessionID) {
77 // checking parameters 87 // checking parameters
78 if (proxySessions_.find(sessionID) == proxySessions_.end()) { 88 if (proxySessions_.find(sessionID) == proxySessions_.end()) {
79 return boost::shared_ptr<SOCKS5BytestreamClientSession>(); 89 return boost::shared_ptr<SOCKS5BytestreamClientSession>();
80 } 90 }
81 if (proxySessions_[sessionID].find(proxyJID) == proxySessions_[sessionID].end()) {
82 return boost::shared_ptr<SOCKS5BytestreamClientSession>();
83 }
84 91
85 // get active session 92 // get active session
86 boost::shared_ptr<SOCKS5BytestreamClientSession> activeSession = proxySessions_[sessionID][proxyJID]; 93 boost::shared_ptr<SOCKS5BytestreamClientSession> activeSession;
87 proxySessions_[sessionID].erase(proxyJID); 94 for (ProxyJIDClientSessionVector::iterator i = proxySessions_[sessionID].begin(); i != proxySessions_[sessionID].end(); i++) {
88 95 i->second->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionReady, this,sessionID, proxyJID, i->second, _1));
89 // close other sessions 96 i->second->onFinished.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionID, proxyJID, i->second, _1));
90 foreach(const ProxyJIDClientSessionMap::value_type& myPair, proxySessions_[sessionID]) { 97 if (i->first == proxyJID && !activeSession) {
91 myPair.second->stop(); 98 activeSession = i->second;
99 }
100 else {
101 i->second->stop();
102 }
92 } 103 }
93 104
94 proxySessions_.erase(sessionID); 105 proxySessions_.erase(sessionID);
95 106
96 return activeSession; 107 return activeSession;
@@ -148,6 +159,43 @@ void SOCKS5BytestreamProxiesManager::queryForProxies() {
148 159
149 proxyFinder_->onProxyFound.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxyFound, this, _1)); 160 proxyFinder_->onProxyFound.connect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxyFound, this, _1));
150 proxyFinder_->start(); 161 proxyFinder_->start();
151} 162}
152 163
164void SOCKS5BytestreamProxiesManager::handleProxySessionReady(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, bool error) {
165 session->onSessionReady.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, boost::cref(sessionID), boost::cref(jid), session, _1));
166 if (!error) {
167 // The SOCKS5 bytestream session to the proxy succeeded; stop and remove other sessions.
168 if (proxySessions_.find(sessionID) != proxySessions_.end()) {
169 for (ProxyJIDClientSessionVector::iterator i = proxySessions_[sessionID].begin(); i != proxySessions_[sessionID].end();) {
170 if ((i->first == jid) && (i->second != session)) {
171 i->second->stop();
172 i = proxySessions_[sessionID].erase(i);
173 }
174 else {
175 i++;
176 }
177 }
178 }
179 }
180}
181
182void SOCKS5BytestreamProxiesManager::handleProxySessionFinished(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, boost::optional<FileTransferError> error) {
183 session->onFinished.disconnect(boost::bind(&SOCKS5BytestreamProxiesManager::handleProxySessionFinished, this, sessionID, jid, session, _1));
184 if (error.is_initialized()) {
185 // The SOCKS5 bytestream session to the proxy failed; remove it.
186 if (proxySessions_.find(sessionID) != proxySessions_.end()) {
187 for (ProxyJIDClientSessionVector::iterator i = proxySessions_[sessionID].begin(); i != proxySessions_[sessionID].end();) {
188 if ((i->first == jid) && (i->second == session)) {
189 i->second->stop();
190 i = proxySessions_[sessionID].erase(i);
191 break;
192 }
193 else {
194 i++;
195 }
196 }
197 }
198 }
199}
200
153} 201}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h
index 06db76c..e4bf1d9 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h
+++ b/Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h
@@ -11,18 +11,20 @@
11 */ 11 */
12 12
13 13
14#pragma once 14#pragma once
15 15
16#include <map>
16#include <string> 17#include <string>
18#include <utility>
17#include <vector> 19#include <vector>
18 20
19#include <Swiften/Base/API.h> 21#include <Swiften/Base/API.h>
20#include <Swiften/Elements/S5BProxyRequest.h> 22#include <Swiften/Elements/S5BProxyRequest.h>
21#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h> 23#include <Swiften/FileTransfer/SOCKS5BytestreamClientSession.h>
22#include <Swiften/JID/JID.h>
23#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h> 24#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h>
25#include <Swiften/JID/JID.h>
24 26
25namespace Swift { 27namespace Swift {
26 class TimerFactory; 28 class TimerFactory;
27 class ConnectionFactory; 29 class ConnectionFactory;
28 class DomainNameResolver; 30 class DomainNameResolver;
@@ -57,19 +59,23 @@ namespace Swift {
57 void handleProxyFound(S5BProxyRequest::ref proxy); 59 void handleProxyFound(S5BProxyRequest::ref proxy);
58 void handleNameLookupResult(const std::vector<HostAddress>&, boost::optional<DomainNameResolveError>, S5BProxyRequest::ref proxy); 60 void handleNameLookupResult(const std::vector<HostAddress>&, boost::optional<DomainNameResolveError>, S5BProxyRequest::ref proxy);
59 61
60 void queryForProxies(); 62 void queryForProxies();
61 63
64 void handleProxySessionReady(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, bool error);
65 void handleProxySessionFinished(const std::string& sessionID, const JID& jid, boost::shared_ptr<SOCKS5BytestreamClientSession> session, boost::optional<FileTransferError> error);
66
62 private: 67 private:
63 ConnectionFactory* connectionFactory_; 68 ConnectionFactory* connectionFactory_;
64 TimerFactory* timerFactory_; 69 TimerFactory* timerFactory_;
65 DomainNameResolver* resolver_; 70 DomainNameResolver* resolver_;
66 IQRouter* iqRouter_; 71 IQRouter* iqRouter_;
67 JID serviceRoot_; 72 JID serviceRoot_;
68 73
69 typedef std::map<JID, boost::shared_ptr<SOCKS5BytestreamClientSession> > ProxyJIDClientSessionMap; 74 typedef std::vector<std::pair<JID, boost::shared_ptr<SOCKS5BytestreamClientSession> > > ProxyJIDClientSessionVector;
70 std::map<std::string, ProxyJIDClientSessionMap> proxySessions_; 75 typedef std::map<std::string, ProxyJIDClientSessionVector> ProxySessionsMap;
76 ProxySessionsMap proxySessions_;
71 77
72 boost::shared_ptr<SOCKS5BytestreamProxyFinder> proxyFinder_; 78 boost::shared_ptr<SOCKS5BytestreamProxyFinder> proxyFinder_;
73 79
74 boost::optional<std::vector<S5BProxyRequest::ref> > localS5BProxies_; 80 boost::optional<std::vector<S5BProxyRequest::ref> > localS5BProxies_;
75 }; 81 };