summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2015-03-08 15:36:49 (GMT)
committerKevin Smith <kevin.smith@isode.com>2015-05-01 17:14:55 (GMT)
commit794fec2873e69ec047974416768b32b69754dad1 (patch)
treea3cc8cb221e9ee7ad5c40a9de0ccc03e5f9d9562
parentd7bc3a37f4bb261c8520a8ddedcda2369f97361c (diff)
downloadswift-794fec2873e69ec047974416768b32b69754dad1.zip
swift-794fec2873e69ec047974416768b32b69754dad1.tar.bz2
Add resource management for S5B server and port forwardings
This patchs adds management of the SOCKS5 bytestream server and port forwarding setup to Swiften. The first file-transfer, regardless of incoming or outgoing transfer, will start and initialize the S5B server and if configured try to set up port forwarding. The last file-transfer to finish will will close the server and remove the port forwarding. Test-Information: Tested with upcoming ConcurrentFileTransferTest.cpp and running multiple S5B file-transfers in parallel. Change-Id: Idd09d3d0ef9498fc9435b0aee81f2b1061783342
-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
@@ -23,7 +23,8 @@
#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;
@@ -39,7 +40,10 @@ LocalJingleTransportCandidateGenerator::LocalJingleTransportCandidateGenerator(
s5bProxy(s5bProxy),
ownJID(ownJID),
idGenerator(idGenerator),
- options_(options) {
+ options_(options),
+ triedServerInit_(false),
+ triedForwarding_(false),
+ triedProxyDiscovery_(false) {
}
LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator() {
@@ -48,43 +52,69 @@ LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator(
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;
@@ -116,7 +146,7 @@ void LocalJingleTransportCandidateGenerator::emitOnLocalTransportCandidatesGener
}
}
- 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;
@@ -135,29 +165,4 @@ 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
@@ -26,6 +26,8 @@ namespace Swift {
class SOCKS5BytestreamServerManager;
class SOCKS5BytestreamProxiesManager;
class SOCKS5BytestreamServerInitializeRequest;
+ class SOCKS5BytestreamServerResourceUser;
+ class SOCKS5BytestreamServerPortForwardingUser;
class JingleS5BTransportPayload;
class LocalJingleTransportCandidateGenerator {
@@ -45,6 +47,7 @@ namespace Swift {
private:
void handleS5BServerInitialized(bool success);
+ void handlePortForwardingSetup(bool success);
void handleDiscoveredProxiesChanged();
void checkS5BCandidatesReady();
@@ -56,6 +59,11 @@ namespace Swift {
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
@@ -26,7 +26,6 @@ sources = [
"IBBSendTransportSession.cpp",
"IBBReceiveTransportSession.cpp",
"SOCKS5BytestreamClientSession.cpp",
- "SOCKS5BytestreamServerInitializeRequest.cpp",
"SOCKS5BytestreamServerManager.cpp",
"SOCKS5BytestreamServer.cpp",
"SOCKS5BytestreamServerSession.cpp",
@@ -38,6 +37,8 @@ sources = [
"FileTransferManager.cpp",
"FileTransferManagerImpl.cpp",
"IncrementalBytestreamHashCalculator.cpp",
+ "SOCKS5BytestreamServerResourceUser.cpp",
+ "SOCKS5BytestreamServerPortForwardingUser.cpp",
]
swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources))
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
@@ -15,7 +15,8 @@
#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>
@@ -42,7 +43,8 @@ SOCKS5BytestreamServerManager::SOCKS5BytestreamServerManager(
networkEnvironment(networkEnvironment),
natTraverser(natTraverser),
state(Start),
- server(NULL) {
+ server(NULL),
+ attemptedPortMapping_(false) {
}
SOCKS5BytestreamServerManager::~SOCKS5BytestreamServerManager() {
@@ -57,9 +59,28 @@ SOCKS5BytestreamServerManager::~SOCKS5BytestreamServerManager() {
}
}
+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 {
@@ -121,24 +142,44 @@ void SOCKS5BytestreamServerManager::initialize() {
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();
}
}
@@ -156,13 +197,6 @@ void SOCKS5BytestreamServerManager::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;
}
@@ -178,8 +212,6 @@ void SOCKS5BytestreamServerManager::handleGetPublicIPResult(boost::optional<Host
getPublicIPRequest->stop();
getPublicIPRequest.reset();
-
- checkInitializeFinished();
}
void SOCKS5BytestreamServerManager::handleForwardPortResult(boost::optional<NATPortMapping> mapping) {
@@ -194,8 +226,6 @@ void SOCKS5BytestreamServerManager::handleForwardPortResult(boost::optional<NATP
forwardPortRequest->stop();
forwardPortRequest.reset();
-
- checkInitializeFinished();
}
void SOCKS5BytestreamServerManager::handleUnforwardPortResult(boost::optional<bool> result) {
@@ -205,13 +235,12 @@ void SOCKS5BytestreamServerManager::handleUnforwardPortResult(boost::optional<bo
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
@@ -8,6 +8,7 @@
#include <vector>
#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/HostAddressPort.h>
@@ -22,10 +23,14 @@ namespace Swift {
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,
@@ -34,7 +39,9 @@ namespace Swift {
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;
@@ -47,6 +54,11 @@ namespace Swift {
private:
bool isInitialized() const;
void initialize();
+
+ bool isPortForwardingReady() const;
+ void setupPortForwarding();
+ void removePortForwarding();
+
void checkInitializeFinished();
void handleGetPublicIPResult(boost::optional<HostAddress> address);
@@ -54,7 +66,7 @@ namespace Swift {
void handleUnforwardPortResult(boost::optional<bool> result);
boost::signal<void (bool /* success */)> onInitialized;
-
+ boost::signal<void (bool /* success */)> onPortForwardingSetup;
private:
friend class SOCKS5BytestreamServerInitializeRequest;
@@ -66,11 +78,16 @@ namespace Swift {
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_;
+};
+
+}