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
@@ -35,6 +35,13 @@ SOCKS5BytestreamProxiesManager::~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) {
@@ -56,7 +63,7 @@ const boost::optional<std::vector<S5BProxyRequest::ref> >& SOCKS5BytestreamProxi
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()) {
@@ -65,7 +72,10 @@ void SOCKS5BytestreamProxiesManager::connectToProxies(const std::string& session
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 }
@@ -78,17 +88,18 @@ boost::shared_ptr<SOCKS5BytestreamClientSession> SOCKS5BytestreamProxiesManager:
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);
@@ -150,4 +161,41 @@ void SOCKS5BytestreamProxiesManager::queryForProxies() {
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
@@ -13,14 +13,16 @@
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;
@@ -59,6 +61,9 @@ namespace Swift {
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_;
@@ -66,8 +71,9 @@ namespace Swift {
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