blob: 1e96b2218d46a52cb7326139a74342b8b5040fbb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
/*
* Copyright (c) 2011 Tobias Markmann
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
/*
* Copyright (c) 2013 Remko Tronçon
* Licensed under the GNU General Public License.
* See the COPYING file for more information.
*/
#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/bind.hpp>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/JingleS5BTransportPayload.h>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
using namespace Swift;
RemoteJingleTransportCandidateSelector::RemoteJingleTransportCandidateSelector(
ConnectionFactory* connectionFactory,
TimerFactory* timerFactory) :
connectionFactory(connectionFactory),
timerFactory(timerFactory) {
}
RemoteJingleTransportCandidateSelector::~RemoteJingleTransportCandidateSelector() {
}
void RemoteJingleTransportCandidateSelector::addCandidates(
const std::vector<JingleS5BTransportPayload::Candidate>& candidates) {
foreach(JingleS5BTransportPayload::Candidate c, candidates) {
this->candidates.push(c);
}
}
void RemoteJingleTransportCandidateSelector::startSelectingCandidate() {
tryNextCandidate();
}
void RemoteJingleTransportCandidateSelector::stopSelectingCandidate() {
if (s5bSession) {
sessionReadyConnection.disconnect();
s5bSession->stop();
}
}
void RemoteJingleTransportCandidateSelector::tryNextCandidate() {
if (candidates.empty()) {
SWIFT_LOG(debug) << "No more candidates" << std::endl;
onCandidateSelectFinished(
boost::optional<JingleS5BTransportPayload::Candidate>(), boost::shared_ptr<SOCKS5BytestreamClientSession>());
}
else {
lastCandidate = candidates.top();
candidates.pop();
SWIFT_LOG(debug) << "Trying candidate " << lastCandidate.cid << std::endl;
if (lastCandidate.type == JingleS5BTransportPayload::Candidate::DirectType
|| lastCandidate.type == JingleS5BTransportPayload::Candidate::AssistedType
|| lastCandidate.type == JingleS5BTransportPayload::Candidate::ProxyType ) {
boost::shared_ptr<Connection> connection = connectionFactory->createConnection();
s5bSession = boost::make_shared<SOCKS5BytestreamClientSession>(
connection, lastCandidate.hostPort, socks5DstAddr, timerFactory);
sessionReadyConnection = s5bSession->onSessionReady.connect(
boost::bind(&RemoteJingleTransportCandidateSelector::handleSessionReady, this, _1));
s5bSession->start();
}
else {
SWIFT_LOG(debug) << "Can't handle this type of candidate" << std::endl;
tryNextCandidate();
}
}
}
void RemoteJingleTransportCandidateSelector::handleSessionReady(bool error) {
sessionReadyConnection.disconnect();
if (error) {
s5bSession.reset();
tryNextCandidate();
}
else {
onCandidateSelectFinished(lastCandidate, s5bSession);
}
}
void RemoteJingleTransportCandidateSelector::setSOCKS5DstAddr(const std::string& socks5DstAddr) {
this->socks5DstAddr = socks5DstAddr;
}
|