summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/FileTransfer')
-rw-r--r--Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp101
-rw-r--r--Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h8
-rw-r--r--Swiften/FileTransfer/SConscript3
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.cpp39
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h33
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp99
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerManager.h23
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.cpp39
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h31
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.cpp35
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h31
11 files changed, 283 insertions, 159 deletions
diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp
index c684a90..6a059bf 100644
--- a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp
+++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp
@@ -20,13 +20,14 @@
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Elements/JingleS5BTransportPayload.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
-#include <Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h>
static const unsigned int LOCAL_PREFERENCE = 0;
namespace Swift {
LocalJingleTransportCandidateGenerator::LocalJingleTransportCandidateGenerator(
@@ -36,58 +37,87 @@ LocalJingleTransportCandidateGenerator::LocalJingleTransportCandidateGenerator(
IDGenerator* idGenerator,
const FileTransferOptions& options) :
s5bServerManager(s5bServerManager),
s5bProxy(s5bProxy),
ownJID(ownJID),
idGenerator(idGenerator),
- options_(options) {
+ options_(options),
+ triedServerInit_(false),
+ triedForwarding_(false),
+ triedProxyDiscovery_(false) {
}
LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator() {
SWIFT_LOG_ASSERT(!s5bServerInitializeRequest, warning) << std::endl;
}
void LocalJingleTransportCandidateGenerator::start() {
assert(!s5bServerInitializeRequest);
- s5bServerInitializeRequest = s5bServerManager->createInitializeRequest();
- s5bServerInitializeRequest->onFinished.connect(
- boost::bind(&LocalJingleTransportCandidateGenerator::handleS5BServerInitialized, this, _1));
- s5bServerInitializeRequest->start();
-}
+ if (options_.isDirectAllowed() || options_.isAssistedAllowed()) {
+ s5bServerResourceUser_ = s5bServerManager->aquireResourceUser();
+ if (s5bServerResourceUser_->isInitialized()) {
+ handleS5BServerInitialized(true);
+ }
+ else {
+ s5bServerResourceUser_->onSuccessfulInitialized.connect(boost::bind(&LocalJingleTransportCandidateGenerator::handleS5BServerInitialized, this, _1));
+ }
+ } else {
+ handleS5BServerInitialized(false);
+ }
-void LocalJingleTransportCandidateGenerator::stop() {
- if (s5bServerInitializeRequest) {
- s5bServerInitializeRequest->stop();
- s5bServerInitializeRequest.reset();
+ if (options_.isProxiedAllowed()) {
+ s5bProxy->onDiscoveredProxiesChanged.connect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this));
+ if (s5bProxy->getOrDiscoverS5BProxies().is_initialized()) {
+ handleDiscoveredProxiesChanged();
+ }
}
+}
- s5bServerManager->stop();
+void LocalJingleTransportCandidateGenerator::stop() {
+ s5bServerResourceUser_.reset();
}
void LocalJingleTransportCandidateGenerator::handleS5BServerInitialized(bool success) {
+ triedServerInit_ = true;
if (success) {
- if (options_.isProxiedAllowed()) {
- if (s5bProxy->getOrDiscoverS5BProxies()) {
- emitOnLocalTransportCandidatesGenerated();
- } else {
- s5bProxy->onDiscoveredProxiesChanged.connect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this));
+ if (options_.isAssistedAllowed()) {
+ // try to setup port forwarding
+ s5bServerPortForwardingUser_ = s5bServerManager->aquirePortForwardingUser();
+ if (s5bServerPortForwardingUser_->isForwardingSetup()) {
+ handlePortForwardingSetup(true);
}
}
- else {
- emitOnLocalTransportCandidatesGenerated();
- }
}
else {
SWIFT_LOG(warning) << "Unable to start SOCKS5 server" << std::endl;
+ s5bServerResourceUser_.reset();
+ handlePortForwardingSetup(false);
}
+ checkS5BCandidatesReady();
+}
- s5bServerInitializeRequest->stop();
- s5bServerInitializeRequest.reset();
+void LocalJingleTransportCandidateGenerator::handlePortForwardingSetup(bool success) {
+ triedForwarding_ = true;
+ checkS5BCandidatesReady();
+}
+void LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged() {
+ s5bProxy->onDiscoveredProxiesChanged.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this));
+ triedProxyDiscovery_ = true;
+ checkS5BCandidatesReady();
}
+void LocalJingleTransportCandidateGenerator::checkS5BCandidatesReady() {
+ if ((!options_.isDirectAllowed() || (options_.isDirectAllowed() && triedServerInit_)) &&
+ (!options_.isProxiedAllowed() || (options_.isProxiedAllowed() && triedProxyDiscovery_)) &&
+ (!options_.isDirectAllowed() || (options_.isDirectAllowed() && triedServerInit_))) {
+ emitOnLocalTransportCandidatesGenerated();
+ }
+}
+
+
void LocalJingleTransportCandidateGenerator::emitOnLocalTransportCandidatesGenerated() {
std::vector<JingleS5BTransportPayload::Candidate> candidates;
if (options_.isDirectAllowed()) {
// get direct candidates
std::vector<HostAddressPort> directCandidates = s5bServerManager->getHostAddressPorts();
@@ -113,13 +143,13 @@ void LocalJingleTransportCandidateGenerator::emitOnLocalTransportCandidatesGener
candidate.priority = 65536 * 120 + LOCAL_PREFERENCE;
candidate.cid = idGenerator->generateID();
candidates.push_back(candidate);
}
}
- if (options_.isProxiedAllowed()) {
+ if (options_.isProxiedAllowed() && s5bProxy->getOrDiscoverS5BProxies().is_initialized()) {
foreach(S5BProxyRequest::ref proxy, s5bProxy->getOrDiscoverS5BProxies().get()) {
if (proxy->getStreamHost()) { // FIXME: Added this test, because there were cases where this wasn't initialized. Investigate this. (Remko)
JingleS5BTransportPayload::Candidate candidate;
candidate.type = JingleS5BTransportPayload::Candidate::ProxyType;
candidate.jid = (*proxy->getStreamHost()).jid;
HostAddress address = (*proxy->getStreamHost()).host;
@@ -132,32 +162,7 @@ void LocalJingleTransportCandidateGenerator::emitOnLocalTransportCandidatesGener
}
}
onLocalTransportCandidatesGenerated(candidates);
}
-void LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged() {
- s5bProxy->onDiscoveredProxiesChanged.disconnect(boost::bind(&LocalJingleTransportCandidateGenerator::handleDiscoveredProxiesChanged, this));
- emitOnLocalTransportCandidatesGenerated();
-}
-
-/*void LocalJingleTransportCandidateGenerator::handleS5BProxiesDiscovered() {
- foreach(S5BProxyRequest::ref proxy, s5bProxiesDiscoverRequest->getS5BProxies()) {
- if (proxy->getStreamHost()) { // FIXME: Added this test, because there were cases where this wasn't initialized. Investigate this. (Remko)
- JingleS5BTransportPayload::Candidate candidate;
- candidate.type = JingleS5BTransportPayload::Candidate::ProxyType;
- candidate.jid = (*proxy->getStreamHost()).jid;
- candidate.hostPort = (*proxy->getStreamHost()).addressPort;
- candidate.priority = 65536 * 10 + LOCAL_PREFERENCE;
- candidate.cid = idGenerator.generateID();
- s5bCandidatesPayload->addCandidate(candidate);
- }
- }
-
- haveS5BProxyCandidates = true;
- s5bProxiesDiscoverRequest->stop();
- s5bProxiesDiscoverRequest.reset();
-
- checkS5BCandidatesReady();
-}*/
-
}
diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h
index ed2b4f0..bbf17a1 100644
--- a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h
+++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h
@@ -23,12 +23,14 @@
#include <Swiften/FileTransfer/SOCKS5BytestreamProxyFinder.h>
namespace Swift {
class SOCKS5BytestreamServerManager;
class SOCKS5BytestreamProxiesManager;
class SOCKS5BytestreamServerInitializeRequest;
+ class SOCKS5BytestreamServerResourceUser;
+ class SOCKS5BytestreamServerPortForwardingUser;
class JingleS5BTransportPayload;
class LocalJingleTransportCandidateGenerator {
public:
LocalJingleTransportCandidateGenerator(
SOCKS5BytestreamServerManager* s5bServerManager,
@@ -42,20 +44,26 @@ namespace Swift {
virtual void stop();
boost::signal<void (const std::vector<JingleS5BTransportPayload::Candidate>&)> onLocalTransportCandidatesGenerated;
private:
void handleS5BServerInitialized(bool success);
+ void handlePortForwardingSetup(bool success);
void handleDiscoveredProxiesChanged();
void checkS5BCandidatesReady();
void emitOnLocalTransportCandidatesGenerated();
private:
SOCKS5BytestreamServerManager* s5bServerManager;
SOCKS5BytestreamProxiesManager* s5bProxy;
JID ownJID;
IDGenerator* idGenerator;
boost::shared_ptr<SOCKS5BytestreamServerInitializeRequest> s5bServerInitializeRequest;
+ boost::shared_ptr<SOCKS5BytestreamServerResourceUser> s5bServerResourceUser_;
+ boost::shared_ptr<SOCKS5BytestreamServerPortForwardingUser> s5bServerPortForwardingUser_;
+ bool triedServerInit_;
+ bool triedForwarding_;
+ bool triedProxyDiscovery_;
FileTransferOptions options_;
};
}
diff --git a/Swiften/FileTransfer/SConscript b/Swiften/FileTransfer/SConscript
index 88cfc00..ff162ad 100644
--- a/Swiften/FileTransfer/SConscript
+++ b/Swiften/FileTransfer/SConscript
@@ -23,24 +23,25 @@ sources = [
"FileWriteBytestream.cpp",
"FileTransfer.cpp",
"TransportSession.cpp",
"IBBSendTransportSession.cpp",
"IBBReceiveTransportSession.cpp",
"SOCKS5BytestreamClientSession.cpp",
- "SOCKS5BytestreamServerInitializeRequest.cpp",
"SOCKS5BytestreamServerManager.cpp",
"SOCKS5BytestreamServer.cpp",
"SOCKS5BytestreamServerSession.cpp",
"SOCKS5BytestreamRegistry.cpp",
"SOCKS5BytestreamProxiesManager.cpp",
"SOCKS5BytestreamProxyFinder.cpp",
"IBBSendSession.cpp",
"IBBReceiveSession.cpp",
"FileTransferManager.cpp",
"FileTransferManagerImpl.cpp",
"IncrementalBytestreamHashCalculator.cpp",
+ "SOCKS5BytestreamServerResourceUser.cpp",
+ "SOCKS5BytestreamServerPortForwardingUser.cpp",
]
swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources))
env.Append(UNITTEST_SOURCES = [
File("UnitTest/SOCKS5BytestreamServerSessionTest.cpp"),
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.cpp
deleted file mode 100644
index c32d142..0000000
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012 Isode Limited.
- * All rights reserved.
- * See the COPYING file for more information.
- */
-
-#include <Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h>
-
-#include <boost/bind.hpp>
-
-#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
-
-using namespace Swift;
-
-SOCKS5BytestreamServerInitializeRequest::SOCKS5BytestreamServerInitializeRequest(SOCKS5BytestreamServerManager* manager) : manager(manager) {
-}
-
-SOCKS5BytestreamServerInitializeRequest::~SOCKS5BytestreamServerInitializeRequest() {
-}
-
-void SOCKS5BytestreamServerInitializeRequest::start() {
- if (manager->isInitialized()) {
- handleInitialized(true);
- }
- else {
- manager->onInitialized.connect(
- boost::bind(&SOCKS5BytestreamServerInitializeRequest::handleInitialized, this, _1));
- manager->initialize();
- }
-}
-
-void SOCKS5BytestreamServerInitializeRequest::stop() {
- manager->onInitialized.disconnect(
- boost::bind(&SOCKS5BytestreamServerInitializeRequest::handleInitialized, this, _1));
-}
-
-void SOCKS5BytestreamServerInitializeRequest::handleInitialized(bool success) {
- onFinished(success);
-}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h b/Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h
deleted file mode 100644
index 57e8d36..0000000
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012 Isode Limited.
- * All rights reserved.
- * See the COPYING file for more information.
- */
-
-#pragma once
-
-#include <Swiften/Base/API.h>
-#include <Swiften/Base/boost_bsignals.h>
-
-namespace Swift {
- class SOCKS5BytestreamServerManager;
-
- class SWIFTEN_API SOCKS5BytestreamServerInitializeRequest {
- public:
- SOCKS5BytestreamServerInitializeRequest(SOCKS5BytestreamServerManager* manager);
- ~SOCKS5BytestreamServerInitializeRequest();
-
- void start();
- void stop();
-
- public:
- boost::signal<void (bool /* success */)> onFinished;
-
- private:
- void handleInitialized(bool success);
-
- private:
- SOCKS5BytestreamServerManager* manager;
- };
-}
-
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp
index cf4ae84..43d3e46 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.cpp
@@ -12,13 +12,14 @@
#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/bind.hpp>
-#include <Swiften/FileTransfer/SOCKS5BytestreamServerInitializeRequest.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h>
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/Log.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/Network/ConnectionServer.h>
#include <Swiften/Network/ConnectionServerFactory.h>
#include <Swiften/Network/NetworkEnvironment.h>
@@ -39,13 +40,14 @@ SOCKS5BytestreamServerManager::SOCKS5BytestreamServerManager(
NATTraverser* natTraverser) :
bytestreamRegistry(bytestreamRegistry),
connectionServerFactory(connectionServerFactory),
networkEnvironment(networkEnvironment),
natTraverser(natTraverser),
state(Start),
- server(NULL) {
+ server(NULL),
+ attemptedPortMapping_(false) {
}
SOCKS5BytestreamServerManager::~SOCKS5BytestreamServerManager() {
SWIFT_LOG_ASSERT(!connectionServer, warning) << std::endl;
SWIFT_LOG_ASSERT(!getPublicIPRequest, warning) << std::endl;
SWIFT_LOG_ASSERT(!forwardPortRequest, warning) << std::endl;
@@ -54,15 +56,34 @@ SOCKS5BytestreamServerManager::~SOCKS5BytestreamServerManager() {
SWIFT_LOG(warning) << "Port forwarding still alive. Trying to remove it now." << std::endl;
unforwardPortRequest = natTraverser->createRemovePortForwardingRequest(portMapping.get().getLocalPort(), portMapping.get().getPublicPort());
unforwardPortRequest->start();
}
}
+boost::shared_ptr<SOCKS5BytestreamServerResourceUser> SOCKS5BytestreamServerManager::aquireResourceUser() {
+ boost::shared_ptr<SOCKS5BytestreamServerResourceUser> resourceUser;
+ if (s5bServerResourceUser_.expired()) {
+ resourceUser = boost::make_shared<SOCKS5BytestreamServerResourceUser>(this);
+ s5bServerResourceUser_ = resourceUser;
+ }
+ else {
+ resourceUser = s5bServerResourceUser_.lock();
+ }
+ return resourceUser;
+}
-boost::shared_ptr<SOCKS5BytestreamServerInitializeRequest> SOCKS5BytestreamServerManager::createInitializeRequest() {
- return boost::make_shared<SOCKS5BytestreamServerInitializeRequest>(this);
+boost::shared_ptr<SOCKS5BytestreamServerPortForwardingUser> SOCKS5BytestreamServerManager::aquirePortForwardingUser() {
+ boost::shared_ptr<SOCKS5BytestreamServerPortForwardingUser> portForwardingUser;
+ if (s5bServerPortForwardingUser_.expired()) {
+ portForwardingUser = boost::make_shared<SOCKS5BytestreamServerPortForwardingUser>(this);
+ s5bServerPortForwardingUser_ = portForwardingUser;
+ }
+ else {
+ portForwardingUser = s5bServerPortForwardingUser_.lock();
+ }
+ return portForwardingUser;
}
std::vector<HostAddressPort> SOCKS5BytestreamServerManager::getHostAddressPorts() const {
std::vector<HostAddressPort> result;
if (connectionServer) {
std::vector<NetworkInterface> networkInterfaces = networkEnvironment->getNetworkInterfaces();
@@ -118,30 +139,50 @@ void SOCKS5BytestreamServerManager::initialize() {
// Start bytestream server. Should actually happen before the connectionserver is started
// but that doesn't really matter here.
assert(!server);
server = new SOCKS5BytestreamServer(connectionServer, bytestreamRegistry);
server->start();
+ checkInitializeFinished();
+ }
+}
- // Retrieve public addresses
- assert(!getPublicIPRequest);
- publicAddress = boost::optional<HostAddress>();
- if ((getPublicIPRequest = natTraverser->createGetPublicIPRequest())) {
- getPublicIPRequest->onResult.connect(
- boost::bind(&SOCKS5BytestreamServerManager::handleGetPublicIPResult, this, _1));
- getPublicIPRequest->start();
- }
+bool SOCKS5BytestreamServerManager::isPortForwardingReady() const {
+ return attemptedPortMapping_ && !getPublicIPRequest && !forwardPortRequest;
+}
- // Forward ports
- assert(!forwardPortRequest);
- portMapping = boost::optional<NATPortMapping>();
- if ((forwardPortRequest = natTraverser->createForwardPortRequest(port, port))) {
- forwardPortRequest->onResult.connect(
- boost::bind(&SOCKS5BytestreamServerManager::handleForwardPortResult, this, _1));
- forwardPortRequest->start();
- }
+void SOCKS5BytestreamServerManager::setupPortForwarding() {
+ assert(server);
+ attemptedPortMapping_ = true;
+
+ // Retrieve public addresses
+ assert(!getPublicIPRequest);
+ publicAddress = boost::optional<HostAddress>();
+ if ((getPublicIPRequest = natTraverser->createGetPublicIPRequest())) {
+ getPublicIPRequest->onResult.connect(
+ boost::bind(&SOCKS5BytestreamServerManager::handleGetPublicIPResult, this, _1));
+ getPublicIPRequest->start();
+ }
+
+ // Forward ports
+ int port = server->getAddressPort().getPort();
+ assert(!forwardPortRequest);
+ portMapping = boost::optional<NATPortMapping>();
+ if ((forwardPortRequest = natTraverser->createForwardPortRequest(port, port))) {
+ forwardPortRequest->onResult.connect(
+ boost::bind(&SOCKS5BytestreamServerManager::handleForwardPortResult, this, _1));
+ forwardPortRequest->start();
+ }
+}
+
+void SOCKS5BytestreamServerManager::removePortForwarding() {
+ // remove port forwards
+ if (portMapping) {
+ unforwardPortRequest = natTraverser->createRemovePortForwardingRequest(portMapping.get().getLocalPort(), portMapping.get().getPublicPort());
+ unforwardPortRequest->onResult.connect(boost::bind(&SOCKS5BytestreamServerManager::handleUnforwardPortResult, this, _1));
+ unforwardPortRequest->start();
}
}
void SOCKS5BytestreamServerManager::stop() {
if (getPublicIPRequest) {
getPublicIPRequest->stop();
@@ -153,19 +194,12 @@ void SOCKS5BytestreamServerManager::stop() {
}
if (connectionServer) {
connectionServer->stop();
connectionServer.reset();
}
- // remove port forwards
- if (portMapping) {
- unforwardPortRequest = natTraverser->createRemovePortForwardingRequest(portMapping.get().getLocalPort(), portMapping.get().getPublicPort());
- unforwardPortRequest->onResult.connect(boost::bind(&SOCKS5BytestreamServerManager::handleUnforwardPortResult, this, _1));
- unforwardPortRequest->start();
- }
-
state = Start;
}
void SOCKS5BytestreamServerManager::handleGetPublicIPResult(boost::optional<HostAddress> address) {
if (address) {
SWIFT_LOG(debug) << "Public IP discovered as " << address.get().toString() << "." << std::endl;
@@ -175,14 +209,12 @@ void SOCKS5BytestreamServerManager::handleGetPublicIPResult(boost::optional<Host
}
publicAddress = address;
getPublicIPRequest->stop();
getPublicIPRequest.reset();
-
- checkInitializeFinished();
}
void SOCKS5BytestreamServerManager::handleForwardPortResult(boost::optional<NATPortMapping> mapping) {
if (mapping) {
SWIFT_LOG(debug) << "Mapping port was successful." << std::endl;
}
@@ -191,27 +223,24 @@ void SOCKS5BytestreamServerManager::handleForwardPortResult(boost::optional<NATP
}
portMapping = mapping;
forwardPortRequest->stop();
forwardPortRequest.reset();
-
- checkInitializeFinished();
}
void SOCKS5BytestreamServerManager::handleUnforwardPortResult(boost::optional<bool> result) {
if (result.is_initialized() && result.get()) {
portMapping.reset();
}
else {
SWIFT_LOG(warning) << "Failed to remove port forwarding." << std::endl;
}
+ attemptedPortMapping_ = false;
unforwardPortRequest.reset();
}
void SOCKS5BytestreamServerManager::checkInitializeFinished() {
assert(state == Initializing);
- if (!getPublicIPRequest && !forwardPortRequest) {
- state = Initialized;
- onInitialized(true);
- }
+ state = Initialized;
+ onInitialized(true);
}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.h b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.h
index abb28b0..e8a43f9 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerManager.h
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerManager.h
@@ -5,12 +5,13 @@
*/
#pragma once
#include <vector>
#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Network/NATPortMapping.h>
namespace Swift {
@@ -19,58 +20,74 @@ namespace Swift {
class NATTraversalGetPublicIPRequest;
class NATTraversalForwardPortRequest;
class NATTraversalRemovePortForwardingRequest;
class SOCKS5BytestreamRegistry;
class ConnectionServerFactory;
class ConnectionServer;
- class SOCKS5BytestreamServerInitializeRequest;
class SOCKS5BytestreamServer;
+ class SOCKS5BytestreamServerResourceUser;
+ class SOCKS5BytestreamServerPortForwardingUser;
class SOCKS5BytestreamServerManager {
+ friend class SOCKS5BytestreamServerResourceUser;
+ friend class SOCKS5BytestreamServerPortForwardingUser;
+
public:
SOCKS5BytestreamServerManager(
SOCKS5BytestreamRegistry* bytestreamRegistry,
ConnectionServerFactory* connectionServerFactory,
NetworkEnvironment* networkEnvironment,
NATTraverser* natTraverser);
~SOCKS5BytestreamServerManager();
- boost::shared_ptr<SOCKS5BytestreamServerInitializeRequest> createInitializeRequest();
+ boost::shared_ptr<SOCKS5BytestreamServerResourceUser> aquireResourceUser();
+ boost::shared_ptr<SOCKS5BytestreamServerPortForwardingUser> aquirePortForwardingUser();
+
void stop();
std::vector<HostAddressPort> getHostAddressPorts() const;
std::vector<HostAddressPort> getAssistedHostAddressPorts() const;
SOCKS5BytestreamServer* getServer() const {
return server;
}
private:
bool isInitialized() const;
void initialize();
+
+ bool isPortForwardingReady() const;
+ void setupPortForwarding();
+ void removePortForwarding();
+
void checkInitializeFinished();
void handleGetPublicIPResult(boost::optional<HostAddress> address);
void handleForwardPortResult(boost::optional<NATPortMapping> mapping);
void handleUnforwardPortResult(boost::optional<bool> result);
boost::signal<void (bool /* success */)> onInitialized;
-
+ boost::signal<void (bool /* success */)> onPortForwardingSetup;
private:
friend class SOCKS5BytestreamServerInitializeRequest;
SOCKS5BytestreamRegistry* bytestreamRegistry;
ConnectionServerFactory* connectionServerFactory;
NetworkEnvironment* networkEnvironment;
NATTraverser* natTraverser;
enum { Start, Initializing, Initialized } state;
SOCKS5BytestreamServer* server;
boost::shared_ptr<ConnectionServer> connectionServer;
int connectionServerPort;
+
boost::shared_ptr<NATTraversalGetPublicIPRequest> getPublicIPRequest;
boost::shared_ptr<NATTraversalForwardPortRequest> forwardPortRequest;
boost::shared_ptr<NATTraversalRemovePortForwardingRequest> unforwardPortRequest;
boost::optional<HostAddress> publicAddress;
boost::optional<NATPortMapping> portMapping;
+ bool attemptedPortMapping_;
+
+ boost::weak_ptr<SOCKS5BytestreamServerResourceUser> s5bServerResourceUser_;
+ boost::weak_ptr<SOCKS5BytestreamServerPortForwardingUser> s5bServerPortForwardingUser_;
};
}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.cpp
new file mode 100644
index 0000000..9ab097b
--- /dev/null
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h>
+
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
+
+#include <boost/bind.hpp>
+
+namespace Swift {
+
+SOCKS5BytestreamServerPortForwardingUser::SOCKS5BytestreamServerPortForwardingUser(SOCKS5BytestreamServerManager* s5bServerManager) : s5bServerManager_(s5bServerManager) {
+ // the server should be initialized, so we know what port to setup a forward for
+ assert(s5bServerManager->isInitialized());
+ assert(!s5bServerManager_->isPortForwardingReady());
+
+ s5bServerManager_->onPortForwardingSetup.connect(boost::bind(&SOCKS5BytestreamServerPortForwardingUser::handleServerManagerPortForwardingSetup, this, _1));
+ s5bServerManager_->setupPortForwarding();
+}
+
+SOCKS5BytestreamServerPortForwardingUser::~SOCKS5BytestreamServerPortForwardingUser() {
+ s5bServerManager_->onPortForwardingSetup.disconnect(boost::bind(&SOCKS5BytestreamServerPortForwardingUser::handleServerManagerPortForwardingSetup, this, _1));
+ if (s5bServerManager_->isPortForwardingReady()) {
+ s5bServerManager_->removePortForwarding();
+ }
+}
+
+bool SOCKS5BytestreamServerPortForwardingUser::isForwardingSetup() const {
+ return s5bServerManager_->isPortForwardingReady();
+}
+
+void SOCKS5BytestreamServerPortForwardingUser::handleServerManagerPortForwardingSetup(bool successful) {
+ onSetup(successful);
+}
+
+}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h b/Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h
new file mode 100644
index 0000000..f486836
--- /dev/null
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerPortForwardingUser.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+
+namespace Swift {
+
+class SOCKS5BytestreamServerManager;
+
+class SOCKS5BytestreamServerPortForwardingUser {
+ public:
+ SOCKS5BytestreamServerPortForwardingUser(SOCKS5BytestreamServerManager* s5bServerManager);
+ ~SOCKS5BytestreamServerPortForwardingUser();
+
+ bool isForwardingSetup() const;
+
+ boost::signal<void (bool /* success */)> onSetup;
+
+ private:
+ void handleServerManagerPortForwardingSetup(bool successful);
+
+ private:
+ SOCKS5BytestreamServerManager* s5bServerManager_;
+};
+
+}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.cpp
new file mode 100644
index 0000000..bf7d4e8
--- /dev/null
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h>
+
+#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
+
+#include <boost/bind.hpp>
+
+namespace Swift {
+
+SOCKS5BytestreamServerResourceUser::SOCKS5BytestreamServerResourceUser(SOCKS5BytestreamServerManager* s5bServerManager) : s5bServerManager_(s5bServerManager) {
+ assert(!s5bServerManager_->isInitialized());
+ s5bServerManager_->onInitialized.connect(boost::bind(&SOCKS5BytestreamServerResourceUser::handleServerManagerInitialized, this, _1));
+ s5bServerManager_->initialize();
+}
+
+SOCKS5BytestreamServerResourceUser::~SOCKS5BytestreamServerResourceUser() {
+ if (s5bServerManager_->isInitialized()) {
+ s5bServerManager_->stop();
+ }
+}
+
+bool SOCKS5BytestreamServerResourceUser::isInitialized() const {
+ return s5bServerManager_->isInitialized();
+}
+
+void SOCKS5BytestreamServerResourceUser::handleServerManagerInitialized(bool successfulInitialize) {
+ onSuccessfulInitialized(successfulInitialize);
+}
+
+}
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h b/Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h
new file mode 100644
index 0000000..014689b
--- /dev/null
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerResourceUser.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+
+namespace Swift {
+
+class SOCKS5BytestreamServerManager;
+
+class SOCKS5BytestreamServerResourceUser {
+ public:
+ SOCKS5BytestreamServerResourceUser(SOCKS5BytestreamServerManager* s5bServerManager);
+ ~SOCKS5BytestreamServerResourceUser();
+
+ bool isInitialized() const;
+
+ boost::signal<void (bool /* success */)> onSuccessfulInitialized;
+
+ private:
+ void handleServerManagerInitialized(bool successfulInitialize);
+
+ private:
+ SOCKS5BytestreamServerManager* s5bServerManager_;
+};
+
+}