summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Network')
-rw-r--r--Swiften/Network/BOSHConnection.cpp36
-rw-r--r--Swiften/Network/BOSHConnection.h5
-rw-r--r--Swiften/Network/BOSHConnectionPool.cpp40
-rw-r--r--Swiften/Network/BOSHConnectionPool.h8
-rw-r--r--Swiften/Network/BoostConnection.cpp3
-rw-r--r--Swiften/Network/BoostConnection.h3
-rw-r--r--Swiften/Network/BoostConnectionServer.cpp18
-rw-r--r--Swiften/Network/BoostConnectionServer.h12
-rw-r--r--Swiften/Network/BoostIOServiceThread.h4
-rw-r--r--Swiften/Network/BoostNetworkFactories.cpp30
-rw-r--r--Swiften/Network/BoostNetworkFactories.h39
-rw-r--r--Swiften/Network/CachingDomainNameResolver.cpp30
-rw-r--r--Swiften/Network/CachingDomainNameResolver.h (renamed from Swiften/Network/CachingNameOnlyDomainNameResolver.h)17
-rw-r--r--Swiften/Network/CachingNameOnlyDomainNameResolver.cpp32
-rw-r--r--Swiften/Network/ChainedConnector.cpp6
-rw-r--r--Swiften/Network/ChainedConnector.h10
-rw-r--r--Swiften/Network/Connection.h3
-rw-r--r--Swiften/Network/ConnectionFactory.h4
-rw-r--r--Swiften/Network/ConnectionServer.h13
-rw-r--r--Swiften/Network/Connector.cpp29
-rw-r--r--Swiften/Network/Connector.h16
-rw-r--r--Swiften/Network/DomainNameResolver.h7
-rw-r--r--Swiften/Network/DomainNameServiceQuery.cpp29
-rw-r--r--Swiften/Network/DomainNameServiceQuery.h3
-rw-r--r--Swiften/Network/DummyConnection.h3
-rw-r--r--Swiften/Network/DummyTimerFactory.h3
-rw-r--r--Swiften/Network/FakeConnection.cpp4
-rw-r--r--Swiften/Network/FakeConnection.h3
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnection.cpp102
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnection.h48
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp6
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnectionFactory.h5
-rw-r--r--Swiften/Network/HostAddress.cpp15
-rw-r--r--Swiften/Network/HostAddress.h9
-rw-r--r--Swiften/Network/HostAddressPort.h3
-rw-r--r--Swiften/Network/HostNameOrAddress.cpp29
-rw-r--r--Swiften/Network/HostNameOrAddress.h16
-rw-r--r--Swiften/Network/MacOSXProxyProvider.cpp17
-rw-r--r--Swiften/Network/MiniUPnPInterface.cpp54
-rw-r--r--Swiften/Network/MiniUPnPInterface.h16
-rw-r--r--Swiften/Network/NATPMPInterface.cpp56
-rw-r--r--Swiften/Network/NATPMPInterface.h11
-rw-r--r--Swiften/Network/NATPortMapping.h5
-rw-r--r--Swiften/Network/NATTraversalForwardPortRequest.h6
-rw-r--r--Swiften/Network/NATTraversalGetPublicIPRequest.h3
-rw-r--r--Swiften/Network/NATTraversalRemovePortForwardingRequest.h5
-rw-r--r--Swiften/Network/NetworkEnvironment.h3
-rw-r--r--Swiften/Network/NetworkFactories.h8
-rw-r--r--Swiften/Network/NullNATTraverser.cpp15
-rw-r--r--Swiften/Network/PlatformDomainNameAddressQuery.cpp10
-rw-r--r--Swiften/Network/PlatformDomainNameAddressQuery.h3
-rw-r--r--Swiften/Network/PlatformDomainNameResolver.cpp17
-rw-r--r--Swiften/Network/PlatformDomainNameResolver.h12
-rw-r--r--Swiften/Network/PlatformDomainNameServiceQuery.cpp18
-rw-r--r--Swiften/Network/PlatformDomainNameServiceQuery.h5
-rw-r--r--Swiften/Network/PlatformNATTraversalWorker.cpp52
-rw-r--r--Swiften/Network/PlatformNATTraversalWorker.h10
-rw-r--r--Swiften/Network/PlatformNetworkEnvironment.h6
-rw-r--r--Swiften/Network/ProxiedConnection.cpp112
-rw-r--r--Swiften/Network/ProxiedConnection.h67
-rw-r--r--Swiften/Network/ProxyProvider.h1
-rw-r--r--Swiften/Network/SConscript32
-rw-r--r--Swiften/Network/SOCKS5ProxiedConnection.cpp108
-rw-r--r--Swiften/Network/SOCKS5ProxiedConnection.h46
-rw-r--r--Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp4
-rw-r--r--Swiften/Network/SOCKS5ProxiedConnectionFactory.h11
-rw-r--r--Swiften/Network/SolarisNetworkEnvironment.cpp292
-rw-r--r--Swiften/Network/SolarisNetworkEnvironment.h29
-rw-r--r--Swiften/Network/StaticDomainNameResolver.cpp4
-rw-r--r--Swiften/Network/StaticDomainNameResolver.h5
-rw-r--r--Swiften/Network/TLSConnection.h2
-rw-r--r--Swiften/Network/Timer.h3
-rw-r--r--Swiften/Network/TimerFactory.h3
-rwxr-xr-xSwiften/Network/UnboundDomainNameResolver.cpp247
-rwxr-xr-xSwiften/Network/UnboundDomainNameResolver.h53
-rw-r--r--Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp26
-rw-r--r--Swiften/Network/UnitTest/BOSHConnectionTest.cpp6
-rw-r--r--Swiften/Network/UnitTest/ChainedConnectorTest.cpp2
-rw-r--r--Swiften/Network/UnitTest/ConnectorTest.cpp75
-rw-r--r--Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp2
-rw-r--r--Swiften/Network/UnixNetworkEnvironment.cpp9
-rw-r--r--Swiften/Network/WindowsNetworkEnvironment.cpp2
-rw-r--r--Swiften/Network/WindowsNetworkEnvironment.h5
-rw-r--r--Swiften/Network/WindowsProxyProvider.h4
84 files changed, 1598 insertions, 527 deletions
diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp
index 73f8ed6..28e27d5 100644
--- a/Swiften/Network/BOSHConnection.cpp
+++ b/Swiften/Network/BOSHConnection.cpp
@@ -6,5 +6,5 @@
/*
- * Copyright (c) 2011 Kevin Smith
+ * Copyright (c) 2011-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -33,4 +33,5 @@ BOSHConnection::BOSHConnection(const URL& boshURL, Connector::ref connector, XML
sid_(),
waitingForStartResponse_(false),
+ rid_(~0ULL),
pending_(false),
connectionReady_(false)
@@ -61,9 +62,12 @@ void BOSHConnection::cancelConnector() {
void BOSHConnection::disconnect() {
- cancelConnector();
if (connection_) {
connection_->disconnect();
sid_ = "";
}
+ else {
+ /* handleDisconnected takes care of the connector_ as well */
+ handleDisconnected(boost::optional<Connection::Error>());
+ }
}
@@ -102,7 +106,11 @@ std::pair<SafeByteArray, size_t> BOSHConnection::createHTTPRequest(const SafeByt
size = safeContent.size();
- header << "POST /" << boshURL.getPath() << " HTTP/1.1\r\n"
- << "Host: " << boshURL.getHost() << ":" << boshURL.getPort() << "\r\n"
- /*<< "Accept-Encoding: deflate\r\n"*/
+ header << "POST " << boshURL.getPath() << " HTTP/1.1\r\n"
+ << "Host: " << boshURL.getHost();
+ if (boshURL.getPort()) {
+ header << ":" << *boshURL.getPort();
+ }
+ header << "\r\n"
+ // << "Accept-Encoding: deflate\r\n"
<< "Content-Type: text/xml; charset=utf-8\r\n"
<< "Content-Length: " << size << "\r\n\r\n";
@@ -129,5 +137,5 @@ void BOSHConnection::write(const SafeByteArray& data, bool streamRestart, bool t
void BOSHConnection::handleConnectFinished(Connection::ref connection) {
cancelConnector();
- connectionReady_ = connection;
+ connectionReady_ = !!connection;
if (connectionReady_) {
connection_ = connection;
@@ -150,5 +158,5 @@ void BOSHConnection::startStream(const std::string& to, unsigned long long rid)
<< " ver='1.6'"
<< " wait='60'" /* FIXME: we probably want this configurable*/
- /*<< " ack='0'" FIXME: support acks */
+ // << " ack='0'" FIXME: support acks
<< " xml:lang='en'"
<< " xmlns:xmpp='urn:xmpp:bosh'"
@@ -158,7 +166,11 @@ void BOSHConnection::startStream(const std::string& to, unsigned long long rid)
std::string contentString = content.str();
- header << "POST /" << boshURL_.getPath() << " HTTP/1.1\r\n"
- << "Host: " << boshURL_.getHost() << ":" << boshURL_.getPort() << "\r\n"
- /*<< "Accept-Encoding: deflate\r\n"*/
+ header << "POST " << boshURL_.getPath() << " HTTP/1.1\r\n"
+ << "Host: " << boshURL_.getHost();
+ if (boshURL_.getPort()) {
+ header << ":" << *boshURL_.getPort();
+ }
+ header << "\r\n"
+ // << "Accept-Encoding: deflate\r\n"
<< "Content-Type: text/xml; charset=utf-8\r\n"
<< "Content-Length: " << contentString.size() << "\r\n\r\n"
@@ -198,5 +210,5 @@ void BOSHConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
sid_ = parser.getBody()->attributes.getAttribute("sid");
std::string requestsString = parser.getBody()->attributes.getAttribute("requests");
- int requests = 2;
+ size_t requests = 2;
if (!requestsString.empty()) {
try {
@@ -274,5 +286,5 @@ void BOSHConnection::setSID(const std::string& sid) {
void BOSHConnection::handleDisconnected(const boost::optional<Connection::Error>& error) {
cancelConnector();
- onDisconnected(error);
+ onDisconnected(error ? true : false);
sid_ = "";
connectionReady_ = false;
diff --git a/Swiften/Network/BOSHConnection.h b/Swiften/Network/BOSHConnection.h
index a2abfcd..01341cc 100644
--- a/Swiften/Network/BOSHConnection.h
+++ b/Swiften/Network/BOSHConnection.h
@@ -16,4 +16,5 @@
#include <boost/enable_shared_from_this.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/Connector.h>
@@ -37,5 +38,5 @@ namespace Swift {
class TLSContextFactory;
- class BOSHError : public SessionStream::SessionStreamError {
+ class SWIFTEN_API BOSHError : public SessionStream::SessionStreamError {
public:
enum Type {BadRequest, HostGone, HostUnknown, ImproperAddressing,
@@ -52,5 +53,5 @@ namespace Swift {
- class BOSHConnection : public boost::enable_shared_from_this<BOSHConnection> {
+ class SWIFTEN_API BOSHConnection : public boost::enable_shared_from_this<BOSHConnection> {
public:
typedef boost::shared_ptr<BOSHConnection> ref;
diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp
index bb24aa5..fdfe420 100644
--- a/Swiften/Network/BOSHConnectionPool.cpp
+++ b/Swiften/Network/BOSHConnectionPool.cpp
@@ -15,5 +15,5 @@
#include <Swiften/Network/TLSConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>
-#include <Swiften/Network/CachingNameOnlyDomainNameResolver.h>
+#include <Swiften/Network/CachingDomainNameResolver.h>
namespace Swift {
@@ -22,5 +22,4 @@ BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* r
connectionFactory(connectionFactoryParameter),
xmlParserFactory(parserFactory),
- tlsFactory(tlsFactory),
timerFactory(timerFactory),
rid(initialRID),
@@ -31,10 +30,10 @@ BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* r
pendingRestart(false) {
- if (!boshHTTPConnectProxyURL.empty()) {
+ if (!boshHTTPConnectProxyURL.isEmpty()) {
if (boshHTTPConnectProxyURL.getScheme() == "https") {
connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory);
myConnectionFactories.push_back(connectionFactory);
}
- connectionFactory = new HTTPConnectProxiedConnectionFactory(realResolver, connectionFactory, timerFactory, eventLoop, boshHTTPConnectProxyURL.getHost(), boshHTTPConnectProxyURL.getPort(), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
+ connectionFactory = new HTTPConnectProxiedConnectionFactory(realResolver, connectionFactory, timerFactory, boshHTTPConnectProxyURL.getHost(), URL::getPortOrDefaultPort(boshHTTPConnectProxyURL), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
}
if (boshURL.getScheme() == "https") {
@@ -42,10 +41,17 @@ BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* r
myConnectionFactories.push_back(connectionFactory);
}
- resolver = new CachingNameOnlyDomainNameResolver(realResolver, eventLoop);
+ resolver = new CachingDomainNameResolver(realResolver, eventLoop);
createConnection();
}
BOSHConnectionPool::~BOSHConnectionPool() {
- close();
+ /* Don't do a normal close here. Instead kill things forcibly, as close() or writeFooter() will already have been called */
+ std::vector<BOSHConnection::ref> connectionCopies = connections;
+ foreach (BOSHConnection::ref connection, connectionCopies) {
+ if (connection) {
+ destroyConnection(connection);
+ connection->disconnect();
+ }
+ }
foreach (ConnectionFactory* factory, myConnectionFactories) {
delete factory;
@@ -84,10 +90,14 @@ void BOSHConnectionPool::writeFooter() {
void BOSHConnectionPool::close() {
- /* TODO: Send a terminate here. */
+ if (!sid.empty()) {
+ writeFooter();
+ }
+ else {
+ pendingTerminate = true;
std::vector<BOSHConnection::ref> connectionCopies = connections;
foreach (BOSHConnection::ref connection, connectionCopies) {
if (connection) {
connection->disconnect();
- destroyConnection(connection);
+ }
}
}
@@ -160,5 +170,6 @@ void BOSHConnectionPool::tryToSendQueuedData() {
suitableConnection->setRID(rid);
suitableConnection->terminateStream();
- onSessionTerminated(boost::shared_ptr<BOSHError>());
+ sid = "";
+ close();
}
}
@@ -200,9 +211,12 @@ void BOSHConnectionPool::handleHTTPError(const std::string& /*errorCode*/) {
}
-void BOSHConnectionPool::handleConnectionDisconnected(bool error, BOSHConnection::ref connection) {
+void BOSHConnectionPool::handleConnectionDisconnected(bool/* error*/, BOSHConnection::ref connection) {
destroyConnection(connection);
- if (false && error) {
- handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition));
+ if (pendingTerminate && sid.empty() && connections.empty()) {
+ handleSessionTerminated(BOSHError::ref());
}
+ //else if (error) {
+ // handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition));
+ //}
else {
/* We might have just freed up a connection slot to send with */
@@ -212,5 +226,5 @@ void BOSHConnectionPool::handleConnectionDisconnected(bool error, BOSHConnection
boost::shared_ptr<BOSHConnection> BOSHConnectionPool::createConnection() {
- Connector::ref connector = Connector::create(boshURL.getHost(), resolver, connectionFactory, timerFactory, boshURL.getPort());
+ Connector::ref connector = Connector::create(boshURL.getHost(), URL::getPortOrDefaultPort(boshURL), boost::optional<std::string>(), resolver, connectionFactory, timerFactory);
BOSHConnection::ref connection = BOSHConnection::create(boshURL, connector, xmlParserFactory);
connection->onXMPPDataRead.connect(boost::bind(&BOSHConnectionPool::handleDataRead, this, _1));
diff --git a/Swiften/Network/BOSHConnectionPool.h b/Swiften/Network/BOSHConnectionPool.h
index 8bc0a7c..de707e8 100644
--- a/Swiften/Network/BOSHConnectionPool.h
+++ b/Swiften/Network/BOSHConnectionPool.h
@@ -10,4 +10,5 @@
#include <vector>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/SafeString.h>
#include <Swiften/Network/BOSHConnection.h>
@@ -16,8 +17,8 @@ namespace Swift {
class HTTPConnectProxiedConnectionFactory;
class TLSConnectionFactory;
- class CachingNameOnlyDomainNameResolver;
+ class CachingDomainNameResolver;
class EventLoop;
- class BOSHConnectionPool : public boost::bsignals::trackable {
+ class SWIFTEN_API BOSHConnectionPool : public boost::bsignals::trackable {
public:
BOSHConnectionPool(const URL& boshURL, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword);
@@ -54,5 +55,4 @@ namespace Swift {
ConnectionFactory* connectionFactory;
XMLParserFactory* xmlParserFactory;
- TLSContextFactory* tlsFactory;
TimerFactory* timerFactory;
std::vector<BOSHConnection::ref> connections;
@@ -66,5 +66,5 @@ namespace Swift {
bool pendingRestart;
std::vector<ConnectionFactory*> myConnectionFactories;
- CachingNameOnlyDomainNameResolver* resolver;
+ CachingDomainNameResolver* resolver;
};
}
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp
index 1d4bd32..5137c3c 100644
--- a/Swiften/Network/BoostConnection.cpp
+++ b/Swiften/Network/BoostConnection.cpp
@@ -15,4 +15,5 @@
#include <boost/asio/write.hpp>
#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <Swiften/Base/Log.h>
@@ -64,5 +65,5 @@ void BoostConnection::listen() {
void BoostConnection::connect(const HostAddressPort& addressPort) {
boost::asio::ip::tcp::endpoint endpoint(
- boost::asio::ip::address::from_string(addressPort.getAddress().toString()), addressPort.getPort());
+ boost::asio::ip::address::from_string(addressPort.getAddress().toString()), boost::numeric_cast<unsigned short>(addressPort.getPort()));
socket_.async_connect(
endpoint,
diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h
index 0e29c54..636853a 100644
--- a/Swiften/Network/BoostConnection.h
+++ b/Swiften/Network/BoostConnection.h
@@ -12,4 +12,5 @@
#include <boost/thread/mutex.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/EventLoop/EventOwner.h>
@@ -26,5 +27,5 @@ namespace Swift {
class EventLoop;
- class BoostConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<BoostConnection> {
+ class SWIFTEN_API BoostConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<BoostConnection> {
public:
typedef boost::shared_ptr<BoostConnection> ref;
diff --git a/Swiften/Network/BoostConnectionServer.cpp b/Swiften/Network/BoostConnectionServer.cpp
index eccffc6..c90b554 100644
--- a/Swiften/Network/BoostConnectionServer.cpp
+++ b/Swiften/Network/BoostConnectionServer.cpp
@@ -10,4 +10,6 @@
#include <boost/system/system_error.hpp>
#include <boost/asio/placeholders.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/optional.hpp>
#include <Swiften/EventLoop/EventLoop.h>
@@ -22,4 +24,11 @@ BoostConnectionServer::BoostConnectionServer(const HostAddress &address, int por
void BoostConnectionServer::start() {
+ boost::optional<Error> error = tryStart();
+ if (error) {
+ eventLoop->postEvent(boost::bind(boost::ref(onStopped), *error), shared_from_this());
+ }
+}
+
+boost::optional<BoostConnectionServer::Error> BoostConnectionServer::tryStart() {
try {
assert(!acceptor_);
@@ -27,10 +36,10 @@ void BoostConnectionServer::start() {
acceptor_ = new boost::asio::ip::tcp::acceptor(
*ioService_,
- boost::asio::ip::tcp::endpoint(address_.getRawAddress(), port_));
+ boost::asio::ip::tcp::endpoint(address_.getRawAddress(), boost::numeric_cast<unsigned short>(port_)));
}
else {
acceptor_ = new boost::asio::ip::tcp::acceptor(
*ioService_,
- boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port_));
+ boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), boost::numeric_cast<unsigned short>(port_)));
}
acceptNextConnection();
@@ -38,10 +47,11 @@ void BoostConnectionServer::start() {
catch (const boost::system::system_error& e) {
if (e.code() == boost::asio::error::address_in_use) {
- eventLoop->postEvent(boost::bind(boost::ref(onStopped), Conflict), shared_from_this());
+ return Conflict;
}
else {
- eventLoop->postEvent(boost::bind(boost::ref(onStopped), UnknownError), shared_from_this());
+ return UnknownError;
}
}
+ return boost::optional<Error>();
}
diff --git a/Swiften/Network/BoostConnectionServer.h b/Swiften/Network/BoostConnectionServer.h
index 56dc8bd..3ad0450 100644
--- a/Swiften/Network/BoostConnectionServer.h
+++ b/Swiften/Network/BoostConnectionServer.h
@@ -11,20 +11,17 @@
#include <boost/asio/ip/tcp.hpp>
#include <boost/enable_shared_from_this.hpp>
-#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
+#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/BoostConnection.h>
#include <Swiften/Network/ConnectionServer.h>
#include <Swiften/EventLoop/EventOwner.h>
+#include <boost/optional/optional_fwd.hpp>
namespace Swift {
- class BoostConnectionServer : public ConnectionServer, public EventOwner, public boost::enable_shared_from_this<BoostConnectionServer> {
+ class SWIFTEN_API BoostConnectionServer : public ConnectionServer, public EventOwner, public boost::enable_shared_from_this<BoostConnectionServer> {
public:
typedef boost::shared_ptr<BoostConnectionServer> ref;
- enum Error {
- Conflict,
- UnknownError
- };
-
static ref create(int port, boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) {
return ref(new BoostConnectionServer(port, ioService, eventLoop));
@@ -35,4 +32,5 @@ namespace Swift {
}
+ virtual boost::optional<Error> tryStart(); // FIXME: This should become the new start
virtual void start();
virtual void stop();
diff --git a/Swiften/Network/BoostIOServiceThread.h b/Swiften/Network/BoostIOServiceThread.h
index 00fb397..d1a5f37 100644
--- a/Swiften/Network/BoostIOServiceThread.h
+++ b/Swiften/Network/BoostIOServiceThread.h
@@ -11,6 +11,8 @@
#include <boost/shared_ptr.hpp>
+#include <Swiften/Base/API.h>
+
namespace Swift {
- class BoostIOServiceThread {
+ class SWIFTEN_API BoostIOServiceThread {
public:
BoostIOServiceThread();
diff --git a/Swiften/Network/BoostNetworkFactories.cpp b/Swiften/Network/BoostNetworkFactories.cpp
index 488e519..870ae97 100644
--- a/Swiften/Network/BoostNetworkFactories.cpp
+++ b/Swiften/Network/BoostNetworkFactories.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -8,11 +8,22 @@
#include <Swiften/Network/BoostTimerFactory.h>
#include <Swiften/Network/BoostConnectionFactory.h>
-#include <Swiften/Network/PlatformDomainNameResolver.h>
+
#include <Swiften/Network/BoostConnectionServerFactory.h>
#include <Swiften/Network/PlatformNATTraversalWorker.h>
#include <Swiften/Parser/PlatformXMLParserFactory.h>
#include <Swiften/Network/NullNATTraverser.h>
+#include <Swiften/Network/PlatformNetworkEnvironment.h>
#include <Swiften/TLS/PlatformTLSFactories.h>
#include <Swiften/Network/PlatformProxyProvider.h>
+#include <Swiften/IDN/PlatformIDNConverter.h>
+#include <Swiften/IDN/IDNConverter.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+
+#ifdef USE_UNBOUND
+#include <Swiften/Network/UnboundDomainNameResolver.h>
+#else
+#include <Swiften/Network/PlatformDomainNameResolver.h>
+#endif
namespace Swift {
@@ -21,5 +32,4 @@ BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) : eventLoop(e
timerFactory = new BoostTimerFactory(ioServiceThread.getIOService(), eventLoop);
connectionFactory = new BoostConnectionFactory(ioServiceThread.getIOService(), eventLoop);
- domainNameResolver = new PlatformDomainNameResolver(eventLoop);
connectionServerFactory = new BoostConnectionServerFactory(ioServiceThread.getIOService(), eventLoop);
#ifdef SWIFT_EXPERIMENTAL_FT
@@ -28,16 +38,28 @@ BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) : eventLoop(e
natTraverser = new NullNATTraverser(eventLoop);
#endif
+ networkEnvironment = new PlatformNetworkEnvironment();
xmlParserFactory = new PlatformXMLParserFactory();
tlsFactories = new PlatformTLSFactories();
proxyProvider = new PlatformProxyProvider();
+ idnConverter = PlatformIDNConverter::create();
+#ifdef USE_UNBOUND
+ // TODO: What to do about idnConverter.
+ domainNameResolver = new UnboundDomainNameResolver(idnConverter, ioServiceThread.getIOService(), eventLoop);
+#else
+ domainNameResolver = new PlatformDomainNameResolver(idnConverter, eventLoop);
+#endif
+ cryptoProvider = PlatformCryptoProvider::create();
}
BoostNetworkFactories::~BoostNetworkFactories() {
+ delete cryptoProvider;
+ delete domainNameResolver;
+ delete idnConverter;
delete proxyProvider;
delete tlsFactories;
delete xmlParserFactory;
+ delete networkEnvironment;
delete natTraverser;
delete connectionServerFactory;
- delete domainNameResolver;
delete connectionFactory;
delete timerFactory;
diff --git a/Swiften/Network/BoostNetworkFactories.h b/Swiften/Network/BoostNetworkFactories.h
index c9b12da..9c3bab1 100644
--- a/Swiften/Network/BoostNetworkFactories.h
+++ b/Swiften/Network/BoostNetworkFactories.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -7,4 +7,6 @@
#pragma once
+#include <Swiften/Base/API.h>
+#include <Swiften/Base/Override.h>
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/Network/BoostIOServiceThread.h>
@@ -15,14 +17,14 @@ namespace Swift {
class PlatformTLSFactories;
- class BoostNetworkFactories : public NetworkFactories {
+ class SWIFTEN_API BoostNetworkFactories : public NetworkFactories {
public:
BoostNetworkFactories(EventLoop* eventLoop);
~BoostNetworkFactories();
- virtual TimerFactory* getTimerFactory() const {
+ virtual TimerFactory* getTimerFactory() const SWIFTEN_OVERRIDE {
return timerFactory;
}
- virtual ConnectionFactory* getConnectionFactory() const {
+ virtual ConnectionFactory* getConnectionFactory() const SWIFTEN_OVERRIDE {
return connectionFactory;
}
@@ -32,30 +34,42 @@ namespace Swift {
}
- DomainNameResolver* getDomainNameResolver() const {
+ DomainNameResolver* getDomainNameResolver() const SWIFTEN_OVERRIDE {
return domainNameResolver;
}
- ConnectionServerFactory* getConnectionServerFactory() const {
+ ConnectionServerFactory* getConnectionServerFactory() const SWIFTEN_OVERRIDE {
return connectionServerFactory;
}
- NATTraverser* getNATTraverser() const {
+ NetworkEnvironment* getNetworkEnvironment() const SWIFTEN_OVERRIDE {
+ return networkEnvironment;
+ }
+
+ NATTraverser* getNATTraverser() const SWIFTEN_OVERRIDE {
return natTraverser;
}
- virtual XMLParserFactory* getXMLParserFactory() const {
+ virtual XMLParserFactory* getXMLParserFactory() const SWIFTEN_OVERRIDE {
return xmlParserFactory;
}
- virtual TLSContextFactory* getTLSContextFactory() const;
+ virtual TLSContextFactory* getTLSContextFactory() const SWIFTEN_OVERRIDE;
- virtual ProxyProvider* getProxyProvider() const {
+ virtual ProxyProvider* getProxyProvider() const SWIFTEN_OVERRIDE {
return proxyProvider;
}
- virtual EventLoop* getEventLoop() const {
+ virtual EventLoop* getEventLoop() const SWIFTEN_OVERRIDE {
return eventLoop;
}
+ virtual IDNConverter* getIDNConverter() const SWIFTEN_OVERRIDE {
+ return idnConverter;
+ }
+
+ virtual CryptoProvider* getCryptoProvider() const SWIFTEN_OVERRIDE {
+ return cryptoProvider;
+ }
+
private:
BoostIOServiceThread ioServiceThread;
@@ -65,8 +79,11 @@ namespace Swift {
ConnectionServerFactory* connectionServerFactory;
NATTraverser* natTraverser;
+ NetworkEnvironment* networkEnvironment;
XMLParserFactory* xmlParserFactory;
PlatformTLSFactories* tlsFactories;
ProxyProvider* proxyProvider;
EventLoop* eventLoop;
+ IDNConverter* idnConverter;
+ CryptoProvider* cryptoProvider;
};
}
diff --git a/Swiften/Network/CachingDomainNameResolver.cpp b/Swiften/Network/CachingDomainNameResolver.cpp
new file mode 100644
index 0000000..fea14a3
--- /dev/null
+++ b/Swiften/Network/CachingDomainNameResolver.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Network/CachingDomainNameResolver.h>
+
+#include <boost/smart_ptr/make_shared.hpp>
+
+namespace Swift {
+
+CachingDomainNameResolver::CachingDomainNameResolver(DomainNameResolver* realResolver, EventLoop*) : realResolver(realResolver) {
+}
+
+CachingDomainNameResolver::~CachingDomainNameResolver() {
+
+}
+
+DomainNameServiceQuery::ref CachingDomainNameResolver::createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) {
+ //TODO: Cache
+ return realResolver->createServiceQuery(serviceLookupPrefix, domain);
+}
+
+DomainNameAddressQuery::ref CachingDomainNameResolver::createAddressQuery(const std::string& name) {
+ //TODO: Cache
+ return realResolver->createAddressQuery(name);
+}
+
+}
diff --git a/Swiften/Network/CachingNameOnlyDomainNameResolver.h b/Swiften/Network/CachingDomainNameResolver.h
index d9e78e6..3d50676 100644
--- a/Swiften/Network/CachingNameOnlyDomainNameResolver.h
+++ b/Swiften/Network/CachingDomainNameResolver.h
@@ -12,21 +12,20 @@
#include <Swiften/Network/StaticDomainNameResolver.h>
-
+/*
+ * FIXME: Does not do any caching yet.
+ */
namespace Swift {
class EventLoop;
- class CachingNameOnlyDomainNameResolver : public DomainNameResolver {
+
+ class CachingDomainNameResolver : public DomainNameResolver {
public:
- CachingNameOnlyDomainNameResolver(DomainNameResolver* realResolver, EventLoop* eventLoop);
- ~CachingNameOnlyDomainNameResolver();
+ CachingDomainNameResolver(DomainNameResolver* realResolver, EventLoop* eventLoop);
+ ~CachingDomainNameResolver();
- virtual DomainNameServiceQuery::ref createServiceQuery(const std::string& name);
+ virtual DomainNameServiceQuery::ref createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain);
virtual DomainNameAddressQuery::ref createAddressQuery(const std::string& name);
private:
- void handleAddressQueryResult(const std::string hostname, const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error);
-
- private:
DomainNameResolver* realResolver;
- boost::shared_ptr<StaticDomainNameResolver> staticResolver;
};
}
diff --git a/Swiften/Network/CachingNameOnlyDomainNameResolver.cpp b/Swiften/Network/CachingNameOnlyDomainNameResolver.cpp
deleted file mode 100644
index a83bebd..0000000
--- a/Swiften/Network/CachingNameOnlyDomainNameResolver.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2012 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/Network/CachingNameOnlyDomainNameResolver.h>
-
-#include <boost/smart_ptr/make_shared.hpp>
-
-namespace Swift {
-CachingNameOnlyDomainNameResolver::CachingNameOnlyDomainNameResolver(DomainNameResolver* realResolver, EventLoop* eventLoop) : realResolver(realResolver) {
- staticResolver = boost::make_shared<StaticDomainNameResolver>(eventLoop);
-}
-
-CachingNameOnlyDomainNameResolver::~CachingNameOnlyDomainNameResolver() {
-
-}
-
-DomainNameServiceQuery::ref CachingNameOnlyDomainNameResolver::createServiceQuery(const std::string& name) {
- return staticResolver->createServiceQuery(name);
-}
-
-DomainNameAddressQuery::ref CachingNameOnlyDomainNameResolver::createAddressQuery(const std::string& name) {
- return realResolver->createAddressQuery(name);
-}
-
-void CachingNameOnlyDomainNameResolver::handleAddressQueryResult(const std::string hostname, const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error) {
- //FIXME: Cache
-}
-
-}
diff --git a/Swiften/Network/ChainedConnector.cpp b/Swiften/Network/ChainedConnector.cpp
index 0a1283f..14d66ae 100644
--- a/Swiften/Network/ChainedConnector.cpp
+++ b/Swiften/Network/ChainedConnector.cpp
@@ -19,8 +19,12 @@ using namespace Swift;
ChainedConnector::ChainedConnector(
const std::string& hostname,
+ int port,
+ const boost::optional<std::string>& serviceLookupPrefix,
DomainNameResolver* resolver,
const std::vector<ConnectionFactory*>& connectionFactories,
TimerFactory* timerFactory) :
hostname(hostname),
+ port(port),
+ serviceLookupPrefix(serviceLookupPrefix),
resolver(resolver),
connectionFactories(connectionFactories),
@@ -59,5 +63,5 @@ void ChainedConnector::tryNextConnectionFactory() {
SWIFT_LOG(debug) << "Trying next connection factory: " << typeid(*connectionFactory).name() << std::endl;
connectionFactoryQueue.pop_front();
- currentConnector = Connector::create(hostname, resolver, connectionFactory, timerFactory);
+ currentConnector = Connector::create(hostname, port, serviceLookupPrefix, resolver, connectionFactory, timerFactory);
currentConnector->setTimeoutMilliseconds(timeoutMilliseconds);
currentConnector->onConnectFinished.connect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1, _2));
diff --git a/Swiften/Network/ChainedConnector.h b/Swiften/Network/ChainedConnector.h
index 12ef023..0a1cca9 100644
--- a/Swiften/Network/ChainedConnector.h
+++ b/Swiften/Network/ChainedConnector.h
@@ -11,5 +11,7 @@
#include <deque>
#include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Base/Error.h>
@@ -22,7 +24,7 @@ namespace Swift {
class DomainNameResolver;
- class ChainedConnector {
+ class SWIFTEN_API ChainedConnector {
public:
- ChainedConnector(const std::string& hostname, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*);
+ ChainedConnector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*);
void setTimeoutMilliseconds(int milliseconds);
@@ -39,4 +41,6 @@ namespace Swift {
private:
std::string hostname;
+ int port;
+ boost::optional<std::string> serviceLookupPrefix;
DomainNameResolver* resolver;
std::vector<ConnectionFactory*> connectionFactories;
@@ -47,3 +51,3 @@ namespace Swift {
boost::shared_ptr<Error> lastError;
};
-};
+}
diff --git a/Swiften/Network/Connection.h b/Swiften/Network/Connection.h
index 6ad2999..97c287d 100644
--- a/Swiften/Network/Connection.h
+++ b/Swiften/Network/Connection.h
@@ -10,4 +10,5 @@
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/SafeByteArray.h>
@@ -15,5 +16,5 @@ namespace Swift {
class HostAddressPort;
- class Connection {
+ class SWIFTEN_API Connection {
public:
typedef boost::shared_ptr<Connection> ref;
diff --git a/Swiften/Network/ConnectionFactory.h b/Swiften/Network/ConnectionFactory.h
index 9e92c36..c8be2fc 100644
--- a/Swiften/Network/ConnectionFactory.h
+++ b/Swiften/Network/ConnectionFactory.h
@@ -9,8 +9,10 @@
#include <boost/shared_ptr.hpp>
+#include <Swiften/Base/API.h>
+
namespace Swift {
class Connection;
- class ConnectionFactory {
+ class SWIFTEN_API ConnectionFactory {
public:
virtual ~ConnectionFactory();
diff --git a/Swiften/Network/ConnectionServer.h b/Swiften/Network/ConnectionServer.h
index 00703a4..2e09348 100644
--- a/Swiften/Network/ConnectionServer.h
+++ b/Swiften/Network/ConnectionServer.h
@@ -8,16 +8,25 @@
#include <boost/shared_ptr.hpp>
-#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
+#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/HostAddressPort.h>
+#include <boost/optional/optional_fwd.hpp>
namespace Swift {
- class ConnectionServer {
+ class SWIFTEN_API ConnectionServer {
public:
+ enum Error {
+ Conflict,
+ UnknownError
+ };
+
virtual ~ConnectionServer();
virtual HostAddressPort getAddressPort() const = 0;
+ virtual boost::optional<Error> tryStart() = 0; // FIXME: This should become the new start
+
virtual void start() = 0;
diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp
index 5e7f8d9..1db1eac 100644
--- a/Swiften/Network/Connector.cpp
+++ b/Swiften/Network/Connector.cpp
@@ -18,5 +18,5 @@
namespace Swift {
-Connector::Connector(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), defaultPort(defaultPort), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) {
+Connector::Connector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), port(port), serviceLookupPrefix(serviceLookupPrefix), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) {
}
@@ -32,13 +32,17 @@ void Connector::start() {
assert(!timer);
queriedAllServices = false;
- serviceQuery = resolver->createServiceQuery("_xmpp-client._tcp." + hostname);
- serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1));
if (timeoutMilliseconds > 0) {
timer = timerFactory->createTimer(timeoutMilliseconds);
timer->onTick.connect(boost::bind(&Connector::handleTimeout, shared_from_this()));
- timer->start();
}
+ if (serviceLookupPrefix) {
+ serviceQuery = resolver->createServiceQuery(*serviceLookupPrefix, hostname);
+ serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1));
serviceQuery->run();
}
+ else {
+ queryAddress(hostname);
+ }
+}
void Connector::stop() {
@@ -110,10 +114,10 @@ void Connector::tryNextAddress() {
addressQueryResults.pop_front();
- int port = defaultPort;
+ int connectPort = (port == -1 ? 5222 : port);
if (!serviceQueryResults.empty()) {
- port = serviceQueryResults.front().port;
+ connectPort = serviceQueryResults.front().port;
}
- tryConnect(HostAddressPort(address, port));
+ tryConnect(HostAddressPort(address, connectPort));
}
}
@@ -125,8 +129,15 @@ void Connector::tryConnect(const HostAddressPort& target) {
currentConnection->onConnectFinished.connect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
currentConnection->connect(target);
+ if (timer) {
+ timer->start();
+ }
}
void Connector::handleConnectionConnectFinished(bool error) {
SWIFT_LOG(debug) << "ConnectFinished: " << (error ? "error" : "success") << std::endl;
+ if (timer) {
+ timer->stop();
+ timer.reset();
+ }
currentConnection->onConnectFinished.disconnect(boost::bind(&Connector::handleConnectionConnectFinished, shared_from_this(), _1));
if (error) {
@@ -170,6 +181,6 @@ void Connector::finish(boost::shared_ptr<Connection> connection) {
void Connector::handleTimeout() {
SWIFT_LOG(debug) << "Timeout" << std::endl;
- finish(boost::shared_ptr<Connection>());
+ handleConnectionConnectFinished(true);
}
-};
+}
diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h
index bf0efaf..16f8539 100644
--- a/Swiften/Network/Connector.h
+++ b/Swiften/Network/Connector.h
@@ -10,5 +10,6 @@
#include <Swiften/Base/boost_bsignals.h>
#include <boost/shared_ptr.hpp>
-
+#include <boost/optional.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/DomainNameServiceQuery.h>
#include <Swiften/Network/Connection.h>
@@ -24,10 +25,10 @@ namespace Swift {
class TimerFactory;
- class Connector : public boost::bsignals::trackable, public boost::enable_shared_from_this<Connector> {
+ class SWIFTEN_API Connector : public boost::bsignals::trackable, public boost::enable_shared_from_this<Connector> {
public:
typedef boost::shared_ptr<Connector> ref;
- static Connector::ref create(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort = 5222) {
- return ref(new Connector(hostname, resolver, connectionFactory, timerFactory, defaultPort));
+ static Connector::ref create(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) {
+ return ref(new Connector(hostname, port, serviceLookupPrefix, resolver, connectionFactory, timerFactory));
}
@@ -39,5 +40,5 @@ namespace Swift {
private:
- Connector(const std::string& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*, int defaultPort);
+ Connector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver*, ConnectionFactory*, TimerFactory*);
void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result);
@@ -56,8 +57,9 @@ namespace Swift {
private:
std::string hostname;
+ int port;
+ boost::optional<std::string> serviceLookupPrefix;
DomainNameResolver* resolver;
ConnectionFactory* connectionFactory;
TimerFactory* timerFactory;
- int defaultPort;
int timeoutMilliseconds;
boost::shared_ptr<Timer> timer;
@@ -70,3 +72,3 @@ namespace Swift {
bool foundSomeDNS;
};
-};
+}
diff --git a/Swiften/Network/DomainNameResolver.h b/Swiften/Network/DomainNameResolver.h
index b0ebc35..dc7013e 100644
--- a/Swiften/Network/DomainNameResolver.h
+++ b/Swiften/Network/DomainNameResolver.h
@@ -8,7 +8,8 @@
#include <boost/shared_ptr.hpp>
-
#include <string>
+#include <Swiften/Base/API.h>
+
namespace Swift {
class DomainNameServiceQuery;
@@ -16,9 +17,9 @@ namespace Swift {
- class DomainNameResolver {
+ class SWIFTEN_API DomainNameResolver {
public:
virtual ~DomainNameResolver();
- virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& name) = 0;
+ virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) = 0;
virtual boost::shared_ptr<DomainNameAddressQuery> createAddressQuery(const std::string& name) = 0;
};
diff --git a/Swiften/Network/DomainNameServiceQuery.cpp b/Swiften/Network/DomainNameServiceQuery.cpp
index da1e1ab..5e87295 100644
--- a/Swiften/Network/DomainNameServiceQuery.cpp
+++ b/Swiften/Network/DomainNameServiceQuery.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -14,6 +14,10 @@
#include <Swiften/Base/RandomGenerator.h>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/typeof/typeof.hpp>
using namespace Swift;
+namespace lambda = boost::lambda;
namespace {
@@ -23,12 +27,4 @@ namespace {
}
};
-
- struct GetWeight {
- GetWeight() {}
-
- int operator()(const DomainNameServiceQuery::Result& result) {
- return result.weight + 1 /* easy hack to account for '0' weights getting at least some weight */;
- }
- };
}
@@ -40,5 +36,5 @@ DomainNameServiceQuery::~DomainNameServiceQuery() {
void DomainNameServiceQuery::sortResults(std::vector<DomainNameServiceQuery::Result>& queries, RandomGenerator& generator) {
ResultPriorityComparator comparator;
- std::sort(queries.begin(), queries.end(), comparator);
+ std::stable_sort(queries.begin(), queries.end(), comparator);
std::vector<DomainNameServiceQuery::Result>::iterator i = queries.begin();
@@ -47,10 +43,15 @@ void DomainNameServiceQuery::sortResults(std::vector<DomainNameServiceQuery::Res
if (std::distance(i, next) > 1) {
std::vector<int> weights;
- std::transform(i, next, std::back_inserter(weights), GetWeight());
- for (size_t j = 0; j < weights.size() - 1; ++j) {
+ std::transform(i, next, std::back_inserter(weights),
+ /* easy hack to account for '0' weights getting at least some weight */
+ lambda::bind(&Result::weight, lambda::_1) + 1);
+ for (int j = 0; j < boost::numeric_cast<int>(weights.size() - 1); ++j) {
std::vector<int> cumulativeWeights;
- std::partial_sum(weights.begin() + j, weights.end(), std::back_inserter(cumulativeWeights));
+ std::partial_sum(
+ weights.begin() + j,
+ weights.end(),
+ std::back_inserter(cumulativeWeights));
int randomNumber = generator.generateRandomInteger(cumulativeWeights.back());
- int selectedIndex = std::lower_bound(cumulativeWeights.begin(), cumulativeWeights.end(), randomNumber) - cumulativeWeights.begin();
+ BOOST_AUTO(selectedIndex, std::lower_bound(cumulativeWeights.begin(), cumulativeWeights.end(), randomNumber) - cumulativeWeights.begin());
std::swap(i[j], i[j + selectedIndex]);
std::swap(weights.begin()[j], weights.begin()[j + selectedIndex]);
diff --git a/Swiften/Network/DomainNameServiceQuery.h b/Swiften/Network/DomainNameServiceQuery.h
index 0e80233..fdf5b5d 100644
--- a/Swiften/Network/DomainNameServiceQuery.h
+++ b/Swiften/Network/DomainNameServiceQuery.h
@@ -13,4 +13,5 @@
#include <string>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/DomainNameResolveError.h>
@@ -18,5 +19,5 @@ namespace Swift {
class RandomGenerator;
- class DomainNameServiceQuery {
+ class SWIFTEN_API DomainNameServiceQuery {
public:
typedef boost::shared_ptr<DomainNameServiceQuery> ref;
diff --git a/Swiften/Network/DummyConnection.h b/Swiften/Network/DummyConnection.h
index 5191e30..36bf897 100644
--- a/Swiften/Network/DummyConnection.h
+++ b/Swiften/Network/DummyConnection.h
@@ -9,4 +9,5 @@
#include <boost/enable_shared_from_this.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/HostAddressPort.h>
@@ -15,5 +16,5 @@
namespace Swift {
- class DummyConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<DummyConnection> {
+ class SWIFTEN_API DummyConnection : public Connection, public EventOwner, public boost::enable_shared_from_this<DummyConnection> {
public:
DummyConnection(EventLoop* eventLoop);
diff --git a/Swiften/Network/DummyTimerFactory.h b/Swiften/Network/DummyTimerFactory.h
index 0c49f3d..1e9413b 100644
--- a/Swiften/Network/DummyTimerFactory.h
+++ b/Swiften/Network/DummyTimerFactory.h
@@ -9,8 +9,9 @@
#include <list>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/TimerFactory.h>
namespace Swift {
- class DummyTimerFactory : public TimerFactory {
+ class SWIFTEN_API DummyTimerFactory : public TimerFactory {
public:
class DummyTimer;
diff --git a/Swiften/Network/FakeConnection.cpp b/Swiften/Network/FakeConnection.cpp
index be5555c..a84c92e 100644
--- a/Swiften/Network/FakeConnection.cpp
+++ b/Swiften/Network/FakeConnection.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -44,5 +44,5 @@ void FakeConnection::connect(const HostAddressPort& address) {
}
eventLoop->postEvent(
- boost::bind(boost::ref(onConnectFinished), error),
+ boost::bind(boost::ref(onConnectFinished), error ? true : false),
shared_from_this());
}
diff --git a/Swiften/Network/FakeConnection.h b/Swiften/Network/FakeConnection.h
index 99cb584..eca45da 100644
--- a/Swiften/Network/FakeConnection.h
+++ b/Swiften/Network/FakeConnection.h
@@ -11,4 +11,5 @@
#include <vector>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/HostAddressPort.h>
@@ -17,5 +18,5 @@
namespace Swift {
- class FakeConnection :
+ class SWIFTEN_API FakeConnection :
public Connection,
public EventOwner,
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp
index 512381f..a88ded1 100644
--- a/Swiften/Network/HTTPConnectProxiedConnection.cpp
+++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp
@@ -16,5 +16,4 @@
#include <iostream>
#include <boost/bind.hpp>
-#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
@@ -25,69 +24,25 @@
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Network/ConnectionFactory.h>
-#include <Swiften/Network/CachingNameOnlyDomainNameResolver.h>
#include <Swiften/StringCodecs/Base64.h>
using namespace Swift;
-HTTPConnectProxiedConnection::HTTPConnectProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) : connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)), authID_(authID), authPassword_(authPassword) {
- resolver_ = new CachingNameOnlyDomainNameResolver(resolver, eventLoop);
- connected_ = false;
+HTTPConnectProxiedConnection::HTTPConnectProxiedConnection(
+ DomainNameResolver* resolver,
+ ConnectionFactory* connectionFactory,
+ TimerFactory* timerFactory,
+ const std::string& proxyHost,
+ int proxyPort,
+ const SafeString& authID,
+ const SafeString& authPassword) :
+ ProxiedConnection(resolver, connectionFactory, timerFactory, proxyHost, proxyPort),
+ authID_(authID),
+ authPassword_(authPassword) {
}
-HTTPConnectProxiedConnection::~HTTPConnectProxiedConnection() {
- cancelConnector();
- delete resolver_;
- if (connection_) {
- connection_->onDataRead.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1));
- }
-
- if (connected_) {
- std::cerr << "Warning: Connection was still established." << std::endl;
- }
-}
-
-void HTTPConnectProxiedConnection::cancelConnector() {
- if (connector_) {
- connector_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectFinished, shared_from_this(), _1));
- connector_->stop();
- connector_.reset();
- }
-}
-
-void HTTPConnectProxiedConnection::connect(const HostAddressPort& server) {
- server_ = server;
- connector_ = Connector::create(proxyHost_, resolver_, connectionFactory_, timerFactory_, proxyPort_);
- connector_->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnection::handleConnectFinished, shared_from_this(), _1));
- connector_->start();
-}
-
-void HTTPConnectProxiedConnection::listen() {
- assert(false);
- connection_->listen();
-}
-
-void HTTPConnectProxiedConnection::disconnect() {
- connected_ = false;
- connection_->disconnect();
-}
-
-void HTTPConnectProxiedConnection::handleDisconnected(const boost::optional<Error>& error) {
- onDisconnected(error);
-}
-
-void HTTPConnectProxiedConnection::write(const SafeByteArray& data) {
- connection_->write(data);
-}
-
-void HTTPConnectProxiedConnection::handleConnectFinished(Connection::ref connection) {
- cancelConnector();
- if (connection) {
- connection_ = connection;
- connection_->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1));
+void HTTPConnectProxiedConnection::initializeProxy() {
std::stringstream connect;
- connect << "CONNECT " << server_.getAddress().toString() << ":" << server_.getPort() << " HTTP/1.1\r\n";
+ connect << "CONNECT " << getServer().getAddress().toString() << ":" << getServer().getPort() << " HTTP/1.1\r\n";
SafeByteArray data = createSafeByteArray(connect.str());
if (!authID_.empty() && !authPassword_.empty()) {
@@ -101,34 +56,29 @@ void HTTPConnectProxiedConnection::handleConnectFinished(Connection::ref connect
append(data, createSafeByteArray("\r\n"));
SWIFT_LOG(debug) << "HTTP Proxy send headers: " << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl;
- connection_->write(data);
- }
- else {
- onConnectFinished(true);
- }
+ write(data);
}
-void HTTPConnectProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
- if (!connected_) {
+void HTTPConnectProxiedConnection::handleProxyInitializeData(boost::shared_ptr<SafeByteArray> data) {
SWIFT_LOG(debug) << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl;
std::vector<std::string> tmp = String::split(byteArrayToString(ByteArray(data->begin(), data->end())), ' ');
if (tmp.size() > 1) {
- int status = boost::lexical_cast<int> (tmp[1].c_str());
+ try {
+ int status = boost::lexical_cast<int>(tmp[1]);
SWIFT_LOG(debug) << "Proxy Status: " << status << std::endl;
if (status / 100 == 2) { // all 2XX states are OK
- connected_ = true;
- onConnectFinished(false);
- return;
+ setProxyInitializeFinished(true);
}
+ else {
SWIFT_LOG(debug) << "HTTP Proxy returned an error: " << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl;
+ setProxyInitializeFinished(false);
}
- disconnect();
- onConnectFinished(true);
}
- else {
- onDataRead(data);
+ catch (boost::bad_lexical_cast&) {
+ SWIFT_LOG(warning) << "Unexpected response: " << tmp[1] << std::endl;
+ setProxyInitializeFinished(false);
}
}
-
-HostAddressPort HTTPConnectProxiedConnection::getLocalAddress() const {
- return connection_->getLocalAddress();
+ else {
+ setProxyInitializeFinished(false);
+ }
}
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.h b/Swiften/Network/HTTPConnectProxiedConnection.h
index 8318ecc..c209dc1 100644
--- a/Swiften/Network/HTTPConnectProxiedConnection.h
+++ b/Swiften/Network/HTTPConnectProxiedConnection.h
@@ -14,58 +14,30 @@
#pragma once
-#include <boost/enable_shared_from_this.hpp>
-
-#include <Swiften/Network/Connection.h>
-#include <Swiften/Network/Connector.h>
-#include <Swiften/Network/HostAddressPort.h>
-#include <Swiften/Base/SafeString.h>
-
-namespace boost {
- class thread;
- namespace system {
- class error_code;
- }
-}
+#include <Swiften/Base/API.h>
+#include <Swiften/Network/ProxiedConnection.h>
namespace Swift {
+ class DomainNameResolver;
class ConnectionFactory;
class EventLoop;
+ class TimerFactory;
- class HTTPConnectProxiedConnection : public Connection, public boost::enable_shared_from_this<HTTPConnectProxiedConnection> {
+ class SWIFTEN_API HTTPConnectProxiedConnection : public ProxiedConnection {
public:
typedef boost::shared_ptr<HTTPConnectProxiedConnection> ref;
- ~HTTPConnectProxiedConnection();
-
- static ref create(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) {
- return ref(new HTTPConnectProxiedConnection(resolver, connectionFactory, timerFactory, eventLoop, proxyHost, proxyPort, authID, authPassword));
+ static ref create(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) {
+ return ref(new HTTPConnectProxiedConnection(resolver, connectionFactory, timerFactory, proxyHost, proxyPort, authID, authPassword));
}
- virtual void listen();
- virtual void connect(const HostAddressPort& address);
- virtual void disconnect();
- virtual void write(const SafeByteArray& data);
-
- virtual HostAddressPort getLocalAddress() const;
private:
- HTTPConnectProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword);
+ HTTPConnectProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword);
- void handleConnectFinished(Connection::ref connection);
- void handleDataRead(boost::shared_ptr<SafeByteArray> data);
- void handleDisconnected(const boost::optional<Error>& error);
- void cancelConnector();
+ virtual void initializeProxy();
+ virtual void handleProxyInitializeData(boost::shared_ptr<SafeByteArray> data);
private:
- bool connected_;
- DomainNameResolver* resolver_;
- ConnectionFactory* connectionFactory_;
- TimerFactory* timerFactory_;
- std::string proxyHost_;
- int proxyPort_;
- HostAddressPort server_;
SafeByteArray authID_;
SafeByteArray authPassword_;
- Connector::ref connector_;
- boost::shared_ptr<Connection> connection_;
};
}
diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp
index 14d702c..cf4cef5 100644
--- a/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp
+++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp
@@ -17,13 +17,13 @@
namespace Swift {
-HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), eventLoop_(eventLoop), proxyHost_(proxyHost), proxyPort_(proxyPort), authID_(""), authPassword_("") {
+HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort), authID_(""), authPassword_("") {
}
-HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), eventLoop_(eventLoop), proxyHost_(proxyHost), proxyPort_(proxyPort), authID_(authID), authPassword_(authPassword) {
+HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort), authID_(authID), authPassword_(authPassword) {
}
boost::shared_ptr<Connection> HTTPConnectProxiedConnectionFactory::createConnection() {
- return HTTPConnectProxiedConnection::create(resolver_, connectionFactory_, timerFactory_, eventLoop_, proxyHost_, proxyPort_, authID_, authPassword_);
+ return HTTPConnectProxiedConnection::create(resolver_, connectionFactory_, timerFactory_, proxyHost_, proxyPort_, authID_, authPassword_);
}
diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.h b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h
index 7d003e8..3efcecd 100644
--- a/Swiften/Network/HTTPConnectProxiedConnectionFactory.h
+++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h
@@ -23,6 +23,6 @@ namespace Swift {
class HTTPConnectProxiedConnectionFactory : public ConnectionFactory {
public:
- HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort);
- HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword);
+ HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort);
+ HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword);
virtual boost::shared_ptr<Connection> createConnection();
@@ -32,5 +32,4 @@ namespace Swift {
ConnectionFactory* connectionFactory_;
TimerFactory* timerFactory_;
- EventLoop* eventLoop_;
std::string proxyHost_;
int proxyPort_;
diff --git a/Swiften/Network/HostAddress.cpp b/Swiften/Network/HostAddress.cpp
index f00581f..ff5c1c4 100644
--- a/Swiften/Network/HostAddress.cpp
+++ b/Swiften/Network/HostAddress.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -16,4 +16,7 @@
#include <string>
+static boost::asio::ip::address localhost4 = boost::asio::ip::address(boost::asio::ip::address_v4::loopback());
+static boost::asio::ip::address localhost6 = boost::asio::ip::address(boost::asio::ip::address_v6::loopback());
+
namespace Swift {
@@ -29,9 +32,9 @@ HostAddress::HostAddress(const std::string& address) {
}
-HostAddress::HostAddress(const unsigned char* address, int length) {
+HostAddress::HostAddress(const unsigned char* address, size_t length) {
assert(length == 4 || length == 16);
if (length == 4) {
boost::asio::ip::address_v4::bytes_type data;
- for (int i = 0; i < length; ++i) {
+ for (size_t i = 0; i < length; ++i) {
data[i] = address[i];
}
@@ -40,5 +43,5 @@ HostAddress::HostAddress(const unsigned char* address, int length) {
else {
boost::asio::ip::address_v6::bytes_type data;
- for (int i = 0; i < length; ++i) {
+ for (size_t i = 0; i < length; ++i) {
data[i] = address[i];
}
@@ -62,3 +65,7 @@ boost::asio::ip::address HostAddress::getRawAddress() const {
}
+bool HostAddress::isLocalhost() const {
+ return address_ == localhost4 || address_ == localhost6;
+}
+
}
diff --git a/Swiften/Network/HostAddress.h b/Swiften/Network/HostAddress.h
index 0b3bdda..c62239b 100644
--- a/Swiften/Network/HostAddress.h
+++ b/Swiften/Network/HostAddress.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -9,10 +9,12 @@
#include <boost/asio/ip/address.hpp>
+#include <Swiften/Base/API.h>
+
namespace Swift {
- class HostAddress {
+ class SWIFTEN_API HostAddress {
public:
HostAddress();
HostAddress(const std::string&);
- HostAddress(const unsigned char* address, int length);
+ HostAddress(const unsigned char* address, size_t length);
HostAddress(const boost::asio::ip::address& address);
@@ -25,4 +27,5 @@ namespace Swift {
bool isValid() const;
+ bool isLocalhost() const;
private:
diff --git a/Swiften/Network/HostAddressPort.h b/Swiften/Network/HostAddressPort.h
index e3c0413..68f3a1c 100644
--- a/Swiften/Network/HostAddressPort.h
+++ b/Swiften/Network/HostAddressPort.h
@@ -9,8 +9,9 @@
#include <boost/asio/ip/tcp.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/HostAddress.h>
namespace Swift {
- class HostAddressPort {
+ class SWIFTEN_API HostAddressPort {
public:
HostAddressPort(const HostAddress& address = HostAddress(), int port = -1);
diff --git a/Swiften/Network/HostNameOrAddress.cpp b/Swiften/Network/HostNameOrAddress.cpp
new file mode 100644
index 0000000..bc2737d
--- /dev/null
+++ b/Swiften/Network/HostNameOrAddress.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Network/HostNameOrAddress.h>
+
+using namespace Swift;
+
+namespace {
+ struct ToStringVisitor : public boost::static_visitor<std::string> {
+ std::string operator()(const HostAddress& address) const {
+ return address.toString();
+ }
+
+ std::string operator()(const std::string & str) const {
+ return str;
+ }
+ };
+}
+
+namespace Swift {
+
+std::string toString(const HostNameOrAddress& address) {
+ return boost::apply_visitor(ToStringVisitor(), address);
+}
+
+}
diff --git a/Swiften/Network/HostNameOrAddress.h b/Swiften/Network/HostNameOrAddress.h
new file mode 100644
index 0000000..f804d15
--- /dev/null
+++ b/Swiften/Network/HostNameOrAddress.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2012 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+#pragma once
+
+#include <string>
+#include <Swiften/Network/HostAddress.h>
+#include <boost/variant.hpp>
+
+namespace Swift {
+ typedef boost::variant<std::string, HostAddress> HostNameOrAddress;
+
+ std::string toString(const HostNameOrAddress& address);
+}
diff --git a/Swiften/Network/MacOSXProxyProvider.cpp b/Swiften/Network/MacOSXProxyProvider.cpp
index eaadd28..3456c73 100644
--- a/Swiften/Network/MacOSXProxyProvider.cpp
+++ b/Swiften/Network/MacOSXProxyProvider.cpp
@@ -5,4 +5,10 @@
*/
+/*
+ * Copyright (c) 2013 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#include <Swiften/Base/Platform.h>
#include <Swiften/Network/MacOSXProxyProvider.h>
@@ -11,4 +17,5 @@
#include <stdlib.h>
#include <iostream>
+#include <boost/numeric/conversion/cast.hpp>
#include <utility>
@@ -17,4 +24,6 @@
#endif
+#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
+
using namespace Swift;
@@ -28,5 +37,5 @@ static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabl
CFNumberRef zero = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i);
CFComparisonResult result = CFNumberCompare(numberValue, zero, NULL);
- CFRelease(numberValue);
+ CFRelease(zero);
if(result != kCFCompareEqualTo) {
@@ -38,5 +47,4 @@ static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabl
if(numberValue != NULL) {
CFNumberGetValue(numberValue, kCFNumberIntType, &port);
- CFRelease(numberValue);
}
@@ -47,5 +55,5 @@ static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabl
// if the string is toby the length must be at least 5.
CFIndex length = CFStringGetLength(stringValue) + 1;
- buffer.resize(length);
+ buffer.resize(boost::numeric_cast<size_t>(length));
if(CFStringGetCString(stringValue, &buffer[0], length, kCFStringEncodingMacRoman)) {
for(std::vector<char>::iterator iter = buffer.begin(); iter != buffer.end(); ++iter) {
@@ -53,5 +61,4 @@ static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabl
}
}
- CFRelease(stringValue);
}
}
@@ -79,4 +86,5 @@ HostAddressPort MacOSXProxyProvider::getHTTPConnectProxy() const {
if(proxies != NULL) {
result = getFromDictionary(proxies, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
+ CFRelease(proxies);
}
#endif
@@ -90,4 +98,5 @@ HostAddressPort MacOSXProxyProvider::getSOCKS5Proxy() const {
if(proxies != NULL) {
result = getFromDictionary(proxies, kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort);
+ CFRelease(proxies);
}
#endif
diff --git a/Swiften/Network/MiniUPnPInterface.cpp b/Swiften/Network/MiniUPnPInterface.cpp
index c9f682f..bfa989f 100644
--- a/Swiften/Network/MiniUPnPInterface.cpp
+++ b/Swiften/Network/MiniUPnPInterface.cpp
@@ -7,6 +7,8 @@
#include <Swiften/Network/MiniUPnPInterface.h>
+#include <miniupnpc.h>
#include <upnpcommands.h>
#include <upnperrors.h>
+#include <boost/smart_ptr/make_shared.hpp>
#include <boost/lexical_cast.hpp>
@@ -15,32 +17,41 @@
namespace Swift {
-MiniUPnPInterface::MiniUPnPInterface() : isValid(false) {
+struct MiniUPnPInterface::Private {
+ bool isValid;
+ std::string localAddress;
+ UPNPDev* deviceList;
+ UPNPUrls urls;
+ IGDdatas data;
+};
+
+MiniUPnPInterface::MiniUPnPInterface() : p(boost::make_shared<Private>()) {
+ p->isValid = false;
int error = 0;
- deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
- if (!deviceList) {
+ p->deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
+ if (!p->deviceList) {
return;
}
char lanAddress[64];
- if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddress, sizeof(lanAddress))) {
+ if (!UPNP_GetValidIGD(p->deviceList, &p->urls, &p->data, lanAddress, sizeof(lanAddress))) {
return;
}
- localAddress = std::string(lanAddress);
- isValid = true;
+ p->localAddress = std::string(lanAddress);
+ p->isValid = true;
}
MiniUPnPInterface::~MiniUPnPInterface() {
- if (isValid) {
- FreeUPNPUrls(&urls);
+ if (p->isValid) {
+ FreeUPNPUrls(&p->urls);
}
- freeUPNPDevlist(deviceList);
+ freeUPNPDevlist(p->deviceList);
}
boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() {
- if (!isValid) {
+ if (!p->isValid) {
return boost::optional<HostAddress>();
}
char externalIPAddress[40];
- int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
+ int ret = UPNP_GetExternalIPAddress(p->urls.controlURL, p->data.first.servicetype, externalIPAddress);
if (ret != UPNPCOMMAND_SUCCESS) {
return boost::optional<HostAddress>();
@@ -52,5 +63,5 @@ boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() {
boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLocalPort, int actualPublicPort) {
- if (!isValid) {
+ if (!p->isValid) {
return boost::optional<NATPortMapping>();
}
@@ -62,5 +73,14 @@ boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLoca
std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds());
- int ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), localPort.c_str(), localAddress.c_str(), 0, mapping.getPublicPort() == NATPortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str());
+ int ret = UPNP_AddPortMapping(
+ p->urls.controlURL,
+ p->data.first.servicetype,
+ publicPort.c_str(),
+ localPort.c_str(),
+ p->localAddress.c_str(),
+ 0,
+ mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP",
+ 0,
+ leaseSeconds.c_str());
if (ret == UPNPCOMMAND_SUCCESS) {
return mapping;
@@ -72,5 +92,5 @@ boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLoca
bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) {
- if (!isValid) {
+ if (!p->isValid) {
return false;
}
@@ -80,7 +100,11 @@ bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) {
std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds());
- int ret = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", 0);
+ int ret = UPNP_DeletePortMapping(p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", 0);
return ret == UPNPCOMMAND_SUCCESS;
}
+bool MiniUPnPInterface::isAvailable() {
+ return p->isValid;
+}
+
}
diff --git a/Swiften/Network/MiniUPnPInterface.h b/Swiften/Network/MiniUPnPInterface.h
index ae9be66..61d12ca 100644
--- a/Swiften/Network/MiniUPnPInterface.h
+++ b/Swiften/Network/MiniUPnPInterface.h
@@ -8,5 +8,6 @@
#include <boost/optional.hpp>
-#include <miniupnpc.h>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
#include <Swiften/Network/NATPortMapping.h>
@@ -14,12 +15,10 @@
namespace Swift {
- class MiniUPnPInterface : public NATTraversalInterface {
+ class MiniUPnPInterface : public NATTraversalInterface, boost::noncopyable {
public:
MiniUPnPInterface();
~MiniUPnPInterface();
- virtual bool isAvailable() {
- return isValid;
- }
+ virtual bool isAvailable();
boost::optional<HostAddress> getPublicIP();
@@ -28,9 +27,6 @@ namespace Swift {
private:
- bool isValid;
- std::string localAddress;
- UPNPDev* deviceList;
- UPNPUrls urls;
- IGDdatas data;
+ struct Private;
+ boost::shared_ptr<Private> p;
};
}
diff --git a/Swiften/Network/NATPMPInterface.cpp b/Swiften/Network/NATPMPInterface.cpp
index 36553ed..dcae641 100644
--- a/Swiften/Network/NATPMPInterface.cpp
+++ b/Swiften/Network/NATPMPInterface.cpp
@@ -5,26 +5,43 @@
*/
+/*
+* Copyright (c) 2014 Kevin Smith
+* Licensed under the GNU General Public License v3.
+* See Documentation/Licenses/GPLv3.txt for more information.
+*/
+
#include <Swiften/Network/NATPMPInterface.h>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
#include <Swiften/Base/Log.h>
+// This has to be included after the previous headers, because of WIN32 macro
+// being defined somewhere.
+#include <natpmp.h>
+
#pragma GCC diagnostic ignored "-Wold-style-cast"
namespace Swift {
-NATPMPInterface::NATPMPInterface() {
- initnatpmp(&natpmp, 0, 0);
+struct NATPMPInterface::Private {
+ natpmp_t natpmp;
+};
+
+NATPMPInterface::NATPMPInterface() : p(boost::make_shared<Private>()) {
+ initnatpmp(&p->natpmp, 0, 0);
}
NATPMPInterface::~NATPMPInterface() {
- closenatpmp(&natpmp);
+ closenatpmp(&p->natpmp);
}
bool NATPMPInterface::isAvailable() {
- return getPublicIP();
+ return getPublicIP() ? true : false;
}
boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
- if (sendpublicaddressrequest(&natpmp) < 0) {
+ if (sendpublicaddressrequest(&p->natpmp) < 0) {
SWIFT_LOG(debug) << "Failed to send NAT-PMP public address request!" << std::endl;
return boost::optional<HostAddress>();
@@ -37,8 +54,8 @@ boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
struct timeval timeout;
FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
+ FD_SET(p->natpmp.s, &fds);
+ getnatpmprequesttimeout(&p->natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
+ r = readnatpmpresponseorretry(&p->natpmp, &response);
} while (r == NATPMP_TRYAGAIN);
@@ -54,5 +71,10 @@ boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, int publicPort) {
NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP);
- if (sendnewportmappingrequest(&natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.getLeaseInSeconds(), mapping.getPublicPort(), mapping.getLocalPort()) < 0) {
+ if (sendnewportmappingrequest(
+ &p->natpmp,
+ mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP,
+ boost::numeric_cast<uint16_t>(mapping.getLocalPort()),
+ boost::numeric_cast<uint16_t>(mapping.getPublicPort()),
+ boost::numeric_cast<uint32_t>(mapping.getLeaseInSeconds())) < 0) {
SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl;
return boost::optional<NATPortMapping>();
@@ -65,12 +87,12 @@ boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, i
struct timeval timeout;
FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
+ FD_SET(p->natpmp.s, &fds);
+ getnatpmprequesttimeout(&p->natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
+ r = readnatpmpresponseorretry(&p->natpmp, &response);
} while(r == NATPMP_TRYAGAIN);
if (r == 0) {
- NATPortMapping result(response.pnu.newportmapping.privateport, response.pnu.newportmapping.mappedpublicport, NATPortMapping::TCP, response.pnu.newportmapping.lifetime);
+ NATPortMapping result(response.pnu.newportmapping.privateport, response.pnu.newportmapping.mappedpublicport, NATPortMapping::TCP, boost::numeric_cast<int>(response.pnu.newportmapping.lifetime));
return result;
}
@@ -82,5 +104,5 @@ boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, i
bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) {
- if (sendnewportmappingrequest(&natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.getLocalPort()) < 0) {
+ if (sendnewportmappingrequest(&p->natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, boost::numeric_cast<uint32_t>(mapping.getLocalPort())) < 0) {
SWIFT_LOG(debug) << "Failed to send NAT-PMP remove forwarding request!" << std::endl;
return false;
@@ -93,8 +115,8 @@ bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) {
struct timeval timeout;
FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
+ FD_SET(p->natpmp.s, &fds);
+ getnatpmprequesttimeout(&p->natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
+ r = readnatpmpresponseorretry(&p->natpmp, &response);
} while(r == NATPMP_TRYAGAIN);
diff --git a/Swiften/Network/NATPMPInterface.h b/Swiften/Network/NATPMPInterface.h
index 6e7fb73..e079a59 100644
--- a/Swiften/Network/NATPMPInterface.h
+++ b/Swiften/Network/NATPMPInterface.h
@@ -8,13 +8,11 @@
#include <boost/optional.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
#include <Swiften/Network/NATPortMapping.h>
#include <Swiften/Network/NATTraversalInterface.h>
-// This has to be included after the previous headers, because of WIN32 macro
-// being defined somewhere.
-#include <natpmp.h>
-
namespace Swift {
- class NATPMPInterface : public NATTraversalInterface {
+ class NATPMPInterface : public NATTraversalInterface, boost::noncopyable {
public:
NATPMPInterface();
@@ -28,5 +26,6 @@ namespace Swift {
private:
- natpmp_t natpmp;
+ struct Private;
+ boost::shared_ptr<Private> p;
};
}
diff --git a/Swiften/Network/NATPortMapping.h b/Swiften/Network/NATPortMapping.h
index db14500..0f6bd95 100644
--- a/Swiften/Network/NATPortMapping.h
+++ b/Swiften/Network/NATPortMapping.h
@@ -14,8 +14,9 @@ namespace Swift {
enum Protocol {
TCP,
- UDP,
+ UDP
};
- NATPortMapping(int localPort, int publicPort, Protocol protocol = TCP, int leaseInSeconds = 60 * 60 * 24) : publicPort(publicPort), localPort(localPort), protocol(protocol), leaseInSeconds(leaseInSeconds) {
+ NATPortMapping(int localPort, int publicPort, Protocol protocol = TCP, int leaseInSeconds = 60 * 60 * 24) :
+ publicPort(publicPort), localPort(localPort), protocol(protocol), leaseInSeconds(leaseInSeconds) {
}
diff --git a/Swiften/Network/NATTraversalForwardPortRequest.h b/Swiften/Network/NATTraversalForwardPortRequest.h
index 1bbc9ca..48f85ea 100644
--- a/Swiften/Network/NATTraversalForwardPortRequest.h
+++ b/Swiften/Network/NATTraversalForwardPortRequest.h
@@ -9,12 +9,14 @@
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/NATPortMapping.h>
namespace Swift {
- class NATTraversalForwardPortRequest {
+ class SWIFTEN_API NATTraversalForwardPortRequest {
public:
virtual ~NATTraversalForwardPortRequest();
- virtual void run() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
boost::signal<void (boost::optional<NATPortMapping>)> onResult;
diff --git a/Swiften/Network/NATTraversalGetPublicIPRequest.h b/Swiften/Network/NATTraversalGetPublicIPRequest.h
index db1f005..1270db3 100644
--- a/Swiften/Network/NATTraversalGetPublicIPRequest.h
+++ b/Swiften/Network/NATTraversalGetPublicIPRequest.h
@@ -15,5 +15,6 @@ namespace Swift {
virtual ~NATTraversalGetPublicIPRequest();
- virtual void run() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
boost::signal<void (boost::optional<HostAddress>)> onResult;
diff --git a/Swiften/Network/NATTraversalRemovePortForwardingRequest.h b/Swiften/Network/NATTraversalRemovePortForwardingRequest.h
index cf349b1..210cbcb 100644
--- a/Swiften/Network/NATTraversalRemovePortForwardingRequest.h
+++ b/Swiften/Network/NATTraversalRemovePortForwardingRequest.h
@@ -16,5 +16,5 @@ namespace Swift {
enum Protocol {
TCP,
- UDP,
+ UDP
};
@@ -28,5 +28,6 @@ namespace Swift {
virtual ~NATTraversalRemovePortForwardingRequest();
- virtual void run() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
boost::signal<void (boost::optional<bool> /* failure */)> onResult;
diff --git a/Swiften/Network/NetworkEnvironment.h b/Swiften/Network/NetworkEnvironment.h
index fbff0cb..36a2bde 100644
--- a/Swiften/Network/NetworkEnvironment.h
+++ b/Swiften/Network/NetworkEnvironment.h
@@ -9,9 +9,10 @@
#include <vector>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/NetworkInterface.h>
namespace Swift {
- class NetworkEnvironment {
+ class SWIFTEN_API NetworkEnvironment {
public:
virtual ~NetworkEnvironment();
diff --git a/Swiften/Network/NetworkFactories.h b/Swiften/Network/NetworkFactories.h
index c8009a6..dd8e216 100644
--- a/Swiften/Network/NetworkFactories.h
+++ b/Swiften/Network/NetworkFactories.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -18,4 +18,7 @@ namespace Swift {
class ProxyProvider;
class EventLoop;
+ class IDNConverter;
+ class NetworkEnvironment;
+ class CryptoProvider;
/**
@@ -31,8 +34,11 @@ namespace Swift {
virtual ConnectionServerFactory* getConnectionServerFactory() const = 0;
virtual NATTraverser* getNATTraverser() const = 0;
+ virtual NetworkEnvironment* getNetworkEnvironment() const = 0;
virtual XMLParserFactory* getXMLParserFactory() const = 0;
virtual TLSContextFactory* getTLSContextFactory() const = 0;
virtual ProxyProvider* getProxyProvider() const = 0;
virtual EventLoop* getEventLoop() const = 0;
+ virtual IDNConverter* getIDNConverter() const = 0;
+ virtual CryptoProvider* getCryptoProvider() const = 0;
};
}
diff --git a/Swiften/Network/NullNATTraverser.cpp b/Swiften/Network/NullNATTraverser.cpp
index 8cb35cd..43fcd08 100644
--- a/Swiften/Network/NullNATTraverser.cpp
+++ b/Swiften/Network/NullNATTraverser.cpp
@@ -22,8 +22,11 @@ class NullNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest
}
- virtual void run() {
+ virtual void start() {
eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<HostAddress>()));
}
+ virtual void stop() {
+ }
+
private:
EventLoop* eventLoop;
@@ -35,8 +38,11 @@ class NullNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest
}
- virtual void run() {
+ virtual void start() {
eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<NATPortMapping>()));
}
+ virtual void stop() {
+ }
+
private:
EventLoop* eventLoop;
@@ -48,8 +54,11 @@ class NullNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePor
}
- virtual void run() {
+ virtual void start() {
eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<bool>(true)));
}
+ virtual void stop() {
+ }
+
private:
EventLoop* eventLoop;
diff --git a/Swiften/Network/PlatformDomainNameAddressQuery.cpp b/Swiften/Network/PlatformDomainNameAddressQuery.cpp
index ec7e663..91d15b9 100644
--- a/Swiften/Network/PlatformDomainNameAddressQuery.cpp
+++ b/Swiften/Network/PlatformDomainNameAddressQuery.cpp
@@ -14,5 +14,9 @@
namespace Swift {
-PlatformDomainNameAddressQuery::PlatformDomainNameAddressQuery(const std::string& host, EventLoop* eventLoop, PlatformDomainNameResolver* resolver) : PlatformDomainNameQuery(resolver), hostname(host), eventLoop(eventLoop) {
+PlatformDomainNameAddressQuery::PlatformDomainNameAddressQuery(const boost::optional<std::string>& host, EventLoop* eventLoop, PlatformDomainNameResolver* resolver) : PlatformDomainNameQuery(resolver), hostnameValid(false), eventLoop(eventLoop) {
+ if (!!host) {
+ hostname = *host;
+ hostnameValid = true;
+ }
}
@@ -22,4 +26,8 @@ void PlatformDomainNameAddressQuery::run() {
void PlatformDomainNameAddressQuery::runBlocking() {
+ if (!hostnameValid) {
+ emitError();
+ return;
+ }
//std::cout << "PlatformDomainNameResolver::doRun()" << std::endl;
boost::asio::ip::tcp::resolver resolver(ioService);
diff --git a/Swiften/Network/PlatformDomainNameAddressQuery.h b/Swiften/Network/PlatformDomainNameAddressQuery.h
index e1dc05f..9e89086 100644
--- a/Swiften/Network/PlatformDomainNameAddressQuery.h
+++ b/Swiften/Network/PlatformDomainNameAddressQuery.h
@@ -21,5 +21,5 @@ namespace Swift {
class PlatformDomainNameAddressQuery : public DomainNameAddressQuery, public PlatformDomainNameQuery, public boost::enable_shared_from_this<PlatformDomainNameAddressQuery>, public EventOwner {
public:
- PlatformDomainNameAddressQuery(const std::string& host, EventLoop* eventLoop, PlatformDomainNameResolver*);
+ PlatformDomainNameAddressQuery(const boost::optional<std::string>& host, EventLoop* eventLoop, PlatformDomainNameResolver*);
void run();
@@ -32,4 +32,5 @@ namespace Swift {
boost::asio::io_service ioService;
std::string hostname;
+ bool hostnameValid;
EventLoop* eventLoop;
};
diff --git a/Swiften/Network/PlatformDomainNameResolver.cpp b/Swiften/Network/PlatformDomainNameResolver.cpp
index 63f7404..b65e884 100644
--- a/Swiften/Network/PlatformDomainNameResolver.cpp
+++ b/Swiften/Network/PlatformDomainNameResolver.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -17,5 +17,5 @@
#include <string>
-#include <Swiften/IDN/IDNA.h>
+#include <Swiften/IDN/IDNConverter.h>
#include <Swiften/Network/HostAddress.h>
#include <Swiften/EventLoop/EventLoop.h>
@@ -28,5 +28,5 @@ using namespace Swift;
namespace Swift {
-PlatformDomainNameResolver::PlatformDomainNameResolver(EventLoop* eventLoop) : eventLoop(eventLoop), stopRequested(false) {
+PlatformDomainNameResolver::PlatformDomainNameResolver(IDNConverter* idnConverter, EventLoop* eventLoop) : idnConverter(idnConverter), eventLoop(eventLoop), stopRequested(false) {
thread = new boost::thread(boost::bind(&PlatformDomainNameResolver::run, this));
}
@@ -39,10 +39,15 @@ PlatformDomainNameResolver::~PlatformDomainNameResolver() {
}
-boost::shared_ptr<DomainNameServiceQuery> PlatformDomainNameResolver::createServiceQuery(const std::string& name) {
- return boost::shared_ptr<DomainNameServiceQuery>(new PlatformDomainNameServiceQuery(IDNA::getEncoded(name), eventLoop, this));
+boost::shared_ptr<DomainNameServiceQuery> PlatformDomainNameResolver::createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) {
+ boost::optional<std::string> encodedDomain = idnConverter->getIDNAEncoded(domain);
+ std::string result;
+ if (encodedDomain) {
+ result = serviceLookupPrefix + *encodedDomain;
+ }
+ return boost::shared_ptr<DomainNameServiceQuery>(new PlatformDomainNameServiceQuery(result, eventLoop, this));
}
boost::shared_ptr<DomainNameAddressQuery> PlatformDomainNameResolver::createAddressQuery(const std::string& name) {
- return boost::shared_ptr<DomainNameAddressQuery>(new PlatformDomainNameAddressQuery(IDNA::getEncoded(name), eventLoop, this));
+ return boost::shared_ptr<DomainNameAddressQuery>(new PlatformDomainNameAddressQuery(idnConverter->getIDNAEncoded(name), eventLoop, this));
}
diff --git a/Swiften/Network/PlatformDomainNameResolver.h b/Swiften/Network/PlatformDomainNameResolver.h
index 295ecc5..6c3bf10 100644
--- a/Swiften/Network/PlatformDomainNameResolver.h
+++ b/Swiften/Network/PlatformDomainNameResolver.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -12,4 +12,5 @@
#include <boost/thread/condition_variable.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/DomainNameResolver.h>
#include <Swiften/Network/PlatformDomainNameQuery.h>
@@ -18,13 +19,13 @@
namespace Swift {
-
+ class IDNConverter;
class EventLoop;
- class PlatformDomainNameResolver : public DomainNameResolver {
+ class SWIFTEN_API PlatformDomainNameResolver : public DomainNameResolver {
public:
- PlatformDomainNameResolver(EventLoop* eventLoop);
+ PlatformDomainNameResolver(IDNConverter* idnConverter, EventLoop* eventLoop);
~PlatformDomainNameResolver();
- virtual DomainNameServiceQuery::ref createServiceQuery(const std::string& name);
+ virtual DomainNameServiceQuery::ref createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain);
virtual DomainNameAddressQuery::ref createAddressQuery(const std::string& name);
@@ -36,4 +37,5 @@ namespace Swift {
friend class PlatformDomainNameServiceQuery;
friend class PlatformDomainNameAddressQuery;
+ IDNConverter* idnConverter;
EventLoop* eventLoop;
bool stopRequested;
diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.cpp b/Swiften/Network/PlatformDomainNameServiceQuery.cpp
index b0579a7..58cf8d2 100644
--- a/Swiften/Network/PlatformDomainNameServiceQuery.cpp
+++ b/Swiften/Network/PlatformDomainNameServiceQuery.cpp
@@ -13,4 +13,5 @@
#include <Swiften/Base/Platform.h>
#include <stdlib.h>
+#include <boost/numeric/conversion/cast.hpp>
#ifdef SWIFTEN_PLATFORM_WINDOWS
#undef UNICODE
@@ -38,5 +39,9 @@ using namespace Swift;
namespace Swift {
-PlatformDomainNameServiceQuery::PlatformDomainNameServiceQuery(const std::string& service, EventLoop* eventLoop, PlatformDomainNameResolver* resolver) : PlatformDomainNameQuery(resolver), eventLoop(eventLoop), service(service) {
+PlatformDomainNameServiceQuery::PlatformDomainNameServiceQuery(const boost::optional<std::string>& serviceName, EventLoop* eventLoop, PlatformDomainNameResolver* resolver) : PlatformDomainNameQuery(resolver), eventLoop(eventLoop), serviceValid(false) {
+ if (!!serviceName) {
+ service = *serviceName;
+ serviceValid = true;
+ }
}
@@ -46,4 +51,9 @@ void PlatformDomainNameServiceQuery::run() {
void PlatformDomainNameServiceQuery::runBlocking() {
+ if (!serviceValid) {
+ emitError();
+ return;
+ }
+
SWIFT_LOG(debug) << "Querying " << service << std::endl;
@@ -122,5 +132,5 @@ void PlatformDomainNameServiceQuery::runBlocking() {
return;
}
- record.priority = ns_get16(currentEntry);
+ record.priority = boost::numeric_cast<int>(ns_get16(currentEntry));
currentEntry += 2;
@@ -130,5 +140,5 @@ void PlatformDomainNameServiceQuery::runBlocking() {
return;
}
- record.weight = ns_get16(currentEntry);
+ record.weight = boost::numeric_cast<int>(ns_get16(currentEntry));
currentEntry += 2;
@@ -138,5 +148,5 @@ void PlatformDomainNameServiceQuery::runBlocking() {
return;
}
- record.port = ns_get16(currentEntry);
+ record.port = boost::numeric_cast<int>(ns_get16(currentEntry));
currentEntry += 2;
diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.h b/Swiften/Network/PlatformDomainNameServiceQuery.h
index 3372517..e105479 100644
--- a/Swiften/Network/PlatformDomainNameServiceQuery.h
+++ b/Swiften/Network/PlatformDomainNameServiceQuery.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -19,5 +19,5 @@ namespace Swift {
class PlatformDomainNameServiceQuery : public DomainNameServiceQuery, public PlatformDomainNameQuery, public boost::enable_shared_from_this<PlatformDomainNameServiceQuery>, public EventOwner {
public:
- PlatformDomainNameServiceQuery(const std::string& service, EventLoop* eventLoop, PlatformDomainNameResolver* resolver);
+ PlatformDomainNameServiceQuery(const boost::optional<std::string>& serviceName, EventLoop* eventLoop, PlatformDomainNameResolver* resolver);
virtual void run();
@@ -30,4 +30,5 @@ namespace Swift {
EventLoop* eventLoop;
std::string service;
+ bool serviceValid;
};
}
diff --git a/Swiften/Network/PlatformNATTraversalWorker.cpp b/Swiften/Network/PlatformNATTraversalWorker.cpp
index c962b3b..65ff577 100644
--- a/Swiften/Network/PlatformNATTraversalWorker.cpp
+++ b/Swiften/Network/PlatformNATTraversalWorker.cpp
@@ -9,11 +9,17 @@
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <Swiften/Base/Log.h>
+#include <Swiften/EventLoop/EventLoop.h>
#include <Swiften/Network/NATTraversalGetPublicIPRequest.h>
#include <Swiften/Network/NATTraversalForwardPortRequest.h>
#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h>
+#ifdef HAVE_LIBNATPMP
#include <Swiften/Network/NATPMPInterface.h>
+#endif
+#ifdef HAVE_LIBMINIUPNPC
#include <Swiften/Network/MiniUPnPInterface.h>
+#endif
namespace Swift {
@@ -38,4 +44,8 @@ class PlatformNATTraversalRequest : public boost::enable_shared_from_this<Platfo
}
+ EventLoop* getEventLoop() const {
+ return worker->getEventLoop();
+ }
+
virtual void runBlocking() = 0;
@@ -50,10 +60,14 @@ class PlatformNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPReq
}
- virtual void run() {
+ virtual void start() {
doRun();
}
+ virtual void stop() {
+ // TODO
+ }
+
virtual void runBlocking() {
- onResult(getNATTraversalInterface()->getPublicIP());
+ getEventLoop()->postEvent(boost::bind(boost::ref(onResult), getNATTraversalInterface()->getPublicIP()));
}
};
@@ -64,10 +78,14 @@ class PlatformNATTraversalForwardPortRequest : public NATTraversalForwardPortReq
}
- virtual void run() {
+ virtual void start() {
doRun();
}
+ virtual void stop() {
+ // TODO
+ }
+
virtual void runBlocking() {
- onResult(getNATTraversalInterface()->addPortForward(localIP, publicIP));
+ getEventLoop()->postEvent(boost::bind(boost::ref(onResult), getNATTraversalInterface()->addPortForward(boost::numeric_cast<int>(localIP), boost::numeric_cast<int>(publicIP))));
}
@@ -82,10 +100,14 @@ class PlatformNATTraversalRemovePortForwardingRequest : public NATTraversalRemov
}
- virtual void run() {
+ virtual void start() {
doRun();
}
+ virtual void stop() {
+ // TODO
+ }
+
virtual void runBlocking() {
- onResult(getNATTraversalInterface()->removePortForward(mapping));
+ getEventLoop()->postEvent(boost::bind(boost::ref(onResult), getNATTraversalInterface()->removePortForward(mapping)));
}
@@ -96,5 +118,6 @@ class PlatformNATTraversalRemovePortForwardingRequest : public NATTraversalRemov
PlatformNATTraversalWorker::PlatformNATTraversalWorker(EventLoop* eventLoop) : eventLoop(eventLoop), stopRequested(false), natPMPSupported(boost::logic::indeterminate), natPMPInterface(NULL), miniUPnPSupported(boost::logic::indeterminate), miniUPnPInterface(NULL) {
nullNATTraversalInterface = new NullNATTraversalInterface();
- thread = new boost::thread(boost::bind(&PlatformNATTraversalWorker::run, this));
+ // FIXME: This should be done from start(), and the current start() should be an internal method
+ thread = new boost::thread(boost::bind(&PlatformNATTraversalWorker::start, this));
}
@@ -104,10 +127,15 @@ PlatformNATTraversalWorker::~PlatformNATTraversalWorker() {
thread->join();
delete thread;
+#ifdef HAVE_LIBNATPMP
delete natPMPInterface;
+#endif
+#ifdef HAVE_LIBMINIUPNPC
delete miniUPnPInterface;
+#endif
delete nullNATTraversalInterface;
}
NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() const {
+#ifdef HAVE_LIBMINIUPNPC
if (boost::logic::indeterminate(miniUPnPSupported)) {
miniUPnPInterface = new MiniUPnPInterface();
@@ -117,6 +145,7 @@ NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() co
return miniUPnPInterface;
}
+#endif
-
+#ifdef HAVE_LIBNATPMP
if (boost::logic::indeterminate(natPMPSupported)) {
natPMPInterface = new NATPMPInterface();
@@ -126,4 +155,5 @@ NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() co
return natPMPInterface;
}
+#endif
return nullNATTraversalInterface;
@@ -143,5 +173,5 @@ boost::shared_ptr<NATTraversalRemovePortForwardingRequest> PlatformNATTraversalW
}
-void PlatformNATTraversalWorker::run() {
+void PlatformNATTraversalWorker::start() {
while (!stopRequested) {
PlatformNATTraversalRequest::ref request;
@@ -162,4 +192,8 @@ void PlatformNATTraversalWorker::run() {
}
+void PlatformNATTraversalWorker::stop() {
+ // TODO
+}
+
void PlatformNATTraversalWorker::addRequestToQueue(PlatformNATTraversalRequest::ref request) {
{
diff --git a/Swiften/Network/PlatformNATTraversalWorker.h b/Swiften/Network/PlatformNATTraversalWorker.h
index 94d3339..91b83f8 100644
--- a/Swiften/Network/PlatformNATTraversalWorker.h
+++ b/Swiften/Network/PlatformNATTraversalWorker.h
@@ -14,4 +14,5 @@
#include <boost/logic/tribool.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/NATTraverser.h>
#include <Swiften/Network/HostAddressPort.h>
@@ -29,5 +30,5 @@ namespace Swift {
class NATPortMapping;
- class PlatformNATTraversalWorker : public NATTraverser {
+ class SWIFTEN_API PlatformNATTraversalWorker : public NATTraverser {
friend class PlatformNATTraversalRequest;
@@ -43,5 +44,10 @@ namespace Swift {
NATTraversalInterface* getNATTraversalInterface() const;
void addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>);
- void run();
+ void start();
+ void stop();
+
+ EventLoop* getEventLoop() const {
+ return eventLoop;
+ }
private:
diff --git a/Swiften/Network/PlatformNetworkEnvironment.h b/Swiften/Network/PlatformNetworkEnvironment.h
index c6b945e..2092bfd 100644
--- a/Swiften/Network/PlatformNetworkEnvironment.h
+++ b/Swiften/Network/PlatformNetworkEnvironment.h
@@ -19,4 +19,10 @@ namespace Swift {
typedef WindowsNetworkEnvironment PlatformNetworkEnvironment;
}
+#elif defined(SWIFTEN_PLATFORM_SOLARIS)
+#include <Swiften/Network/SolarisNetworkEnvironment.h>
+namespace Swift {
+ typedef SolarisNetworkEnvironment PlatformNetworkEnvironment;
+}
+
#else
#include <Swiften/Network/UnixNetworkEnvironment.h>
diff --git a/Swiften/Network/ProxiedConnection.cpp b/Swiften/Network/ProxiedConnection.cpp
new file mode 100644
index 0000000..0061820
--- /dev/null
+++ b/Swiften/Network/ProxiedConnection.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+
+#include <Swiften/Network/ProxiedConnection.h>
+
+#include <iostream>
+#include <boost/bind.hpp>
+
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Network/ConnectionFactory.h>
+
+using namespace Swift;
+
+ProxiedConnection::ProxiedConnection(
+ DomainNameResolver* resolver,
+ ConnectionFactory* connectionFactory,
+ TimerFactory* timerFactory,
+ const std::string& proxyHost,
+ int proxyPort) :
+ resolver_(resolver),
+ connectionFactory_(connectionFactory),
+ timerFactory_(timerFactory),
+ proxyHost_(proxyHost),
+ proxyPort_(proxyPort),
+ server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) {
+ connected_ = false;
+}
+
+ProxiedConnection::~ProxiedConnection() {
+ cancelConnector();
+ if (connection_) {
+ connection_->onDataRead.disconnect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1));
+ connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1));
+ }
+ if (connected_) {
+ std::cerr << "Warning: Connection was still established." << std::endl;
+ }
+}
+
+void ProxiedConnection::cancelConnector() {
+ if (connector_) {
+ connector_->onConnectFinished.disconnect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1));
+ connector_->stop();
+ connector_.reset();
+ }
+}
+
+void ProxiedConnection::connect(const HostAddressPort& server) {
+ server_ = server;
+
+ connector_ = Connector::create(proxyHost_, proxyPort_, boost::optional<std::string>(), resolver_, connectionFactory_, timerFactory_);
+ connector_->onConnectFinished.connect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1));
+ connector_->start();
+}
+
+void ProxiedConnection::listen() {
+ assert(false);
+ connection_->listen();
+}
+
+void ProxiedConnection::disconnect() {
+ connected_ = false;
+ connection_->disconnect();
+}
+
+void ProxiedConnection::handleDisconnected(const boost::optional<Error>& error) {
+ onDisconnected(error);
+}
+
+void ProxiedConnection::write(const SafeByteArray& data) {
+ connection_->write(data);
+}
+
+void ProxiedConnection::handleConnectFinished(Connection::ref connection) {
+ cancelConnector();
+ if (connection) {
+ connection_ = connection;
+ connection_->onDataRead.connect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1));
+ connection_->onDisconnected.connect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1));
+
+ initializeProxy();
+ }
+ else {
+ onConnectFinished(true);
+ }
+}
+
+void ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
+ if (!connected_) {
+ handleProxyInitializeData(data);
+ }
+ else {
+ onDataRead(data);
+ }
+}
+
+HostAddressPort ProxiedConnection::getLocalAddress() const {
+ return connection_->getLocalAddress();
+}
+
+void ProxiedConnection::setProxyInitializeFinished(bool success) {
+ connected_ = success;
+ if (!success) {
+ disconnect();
+ }
+ onConnectFinished(!success);
+}
diff --git a/Swiften/Network/ProxiedConnection.h b/Swiften/Network/ProxiedConnection.h
new file mode 100644
index 0000000..aa8df38
--- /dev/null
+++ b/Swiften/Network/ProxiedConnection.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+
+#pragma once
+
+#include <boost/enable_shared_from_this.hpp>
+
+#include <Swiften/Network/Connection.h>
+#include <Swiften/Network/Connector.h>
+#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Base/SafeString.h>
+
+namespace boost {
+ class thread;
+ namespace system {
+ class error_code;
+ }
+}
+
+namespace Swift {
+ class ConnectionFactory;
+
+ class ProxiedConnection : public Connection, public boost::enable_shared_from_this<ProxiedConnection> {
+ public:
+ ProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort);
+ ~ProxiedConnection();
+
+ virtual void listen();
+ virtual void connect(const HostAddressPort& address);
+ virtual void disconnect();
+ virtual void write(const SafeByteArray& data);
+
+ virtual HostAddressPort getLocalAddress() const;
+
+ private:
+ void handleConnectFinished(Connection::ref connection);
+ void handleDataRead(boost::shared_ptr<SafeByteArray> data);
+ void handleDisconnected(const boost::optional<Error>& error);
+ void cancelConnector();
+
+ protected:
+ void setProxyInitializeFinished(bool success);
+
+ virtual void initializeProxy() = 0;
+ virtual void handleProxyInitializeData(boost::shared_ptr<SafeByteArray> data) = 0;
+
+ const HostAddressPort& getServer() const {
+ return server_;
+ }
+
+ private:
+ bool connected_;
+ DomainNameResolver* resolver_;
+ ConnectionFactory* connectionFactory_;
+ TimerFactory* timerFactory_;
+ std::string proxyHost_;
+ int proxyPort_;
+ HostAddressPort server_;
+ Connector::ref connector_;
+ boost::shared_ptr<Connection> connection_;
+ };
+}
+
diff --git a/Swiften/Network/ProxyProvider.h b/Swiften/Network/ProxyProvider.h
index 0b63d51..9a1ccee 100644
--- a/Swiften/Network/ProxyProvider.h
+++ b/Swiften/Network/ProxyProvider.h
@@ -8,5 +8,4 @@
#include <map>
-#include <Swiften/Base/Log.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Base/String.h>
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index ecd7be9..284c1f4 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -2,7 +2,11 @@ Import("swiften_env")
myenv = swiften_env.Clone()
-myenv.MergeFlags(myenv["LIBIDN_FLAGS"])
+
+if myenv.get("unbound", False) :
+ myenv.MergeFlags(myenv.get("UNBOUND_FLAGS", {}))
+ myenv.MergeFlags(myenv.get("LDNS_FLAGS", {}))
sourceList = [
+ "ProxiedConnection.cpp",
"HTTPConnectProxiedConnection.cpp",
"HTTPConnectProxiedConnectionFactory.cpp",
@@ -16,5 +20,5 @@ sourceList = [
"BOSHConnection.cpp",
"BOSHConnectionPool.cpp",
- "CachingNameOnlyDomainNameResolver.cpp",
+ "CachingDomainNameResolver.cpp",
"ConnectionFactory.cpp",
"ConnectionServer.cpp",
@@ -31,10 +35,8 @@ sourceList = [
"DomainNameAddressQuery.cpp",
"DomainNameServiceQuery.cpp",
- "PlatformDomainNameResolver.cpp",
- "PlatformDomainNameServiceQuery.cpp",
- "PlatformDomainNameAddressQuery.cpp",
"StaticDomainNameResolver.cpp",
"HostAddress.cpp",
"HostAddressPort.cpp",
+ "HostNameOrAddress.cpp",
"NetworkFactories.cpp",
"BoostNetworkFactories.cpp",
@@ -54,5 +56,13 @@ sourceList = [
]
-if myenv["PLATFORM"] == "darwin" :
+if myenv.get("unbound", False) :
+ myenv.Append(CPPDEFINES = "USE_UNBOUND")
+ sourceList.append("UnboundDomainNameResolver.cpp")
+else :
+ sourceList.append("PlatformDomainNameResolver.cpp")
+ sourceList.append("PlatformDomainNameServiceQuery.cpp")
+ sourceList.append("PlatformDomainNameAddressQuery.cpp")
+
+if myenv["PLATFORM"] == "darwin" and myenv["target"] != "android":
myenv.Append(FRAMEWORKS = ["CoreServices", "SystemConfiguration"])
sourceList += [ "MacOSXProxyProvider.cpp" ]
@@ -61,4 +71,8 @@ elif myenv["PLATFORM"] == "win32" :
sourceList += [ "WindowsProxyProvider.cpp" ]
sourceList += [ "WindowsNetworkEnvironment.cpp" ]
+elif myenv["PLATFORM"] == "sunos" :
+ sourceList += [ "UnixProxyProvider.cpp" ]
+ sourceList += [ "SolarisNetworkEnvironment.cpp" ]
+ sourceList += [ "EnvironmentProxyProvider.cpp" ]
else :
sourceList += [ "UnixNetworkEnvironment.cpp" ]
@@ -72,8 +86,10 @@ else :
objects = myenv.SwiftenObject(sourceList)
-if myenv["experimental"] :
+if myenv["experimental_ft"] :
# LibNATPMP classes
+ if myenv.get("HAVE_LIBNATPMP", False) :
natpmp_env = myenv.Clone()
natpmp_env.Append(CPPDEFINES = natpmp_env["LIBNATPMP_FLAGS"].get("INTERNAL_CPPDEFINES", []))
+ myenv.Append(CPPDEFINES = ["HAVE_LIBNATPMP"])
objects += natpmp_env.SwiftenObject([
"NATPMPInterface.cpp",
@@ -81,6 +97,8 @@ if myenv["experimental"] :
# LibMINIUPnP classes
+ if myenv.get("HAVE_LIBMINIUPNPC", False) :
upnp_env = myenv.Clone()
upnp_env.Append(CPPDEFINES = upnp_env["LIBMINIUPNPC_FLAGS"].get("INTERNAL_CPPDEFINES", []))
+ myenv.Append(CPPDEFINES = ["HAVE_LIBMINIUPNPC"])
objects += upnp_env.SwiftenObject([
"MiniUPnPInterface.cpp",
diff --git a/Swiften/Network/SOCKS5ProxiedConnection.cpp b/Swiften/Network/SOCKS5ProxiedConnection.cpp
index 163e23a..3fd8184 100644
--- a/Swiften/Network/SOCKS5ProxiedConnection.cpp
+++ b/Swiften/Network/SOCKS5ProxiedConnection.cpp
@@ -5,4 +5,10 @@
*/
+/*
+ * Copyright (c) 2014 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#include <Swiften/Network/SOCKS5ProxiedConnection.h>
@@ -19,57 +25,15 @@
using namespace Swift;
-SOCKS5ProxiedConnection::SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) : connectionFactory_(connectionFactory), proxy_(proxy), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) {
- connected_ = false;
-}
-
-SOCKS5ProxiedConnection::~SOCKS5ProxiedConnection() {
- if (connection_) {
- connection_->onDataRead.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleDisconnected, shared_from_this(), _1));
- }
-
- if (connected_) {
- std::cerr << "Warning: Connection was still established." << std::endl;
- }
-}
-
-void SOCKS5ProxiedConnection::connect(const HostAddressPort& server) {
- server_ = server;
- connection_ = connectionFactory_->createConnection();
- connection_->onConnectFinished.connect(boost::bind(&SOCKS5ProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1));
- connection_->onDataRead.connect(boost::bind(&SOCKS5ProxiedConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.connect(boost::bind(&SOCKS5ProxiedConnection::handleDisconnected, shared_from_this(), _1));
- SWIFT_LOG(debug) << "Trying to connect via proxy " << proxy_.getAddress().toString() << ":" << proxy_.getPort() << std::endl;
- SWIFT_LOG(debug) << "to server " << server.getAddress().toString() << ":" << server.getPort() << std::endl;
- connection_->connect(proxy_);
-}
-
-void SOCKS5ProxiedConnection::listen() {
- assert(false);
- connection_->listen();
-}
-
-void SOCKS5ProxiedConnection::disconnect() {
- connected_ = false;
- if (connection_) {
- connection_->disconnect();
- }
-}
-
-void SOCKS5ProxiedConnection::handleDisconnected(const boost::optional<Error>& error) {
- onDisconnected(error);
+SOCKS5ProxiedConnection::SOCKS5ProxiedConnection(
+ DomainNameResolver* resolver,
+ ConnectionFactory* connectionFactory,
+ TimerFactory* timerFactory,
+ const std::string& proxyHost,
+ int proxyPort) :
+ ProxiedConnection(resolver, connectionFactory, timerFactory, proxyHost, proxyPort),
+ proxyState_(Initial) {
}
-void SOCKS5ProxiedConnection::write(const SafeByteArray& data) {
- if (connection_) {
- connection_->write(data);
- }
-}
-
-void SOCKS5ProxiedConnection::handleConnectionConnectFinished(bool error) {
- connection_->onConnectFinished.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1));
- if (!error) {
- SWIFT_LOG(debug) << "Connection to proxy established, now connect to the server via it." << std::endl;
-
+void SOCKS5ProxiedConnection::initializeProxy() {
proxyState_ = ProxyAuthenticating;
SafeByteArray socksConnect;
@@ -80,16 +44,12 @@ void SOCKS5ProxiedConnection::handleConnectionConnectFinished(bool error) {
// buffer.push_back(0x02); // 0x02 == Username/Password
// rest see RFC 1928 (http://tools.ietf.org/html/rfc1928)
- connection_->write(socksConnect);
- }
- else {
- onConnectFinished(true);
- }
+ write(socksConnect);
}
-void SOCKS5ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
+void SOCKS5ProxiedConnection::handleProxyInitializeData(boost::shared_ptr<SafeByteArray> data) {
SafeByteArray socksConnect;
- boost::asio::ip::address rawAddress = server_.getAddress().getRawAddress();
+ boost::asio::ip::address rawAddress = getServer().getAddress().getRawAddress();
assert(rawAddress.is_v4() || rawAddress.is_v6());
- if (!connected_) {
+
if (proxyState_ == ProxyAuthenticating) {
SWIFT_LOG(debug) << "ProxyAuthenticating response received, reply with the connect BYTEs" << std::endl;
@@ -113,10 +73,10 @@ void SOCKS5ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> da
uc = rawAddress.to_v6().to_bytes()[s]; // the address.
}
- socksConnect.push_back(static_cast<char>(uc));
+ socksConnect.push_back(uc);
}
- socksConnect.push_back(static_cast<unsigned char> ((server_.getPort() >> 8) & 0xFF)); // highbyte of the port.
- socksConnect.push_back(static_cast<unsigned char> (server_.getPort() & 0xFF)); // lowbyte of the port.
- connection_->write(socksConnect);
+ socksConnect.push_back(static_cast<unsigned char> ((getServer().getPort() >> 8) & 0xFF)); // highbyte of the port.
+ socksConnect.push_back(static_cast<unsigned char> (getServer().getPort() & 0xFF)); // lowbyte of the port.
+ write(socksConnect);
return;
}
@@ -124,12 +84,13 @@ void SOCKS5ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> da
std::cerr << "exception caught" << std::endl;
}
- connection_->write(socksConnect);
+ write(socksConnect);
break;
default:
- onConnectFinished(true);
+ setProxyInitializeFinished(true);
break;
}
return;
}
+ setProxyInitializeFinished(false);
}
else if (proxyState_ == ProxyConnecting) {
@@ -152,23 +113,10 @@ void SOCKS5ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> da
if ((*data)[0] == 0x05 && (*data)[1] == 0x0) {
SWIFT_LOG(debug) << "Successfully connected the server via the proxy." << std::endl;
- connected_ = true;
- onConnectFinished(false);
- return;
+ setProxyInitializeFinished(true);
}
else {
std::cerr << "SOCKS Proxy returned an error: " << std::hex << (*data)[1] << std::endl;
+ setProxyInitializeFinished(false);
}
- return;
- }
- }
- else {
- onDataRead(data);
- return;
}
- disconnect();
- onConnectFinished(true);
-}
-
-HostAddressPort SOCKS5ProxiedConnection::getLocalAddress() const {
- return connection_->getLocalAddress();
}
diff --git a/Swiften/Network/SOCKS5ProxiedConnection.h b/Swiften/Network/SOCKS5ProxiedConnection.h
index 592ce7d..2c93468 100644
--- a/Swiften/Network/SOCKS5ProxiedConnection.h
+++ b/Swiften/Network/SOCKS5ProxiedConnection.h
@@ -7,53 +7,31 @@
#pragma once
-#include <boost/enable_shared_from_this.hpp>
-
-#include <Swiften/Network/Connection.h>
-#include <Swiften/Network/HostAddressPort.h>
-
-namespace boost {
- class thread;
- namespace system {
- class error_code;
- }
-}
+#include <Swiften/Network/ProxiedConnection.h>
namespace Swift {
class ConnectionFactory;
+ class DomainNameResolver;
+ class TimerFactory;
- class SOCKS5ProxiedConnection : public Connection, public boost::enable_shared_from_this<SOCKS5ProxiedConnection> {
+ class SOCKS5ProxiedConnection : public ProxiedConnection {
public:
typedef boost::shared_ptr<SOCKS5ProxiedConnection> ref;
- ~SOCKS5ProxiedConnection();
-
- static ref create(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) {
- return ref(new SOCKS5ProxiedConnection(connectionFactory, proxy));
+ static ref create(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort) {
+ return ref(new SOCKS5ProxiedConnection(resolver, connectionFactory, timerFactory, proxyHost, proxyPort));
}
- virtual void listen();
- virtual void connect(const HostAddressPort& address);
- virtual void disconnect();
- virtual void write(const SafeByteArray& data);
-
- virtual HostAddressPort getLocalAddress() const;
-
private:
- SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, const HostAddressPort& proxy);
+ SOCKS5ProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort);
- void handleConnectionConnectFinished(bool error);
- void handleDataRead(boost::shared_ptr<SafeByteArray> data);
- void handleDisconnected(const boost::optional<Error>& error);
+ virtual void initializeProxy();
+ virtual void handleProxyInitializeData(boost::shared_ptr<SafeByteArray> data);
private:
enum {
- ProxyAuthenticating = 0,
- ProxyConnecting,
+ Initial = 0,
+ ProxyAuthenticating,
+ ProxyConnecting
} proxyState_;
- bool connected_;
- ConnectionFactory* connectionFactory_;
- HostAddressPort proxy_;
- HostAddressPort server_;
- boost::shared_ptr<Connection> connection_;
};
}
diff --git a/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp b/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp
index 272ade9..af99034 100644
--- a/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp
+++ b/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp
@@ -11,9 +11,9 @@
namespace Swift {
-SOCKS5ProxiedConnectionFactory::SOCKS5ProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) : connectionFactory_(connectionFactory), proxy_(proxy) {
+SOCKS5ProxiedConnectionFactory::SOCKS5ProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort) {
}
boost::shared_ptr<Connection> SOCKS5ProxiedConnectionFactory::createConnection() {
- return SOCKS5ProxiedConnection::create(connectionFactory_, proxy_);
+ return SOCKS5ProxiedConnection::create(resolver_, connectionFactory_, timerFactory_, proxyHost_, proxyPort_);
}
diff --git a/Swiften/Network/SOCKS5ProxiedConnectionFactory.h b/Swiften/Network/SOCKS5ProxiedConnectionFactory.h
index f36d42a..4c5c585 100644
--- a/Swiften/Network/SOCKS5ProxiedConnectionFactory.h
+++ b/Swiften/Network/SOCKS5ProxiedConnectionFactory.h
@@ -9,15 +9,22 @@
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Network/HostNameOrAddress.h>
namespace Swift {
+ class DomainNameResolver;
+ class TimerFactory;
+
class SOCKS5ProxiedConnectionFactory : public ConnectionFactory {
public:
- SOCKS5ProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy);
+ SOCKS5ProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort);
virtual boost::shared_ptr<Connection> createConnection();
private:
+ DomainNameResolver* resolver_;
ConnectionFactory* connectionFactory_;
- HostAddressPort proxy_;
+ TimerFactory* timerFactory_;
+ std::string proxyHost_;
+ int proxyPort_;
};
}
diff --git a/Swiften/Network/SolarisNetworkEnvironment.cpp b/Swiften/Network/SolarisNetworkEnvironment.cpp
new file mode 100644
index 0000000..93eec32
--- /dev/null
+++ b/Swiften/Network/SolarisNetworkEnvironment.cpp
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+/*
+* Copyright (c) 2013-2014 Remko Tronçon and Kevin Smith
+* Licensed under the GNU General Public License v3.
+* See Documentation/Licenses/GPLv3.txt for more information.
+*/
+
+#include <Swiften/Network/SolarisNetworkEnvironment.h>
+
+#include <string>
+#include <vector>
+#include <map>
+#include <boost/optional.hpp>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <net/if.h>
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Network/HostAddress.h>
+#include <Swiften/Network/NetworkInterface.h>
+
+/*
+ * Copyright (c) 2006 WIDE Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#undef ifa_broadaddr
+#undef ifa_dstaddr
+struct ifaddrs {
+ struct ifaddrs *ifa_next; /* Pointer to next struct */
+ char *ifa_name; /* Interface name */
+ uint64_t ifa_flags; /* Interface flags */
+ struct sockaddr *ifa_addr; /* Interface address */
+ struct sockaddr *ifa_netmask; /* Interface netmask */
+ struct sockaddr *ifa_dstaddr; /* P2P interface destination */
+};
+#define ifa_broadaddr ifa_dstaddr
+
+static int
+get_lifreq(int fd, struct lifreq **ifr_ret)
+{
+ struct lifnum lifn;
+ struct lifconf lifc;
+ struct lifreq *lifrp;
+
+ lifn.lifn_family = AF_UNSPEC;
+ lifn.lifn_flags = 0;
+ if (ioctl(fd, SIOCGLIFNUM, &lifn) == -1)
+ lifn.lifn_count = 16;
+ else
+ lifn.lifn_count += 16;
+
+ for (;;) {
+ lifc.lifc_len = lifn.lifn_count * sizeof (*lifrp);
+ lifrp = (struct lifreq *) malloc(lifc.lifc_len);
+ if (lifrp == NULL)
+ return (-1);
+
+ lifc.lifc_family = AF_UNSPEC;
+ lifc.lifc_flags = 0;
+ lifc.lifc_buf = (char *)lifrp;
+ if (ioctl(fd, SIOCGLIFCONF, &lifc) == -1) {
+ free(lifrp);
+ if (errno == EINVAL) {
+ lifn.lifn_count <<= 1;
+ continue;
+ }
+ (void) close(fd);
+ return (-1);
+ }
+ if (lifc.lifc_len < (lifn.lifn_count - 1) * sizeof (*lifrp))
+ break;
+ free(lifrp);
+ lifn.lifn_count <<= 1;
+ }
+ (void) close(fd);
+
+ *ifr_ret = lifrp;
+
+ return (lifc.lifc_len / sizeof (*lifrp));
+}
+
+static size_t
+nbytes(const struct lifreq *lifrp, int nlif, size_t socklen)
+{
+ size_t len = 0;
+ size_t slen;
+
+ while (nlif > 0) {
+ slen = strlen(lifrp->lifr_name) + 1;
+ len += sizeof (struct ifaddrs) + ((slen + 3) & ~3);
+ len += 3 * socklen;
+ lifrp++;
+ nlif--;
+ }
+ return (len);
+}
+
+static struct sockaddr *
+addrcpy(struct sockaddr_storage *addr, char **bufp)
+{
+ char *buf = *bufp;
+ size_t len;
+
+ len = addr->ss_family == AF_INET ? sizeof (struct sockaddr_in) :
+ sizeof (struct sockaddr_in6);
+ (void) memcpy(buf, addr, len);
+ *bufp = buf + len;
+ return ((struct sockaddr *)buf);
+}
+
+static int
+populate(struct ifaddrs *ifa, int fd, struct lifreq *lifrp, int nlif, int af,
+ char **bufp)
+{
+ char *buf = *bufp;
+ size_t slen;
+
+ while (nlif > 0) {
+ ifa->ifa_next = (nlif > 1) ? ifa + 1 : NULL;
+ (void) strcpy(ifa->ifa_name = buf, lifrp->lifr_name);
+ slen = strlen(lifrp->lifr_name) + 1;
+ buf += (slen + 3) & ~3;
+ if (ioctl(fd, SIOCGLIFFLAGS, lifrp) == -1)
+ ifa->ifa_flags = 0;
+ else
+ ifa->ifa_flags = lifrp->lifr_flags;
+ if (ioctl(fd, SIOCGLIFADDR, lifrp) == -1)
+ ifa->ifa_addr = NULL;
+ else
+ ifa->ifa_addr = addrcpy(&lifrp->lifr_addr, &buf);
+ if (ioctl(fd, SIOCGLIFNETMASK, lifrp) == -1)
+ ifa->ifa_netmask = NULL;
+ else
+ ifa->ifa_netmask = addrcpy(&lifrp->lifr_addr, &buf);
+ if (ifa->ifa_flags & IFF_POINTOPOINT) {
+ if (ioctl(fd, SIOCGLIFDSTADDR, lifrp) == -1)
+ ifa->ifa_dstaddr = NULL;
+ else
+ ifa->ifa_dstaddr =
+ addrcpy(&lifrp->lifr_dstaddr, &buf);
+ } else if (ifa->ifa_flags & IFF_BROADCAST) {
+ if (ioctl(fd, SIOCGLIFBRDADDR, lifrp) == -1)
+ ifa->ifa_broadaddr = NULL;
+ else
+ ifa->ifa_broadaddr =
+ addrcpy(&lifrp->lifr_broadaddr, &buf);
+ } else {
+ ifa->ifa_dstaddr = NULL;
+ }
+
+ ifa++;
+ nlif--;
+ lifrp++;
+ }
+ *bufp = buf;
+ return (0);
+}
+
+static int
+getifaddrs(struct ifaddrs **ifap)
+{
+ int fd4, fd6;
+ int nif4, nif6 = 0;
+ struct lifreq *ifr4 = NULL;
+ struct lifreq *ifr6 = NULL;
+ struct ifaddrs *ifa = NULL;
+ char *buf;
+
+ if ((fd4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ return (-1);
+ if ((fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 &&
+ errno != EAFNOSUPPORT) {
+ (void) close(fd4);
+ return (-1);
+ }
+
+ if ((nif4 = get_lifreq(fd4, &ifr4)) == -1 ||
+ (fd6 != -1 && (nif6 = get_lifreq(fd6, &ifr6)) == -1))
+ goto failure;
+
+ if (nif4 == 0 && nif6 == 0) {
+ *ifap = NULL;
+ return (0);
+ }
+
+ ifa = (struct ifaddrs *) malloc(nbytes(ifr4, nif4, sizeof (struct sockaddr_in)) +
+ nbytes(ifr6, nif6, sizeof (struct sockaddr_in6)));
+ if (ifa == NULL)
+ goto failure;
+
+ buf = (char *)(ifa + nif4 + nif6);
+
+ if (populate(ifa, fd4, ifr4, nif4, AF_INET, &buf) == -1)
+ goto failure;
+ if (nif4 > 0 && nif6 > 0)
+ ifa[nif4 - 1].ifa_next = ifa + nif4;
+ if (populate(ifa + nif4, fd6, ifr6, nif6, AF_INET6, &buf) == -1)
+ goto failure;
+
+ return (0);
+
+failure:
+ free(ifa);
+ (void) close(fd4);
+ if (fd6 != -1)
+ (void) close(fd6);
+ free(ifr4);
+ free(ifr6);
+ return (-1);
+}
+
+static void
+freeifaddrs(struct ifaddrs *ifa)
+{
+ free(ifa);
+}
+
+/* End WIDE Project code */
+
+namespace Swift {
+
+std::vector<NetworkInterface> SolarisNetworkEnvironment::getNetworkInterfaces() const {
+ std::map<std::string, NetworkInterface> interfaces;
+
+ ifaddrs* addrs = 0;
+ int ret = getifaddrs(&addrs);
+ if (ret != 0) {
+ return std::vector<NetworkInterface>();
+ }
+
+ for (ifaddrs* a = addrs; a != 0; a = a->ifa_next) {
+ std::string name(a->ifa_name);
+ boost::optional<HostAddress> address;
+ if (a->ifa_addr->sa_family == PF_INET) {
+ sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(a->ifa_addr);
+ address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin_addr)), 4);
+ }
+ else if (a->ifa_addr->sa_family == PF_INET6) {
+ sockaddr_in6* sa = reinterpret_cast<sockaddr_in6*>(a->ifa_addr);
+ address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin6_addr)), 16);
+ }
+ if (address) {
+ std::map<std::string, NetworkInterface>::iterator i = interfaces.insert(std::make_pair(name, NetworkInterface(name, a->ifa_flags & IFF_LOOPBACK))).first;
+ i->second.addAddress(*address);
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ std::vector<NetworkInterface> result;
+ for (std::map<std::string,NetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) {
+ result.push_back(i->second);
+ }
+ return result;
+}
+
+}
diff --git a/Swiften/Network/SolarisNetworkEnvironment.h b/Swiften/Network/SolarisNetworkEnvironment.h
new file mode 100644
index 0000000..7481ff4
--- /dev/null
+++ b/Swiften/Network/SolarisNetworkEnvironment.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+/*
+* Copyright (c) 2013-2014 Remko Tronçon and Kevin Smith
+* Licensed under the GNU General Public License v3.
+* See Documentation/Licenses/GPLv3.txt for more information.
+*/
+
+#pragma once
+
+#include <vector>
+
+#include <Swiften/Base/boost_bsignals.h>
+
+#include <Swiften/Network/NetworkEnvironment.h>
+#include <Swiften/Network/NetworkInterface.h>
+
+namespace Swift {
+
+ class SolarisNetworkEnvironment : public NetworkEnvironment {
+ public:
+ std::vector<NetworkInterface> getNetworkInterfaces() const;
+ };
+
+}
diff --git a/Swiften/Network/StaticDomainNameResolver.cpp b/Swiften/Network/StaticDomainNameResolver.cpp
index ee18ee5..17d9c3b 100644
--- a/Swiften/Network/StaticDomainNameResolver.cpp
+++ b/Swiften/Network/StaticDomainNameResolver.cpp
@@ -109,6 +109,6 @@ void StaticDomainNameResolver::addXMPPClientService(const std::string& domain, c
}
-boost::shared_ptr<DomainNameServiceQuery> StaticDomainNameResolver::createServiceQuery(const std::string& name) {
- return boost::shared_ptr<DomainNameServiceQuery>(new ServiceQuery(name, this, eventLoop, owner));
+boost::shared_ptr<DomainNameServiceQuery> StaticDomainNameResolver::createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) {
+ return boost::shared_ptr<DomainNameServiceQuery>(new ServiceQuery(serviceLookupPrefix + domain, this, eventLoop, owner));
}
diff --git a/Swiften/Network/StaticDomainNameResolver.h b/Swiften/Network/StaticDomainNameResolver.h
index 29d1629..81ff040 100644
--- a/Swiften/Network/StaticDomainNameResolver.h
+++ b/Swiften/Network/StaticDomainNameResolver.h
@@ -10,4 +10,5 @@
#include <map>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/HostAddress.h>
#include <Swiften/Network/HostAddressPort.h>
@@ -18,5 +19,5 @@
namespace Swift {
- class StaticDomainNameResolver : public DomainNameResolver {
+ class SWIFTEN_API StaticDomainNameResolver : public DomainNameResolver {
public:
typedef std::map<std::string, std::vector<HostAddress> > AddressesMap;
@@ -48,5 +49,5 @@ namespace Swift {
}
- virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& name);
+ virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain);
virtual boost::shared_ptr<DomainNameAddressQuery> createAddressQuery(const std::string& name);
private:
diff --git a/Swiften/Network/TLSConnection.h b/Swiften/Network/TLSConnection.h
index a798393..60f73ea 100644
--- a/Swiften/Network/TLSConnection.h
+++ b/Swiften/Network/TLSConnection.h
@@ -25,5 +25,5 @@ namespace Swift {
virtual ~TLSConnection();
- virtual void listen() {assert(false);};
+ virtual void listen() {assert(false);}
virtual void connect(const HostAddressPort& address);
virtual void disconnect();
diff --git a/Swiften/Network/Timer.h b/Swiften/Network/Timer.h
index b7578f2..d08cf3c 100644
--- a/Swiften/Network/Timer.h
+++ b/Swiften/Network/Timer.h
@@ -8,4 +8,5 @@
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
namespace Swift {
@@ -13,5 +14,5 @@ namespace Swift {
* A class for triggering an event after a given period.
*/
- class Timer {
+ class SWIFTEN_API Timer {
public:
typedef boost::shared_ptr<Timer> ref;
diff --git a/Swiften/Network/TimerFactory.h b/Swiften/Network/TimerFactory.h
index 99903c3..62850bc 100644
--- a/Swiften/Network/TimerFactory.h
+++ b/Swiften/Network/TimerFactory.h
@@ -9,8 +9,9 @@
#include <boost/shared_ptr.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Network/Timer.h>
namespace Swift {
- class TimerFactory {
+ class SWIFTEN_API TimerFactory {
public:
virtual ~TimerFactory();
diff --git a/Swiften/Network/UnboundDomainNameResolver.cpp b/Swiften/Network/UnboundDomainNameResolver.cpp
new file mode 100755
index 0000000..bc280eb
--- /dev/null
+++ b/Swiften/Network/UnboundDomainNameResolver.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "UnboundDomainNameResolver.h"
+
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <Swiften/Base/Log.h>
+#include <Swiften/EventLoop/EventLoop.h>
+#include <Swiften/IDN/IDNConverter.h>
+#include <Swiften/Network/DomainNameAddressQuery.h>
+#include <Swiften/Network/DomainNameResolveError.h>
+#include <Swiften/Network/DomainNameServiceQuery.h>
+#include <Swiften/Network/HostAddress.h>
+#include <Swiften/Network/TimerFactory.h>
+
+#include <arpa/inet.h>
+#include <unbound.h>
+#include <ldns/ldns.h>
+#include <unistd.h>
+
+namespace Swift {
+
+class UnboundQuery {
+ public:
+ UnboundQuery(UnboundDomainNameResolver* resolver, ub_ctx* context) : resolver(resolver), ubContext(context) {}
+ virtual ~UnboundQuery() {}
+ virtual void handleResult(int err, ub_result* result) = 0;
+ protected:
+ UnboundDomainNameResolver* resolver;
+ ub_ctx* ubContext;
+};
+
+struct UnboundWrapperHelper {
+ UnboundWrapperHelper(UnboundDomainNameResolver* resolver, boost::shared_ptr<UnboundQuery> query) : resolver(resolver), query(query) {}
+ UnboundDomainNameResolver* resolver;
+ boost::shared_ptr<UnboundQuery> query;
+};
+
+class UnboundDomainNameServiceQuery : public DomainNameServiceQuery, public UnboundQuery, public boost::enable_shared_from_this<UnboundDomainNameServiceQuery> {
+ public:
+ UnboundDomainNameServiceQuery(UnboundDomainNameResolver* resolver, ub_ctx* context, std::string name) : UnboundQuery(resolver, context), name(name) {
+ }
+
+ virtual ~UnboundDomainNameServiceQuery() { }
+
+ virtual void run() {
+ int retval;
+ UnboundWrapperHelper* helper = new UnboundWrapperHelper(resolver, shared_from_this());
+
+ retval = ub_resolve_async(ubContext, const_cast<char*>(name.c_str()), LDNS_RR_TYPE_SRV,
+ 1 /* CLASS IN (internet) */,
+ helper, UnboundDomainNameResolver::unbound_callback_wrapper, NULL);
+ if(retval != 0) {
+ SWIFT_LOG(debug) << "resolve error: " << ub_strerror(retval) << std::endl;
+ delete helper;
+ }
+ }
+
+ void handleResult(int err, struct ub_result* result) {
+ std::vector<DomainNameServiceQuery::Result> serviceRecords;
+
+ if(err != 0) {
+ SWIFT_LOG(debug) << "resolve error: " << ub_strerror(err) << std::endl;
+ } else {
+ if(result->havedata) {
+ ldns_pkt* replyPacket = 0;
+ ldns_buffer* buffer = ldns_buffer_new(1024);
+ if (buffer && ldns_wire2pkt(&replyPacket, static_cast<const uint8_t*>(result->answer_packet), result->answer_len) == LDNS_STATUS_OK) {
+ ldns_rr_list* rrList = ldns_pkt_answer(replyPacket);
+ for (size_t n = 0; n < ldns_rr_list_rr_count(rrList); n++) {
+ ldns_rr* rr = ldns_rr_list_rr(rrList, n);
+ if ((ldns_rr_get_type(rr) != LDNS_RR_TYPE_SRV) ||
+ (ldns_rr_get_class(rr) != LDNS_RR_CLASS_IN) ||
+ (ldns_rr_rd_count(rr) != 4)) {
+ continue;
+ }
+
+ DomainNameServiceQuery::Result serviceRecord;
+ serviceRecord.priority = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
+ serviceRecord.weight = ldns_rdf2native_int16(ldns_rr_rdf(rr, 1));
+ serviceRecord.port = ldns_rdf2native_int16(ldns_rr_rdf(rr, 2));
+
+ ldns_buffer_rewind(buffer);
+ if ((ldns_rdf2buffer_str_dname(buffer, ldns_rr_rdf(rr, 3)) != LDNS_STATUS_OK) ||
+ (ldns_buffer_position(buffer) < 2) ||
+ !ldns_buffer_reserve(buffer, 1)) {
+ // either name invalid, empty or buffer to small
+ continue;
+ }
+ char terminator = 0;
+ ldns_buffer_write(buffer, &terminator, sizeof(terminator));
+
+ serviceRecord.hostname = std::string(reinterpret_cast<char*>(ldns_buffer_at(buffer, 0)));
+ serviceRecords.push_back(serviceRecord);
+ SWIFT_LOG(debug) << "hostname " << serviceRecord.hostname << " added" << std::endl;
+ }
+ }
+ if (replyPacket) ldns_pkt_free(replyPacket);
+ if (buffer) ldns_buffer_free(buffer);
+ }
+ }
+
+ ub_resolve_free(result);
+ onResult(serviceRecords);
+ }
+
+ private:
+ std::string name;
+};
+
+class UnboundDomainNameAddressQuery : public DomainNameAddressQuery, public UnboundQuery, public boost::enable_shared_from_this<UnboundDomainNameAddressQuery> {
+ public:
+ UnboundDomainNameAddressQuery(UnboundDomainNameResolver* resolver, ub_ctx* context, std::string name) : UnboundQuery(resolver, context), name(name) {
+ }
+
+ virtual ~UnboundDomainNameAddressQuery() { }
+
+ virtual void run() {
+ int retval;
+ UnboundWrapperHelper* helper = new UnboundWrapperHelper(resolver, shared_from_this());
+
+ //FIXME: support AAAA queries in some way
+ retval = ub_resolve_async(ubContext, const_cast<char*>(name.c_str()), LDNS_RR_TYPE_A,
+ 1 /* CLASS IN (internet) */,
+ helper, UnboundDomainNameResolver::unbound_callback_wrapper, NULL);
+ if(retval != 0) {
+ SWIFT_LOG(debug) << "resolve error: " << ub_strerror(retval) << std::endl;
+ delete helper;
+ }
+ }
+
+ void handleResult(int err, struct ub_result* result) {
+ std::vector<HostAddress> addresses;
+ boost::optional<DomainNameResolveError> error;
+ SWIFT_LOG(debug) << "Result for: " << name << std::endl;
+
+ if(err != 0) {
+ SWIFT_LOG(debug) << "resolve error: " << ub_strerror(err) << std::endl;
+ error = DomainNameResolveError();
+ } else {
+ if(result->havedata) {
+ for(int i=0; result->data[i]; i++) {
+ char address[100];
+ const char* addressStr = 0;
+ if ((addressStr = inet_ntop(AF_INET, result->data[i], address, 100))) {
+ SWIFT_LOG(debug) << "IPv4 address: " << addressStr << std::endl;
+ addresses.push_back(HostAddress(std::string(addressStr)));
+ } else if ((addressStr = inet_ntop(AF_INET6, result->data[i], address, 100))) {
+ SWIFT_LOG(debug) << "IPv6 address: " << addressStr << std::endl;
+ addresses.push_back(HostAddress(std::string(addressStr)));
+ } else {
+ SWIFT_LOG(debug) << "inet_ntop() failed" << std::endl;
+ error = DomainNameResolveError();
+ }
+ }
+ } else {
+ error = DomainNameResolveError();
+ }
+ }
+
+ ub_resolve_free(result);
+ onResult(addresses, error);
+ }
+
+ private:
+ std::string name;
+};
+
+UnboundDomainNameResolver::UnboundDomainNameResolver(IDNConverter* idnConverter, boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) : idnConverter(idnConverter), ioService(ioService), ubDescriptior(*ioService), eventLoop(eventLoop) {
+ ubContext = ub_ctx_create();
+ if(!ubContext) {
+ SWIFT_LOG(debug) << "could not create unbound context" << std::endl;
+ }
+ eventOwner = boost::make_shared<EventOwner>();
+
+ ub_ctx_async(ubContext, true);
+
+ int ret;
+
+ /* read /etc/resolv.conf for DNS proxy settings (from DHCP) */
+ if( (ret=ub_ctx_resolvconf(ubContext, const_cast<char*>("/etc/resolv.conf"))) != 0) {
+ SWIFT_LOG(error) << "error reading resolv.conf: " << ub_strerror(ret) << ". errno says: " << strerror(errno) << std::endl;
+ }
+ /* read /etc/hosts for locally supplied host addresses */
+ if( (ret=ub_ctx_hosts(ubContext, const_cast<char*>("/etc/hosts"))) != 0) {
+ SWIFT_LOG(error) << "error reading hosts: " << ub_strerror(ret) << ". errno says: " << strerror(errno) << std::endl;
+ }
+
+ ubDescriptior.assign(ub_fd(ubContext));
+
+ ubDescriptior.async_read_some(boost::asio::null_buffers(), boost::bind(&UnboundDomainNameResolver::handleUBSocketReadable, this, boost::asio::placeholders::error));
+}
+
+UnboundDomainNameResolver::~UnboundDomainNameResolver() {
+ eventLoop->removeEventsFromOwner(eventOwner);
+ if (ubContext) {
+ ub_ctx_delete(ubContext);
+ }
+}
+
+void UnboundDomainNameResolver::unbound_callback(boost::shared_ptr<UnboundQuery> query, int err, ub_result* result) {
+ query->handleResult(err, result);
+}
+
+void UnboundDomainNameResolver::unbound_callback_wrapper(void* data, int err, ub_result* result) {
+ UnboundWrapperHelper* helper = static_cast<UnboundWrapperHelper*>(data);
+ UnboundDomainNameResolver* resolver = helper->resolver;
+ resolver->unbound_callback(helper->query, err, result);
+ delete helper;
+}
+
+void UnboundDomainNameResolver::handleUBSocketReadable(boost::system::error_code) {
+ eventLoop->postEvent(boost::bind(&UnboundDomainNameResolver::processData, this), eventOwner);
+ ubDescriptior.async_read_some(boost::asio::null_buffers(), boost::bind(&UnboundDomainNameResolver::handleUBSocketReadable, this, boost::asio::placeholders::error));
+}
+
+void UnboundDomainNameResolver::processData() {
+ if (ub_poll(ubContext)) {
+ int ret = ub_process(ubContext);
+ if(ret != 0) {
+ SWIFT_LOG(debug) << "resolve error: " << ub_strerror(ret) << std::endl;
+ }
+ }
+}
+
+boost::shared_ptr<DomainNameServiceQuery> UnboundDomainNameResolver::createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain) {
+ boost::optional<std::string> encodedDomain = idnConverter->getIDNAEncoded(domain);
+ std::string result;
+ if (encodedDomain) {
+ result = serviceLookupPrefix + *encodedDomain;
+ }
+ return boost::make_shared<UnboundDomainNameServiceQuery>(this, ubContext, result);
+}
+
+boost::shared_ptr<DomainNameAddressQuery> UnboundDomainNameResolver::createAddressQuery(const std::string& name) {
+ return boost::make_shared<UnboundDomainNameAddressQuery>(this, ubContext, idnConverter->getIDNAEncoded(name).get_value_or(""));
+}
+
+}
diff --git a/Swiften/Network/UnboundDomainNameResolver.h b/Swiften/Network/UnboundDomainNameResolver.h
new file mode 100755
index 0000000..6b78cf3
--- /dev/null
+++ b/Swiften/Network/UnboundDomainNameResolver.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Network/DomainNameResolver.h>
+#include <Swiften/Network/Timer.h>
+#include <Swiften/EventLoop/EventOwner.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/asio.hpp>
+
+struct ub_ctx;
+struct ub_result;
+
+namespace Swift {
+ class EventLoop;
+ class IDNConverter;
+ class TimerFactory;
+
+ class UnboundDomainNameResolver;
+ class UnboundQuery;
+
+ class UnboundDomainNameResolver : public DomainNameResolver, public EventOwner, public boost::enable_shared_from_this<UnboundDomainNameResolver> {
+ public:
+ UnboundDomainNameResolver(IDNConverter* idnConverter, boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop);
+ virtual ~UnboundDomainNameResolver();
+
+ virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& serviceLookupPrefix, const std::string& domain);
+ virtual boost::shared_ptr<DomainNameAddressQuery> createAddressQuery(const std::string& name);
+
+ static void unbound_callback_wrapper(void* data, int err, ub_result* result);
+
+ private:
+ void unbound_callback(boost::shared_ptr<UnboundQuery> query, int err, ub_result* result);
+
+ void handleUBSocketReadable(boost::system::error_code);
+ void processData();
+
+ private:
+ IDNConverter* idnConverter;
+ boost::shared_ptr<EventOwner> eventOwner;
+ boost::shared_ptr<boost::asio::io_service> ioService;
+ boost::asio::posix::stream_descriptor ubDescriptior;
+ EventLoop* eventLoop;
+ ub_ctx* ubContext;
+ };
+
+}
diff --git a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
index 82762c5..8a63fcb 100644
--- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
+++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
@@ -48,5 +48,5 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
void setUp() {
to = "wonderland.lit";
- path = "http-bind";
+ path = "/http-bind";
port = "5280";
sid = "MyShinySID";
@@ -171,5 +171,5 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
boost::shared_ptr<MockConnection> c0;
boost::shared_ptr<MockConnection> c1;
- long rid = initialRID;
+ unsigned long long rid = initialRID;
PoolRef testling = createTestling();
@@ -237,5 +237,5 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
to = "prosody.doomsong.co.uk";
resolver->addAddress("prosody.doomsong.co.uk", HostAddress("127.0.0.1"));
- path = "http-bind/";
+ path = "/http-bind/";
boshURL = URL("http", to, 5280, path);
@@ -275,4 +275,22 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(st(3), boshDataWritten.size());
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
+
+ testling->restartStream();
+ eventLoop->processEvents();
+ CPPUNIT_ASSERT_EQUAL(st(4), boshDataWritten.size());
+ CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
+
+ response = "<body xmpp:version='1.0' xmlns:stream='http://etherx.jabber.org/streams' xmlns:xmpp='urn:xmpp:xbosh' inactivity='60' wait='60' polling='5' secure='true' hold='1' from='prosody.doomsong.co.uk' ver='1.6' sid='743da605-4c2e-4de1-afac-ac040dd4a940' requests='2' xmlns='http://jabber.org/protocol/httpbind'><stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><required/></bind><session xmlns='urn:ietf:params:xml:ns:xmpp-session'><optional/></session><sm xmlns='urn:xmpp:sm:2'><optional/></sm></stream:features></body>";
+ readResponse(response, connectionFactory->connections[0]);
+ eventLoop->processEvents();
+ CPPUNIT_ASSERT_EQUAL(st(5), boshDataWritten.size()); /* Now we've authed (restarted) we should be keeping one query in flight so the server can reply to us at any time it wants. */
+ CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
+
+ send = "<body rid='2821988967416214' sid='cf663f6b94279d4f' xmlns='http://jabber.org/protocol/httpbind'><iq id='session-bind' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>d5a9744036cd20a0</resource></bind></iq></body>";
+ testling->write(createSafeByteArray(send));
+ eventLoop->processEvents();
+ CPPUNIT_ASSERT_EQUAL(st(6), boshDataWritten.size());
+ CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size()); /* and as it keeps one in flight, it's needed to open a second to send these data */
+
}
@@ -444,5 +462,5 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
std::string sid;
std::string initial;
- long initialRID;
+ unsigned long long initialRID;
int sessionStarted;
int sessionTerminated;
diff --git a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
index e0dc0bf..0d06420 100644
--- a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
+++ b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
@@ -108,5 +108,5 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
testling->setSID("mySID");
CPPUNIT_ASSERT(testling->isReadyToSend());
- connectionFactory->connections[0]->onDisconnected(false);
+ connectionFactory->connections[0]->onDisconnected(boost::optional<Connection::Error>());
CPPUNIT_ASSERT(!testling->isReadyToSend());
}
@@ -193,6 +193,6 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
BOSHConnection::ref createTestling() {
resolver->addAddress("wonderland.lit", HostAddress("127.0.0.1"));
- Connector::ref connector = Connector::create("wonderland.lit", resolver, connectionFactory, timerFactory, 5280);
- BOSHConnection::ref c = BOSHConnection::create(URL("http", "wonderland.lit", 5280, "http-bind"), connector, &parserFactory);
+ Connector::ref connector = Connector::create("wonderland.lit", 5280, boost::optional<std::string>(), resolver, connectionFactory, timerFactory);
+ BOSHConnection::ref c = BOSHConnection::create(URL("http", "wonderland.lit", 5280, "/http-bind"), connector, &parserFactory);
c->onConnectFinished.connect(boost::bind(&BOSHConnectionTest::handleConnectFinished, this, _1));
c->onDisconnected.connect(boost::bind(&BOSHConnectionTest::handleDisconnected, this, _1));
diff --git a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
index a2fceb9..9176fe7 100644
--- a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
@@ -127,5 +127,5 @@ class ChainedConnectorTest : public CppUnit::TestFixture {
factories.push_back(connectionFactory1);
factories.push_back(connectionFactory2);
- boost::shared_ptr<ChainedConnector> connector = boost::make_shared<ChainedConnector>("foo.com", resolver, factories, timerFactory);
+ boost::shared_ptr<ChainedConnector> connector = boost::make_shared<ChainedConnector>("foo.com", -1, boost::optional<std::string>("_xmpp-client._tcp."), resolver, factories, timerFactory);
connector->onConnectFinished.connect(boost::bind(&ChainedConnectorTest::handleConnectorFinished, this, _1, _2));
return connector;
diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp
index 67270be..3b1d4e4 100644
--- a/Swiften/Network/UnitTest/ConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ConnectorTest.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -25,4 +25,6 @@ class ConnectorTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ConnectorTest);
CPPUNIT_TEST(testConnect);
+ CPPUNIT_TEST(testConnect_NoServiceLookups);
+ CPPUNIT_TEST(testConnect_NoServiceLookups_DefaultPort);
CPPUNIT_TEST(testConnect_FirstAddressHostFails);
CPPUNIT_TEST(testConnect_NoSRVHost);
@@ -32,6 +34,7 @@ class ConnectorTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testConnect_AllSRVHostsFailWithFallbackHost);
CPPUNIT_TEST(testConnect_SRVAndFallbackHostsFail);
- CPPUNIT_TEST(testConnect_TimeoutDuringResolve);
- CPPUNIT_TEST(testConnect_TimeoutDuringConnect);
+ //CPPUNIT_TEST(testConnect_TimeoutDuringResolve);
+ CPPUNIT_TEST(testConnect_TimeoutDuringConnectToOnlyCandidate);
+ CPPUNIT_TEST(testConnect_TimeoutDuringConnectToCandidateFallsBack);
CPPUNIT_TEST(testConnect_NoTimeout);
CPPUNIT_TEST(testStop_DuringSRVQuery);
@@ -72,4 +75,36 @@ class ConnectorTest : public CppUnit::TestFixture {
}
+ void testConnect_NoServiceLookups() {
+ Connector::ref testling(createConnector(4321, boost::optional<std::string>()));
+ resolver->addXMPPClientService("foo.com", host1);
+ resolver->addXMPPClientService("foo.com", host2);
+ resolver->addAddress("foo.com", host3.getAddress());
+
+ testling->start();
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
+ CPPUNIT_ASSERT(connections[0]);
+ CPPUNIT_ASSERT(host3.getAddress() == (*(connections[0]->hostAddressPort)).getAddress());
+ CPPUNIT_ASSERT(4321 == (*(connections[0]->hostAddressPort)).getPort());
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
+ }
+
+ void testConnect_NoServiceLookups_DefaultPort() {
+ Connector::ref testling(createConnector(-1, boost::optional<std::string>()));
+ resolver->addXMPPClientService("foo.com", host1);
+ resolver->addXMPPClientService("foo.com", host2);
+ resolver->addAddress("foo.com", host3.getAddress());
+
+ testling->start();
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
+ CPPUNIT_ASSERT(connections[0]);
+ CPPUNIT_ASSERT(host3.getAddress() == (*(connections[0]->hostAddressPort)).getAddress());
+ CPPUNIT_ASSERT_EQUAL(5222, (*(connections[0]->hostAddressPort)).getPort());
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
+ }
+
void testConnect_NoSRVHost() {
Connector::ref testling(createConnector());
@@ -176,5 +211,5 @@ class ConnectorTest : public CppUnit::TestFixture {
}
- void testConnect_TimeoutDuringResolve() {
+ /*void testConnect_TimeoutDuringResolve() {
Connector::ref testling(createConnector());
testling->setTimeoutMilliseconds(10);
@@ -189,7 +224,7 @@ class ConnectorTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(boost::dynamic_pointer_cast<DomainNameResolveError>(error));
CPPUNIT_ASSERT(!connections[0]);
- }
+ }*/
- void testConnect_TimeoutDuringConnect() {
+ void testConnect_TimeoutDuringConnectToOnlyCandidate() {
Connector::ref testling(createConnector());
testling->setTimeoutMilliseconds(10);
@@ -207,4 +242,28 @@ class ConnectorTest : public CppUnit::TestFixture {
}
+ void testConnect_TimeoutDuringConnectToCandidateFallsBack() {
+ Connector::ref testling(createConnector());
+ testling->setTimeoutMilliseconds(10);
+
+ resolver->addXMPPClientService("foo.com", "host-foo.com", 1234);
+ HostAddress address1("1.1.1.1");
+ resolver->addAddress("host-foo.com", address1);
+ HostAddress address2("2.2.2.2");
+ resolver->addAddress("host-foo.com", address2);
+
+ connectionFactory->isResponsive = false;
+ testling->start();
+ eventLoop->processEvents();
+ connectionFactory->isResponsive = true;
+ timerFactory->setTime(10);
+ eventLoop->processEvents();
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connections.size()));
+ CPPUNIT_ASSERT(connections[0]);
+ CPPUNIT_ASSERT(HostAddressPort(address2, 1234) == *(connections[0]->hostAddressPort));
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<DomainNameResolveError>(error));
+ }
+
+
void testConnect_NoTimeout() {
Connector::ref testling(createConnector());
@@ -254,6 +313,6 @@ class ConnectorTest : public CppUnit::TestFixture {
private:
- Connector::ref createConnector() {
- Connector::ref connector = Connector::create("foo.com", resolver, connectionFactory, timerFactory);
+ Connector::ref createConnector(int port = -1, boost::optional<std::string> serviceLookupPrefix = boost::optional<std::string>("_xmpp-client._tcp.")) {
+ Connector::ref connector = Connector::create("foo.com", port, serviceLookupPrefix, resolver, connectionFactory, timerFactory);
connector->onConnectFinished.connect(boost::bind(&ConnectorTest::handleConnectorFinished, this, _1, _2));
return connector;
diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
index 347a145..134748f 100644
--- a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
+++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
@@ -171,5 +171,5 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
private:
HTTPConnectProxiedConnection::ref createTestling() {
- boost::shared_ptr<HTTPConnectProxiedConnection> c = HTTPConnectProxiedConnection::create(resolver, connectionFactory, timerFactory, eventLoop, proxyHost, proxyPort, "", "");
+ boost::shared_ptr<HTTPConnectProxiedConnection> c = HTTPConnectProxiedConnection::create(resolver, connectionFactory, timerFactory, proxyHost, proxyPort, "", "");
c->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleConnectFinished, this, _1));
c->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleDisconnected, this, _1));
diff --git a/Swiften/Network/UnixNetworkEnvironment.cpp b/Swiften/Network/UnixNetworkEnvironment.cpp
index 52c5cbe..e1fdc88 100644
--- a/Swiften/Network/UnixNetworkEnvironment.cpp
+++ b/Swiften/Network/UnixNetworkEnvironment.cpp
@@ -15,5 +15,8 @@
#include <arpa/inet.h>
#include <net/if.h>
+
+#ifndef __ANDROID__
#include <ifaddrs.h>
+#endif
#include <Swiften/Base/boost_bsignals.h>
@@ -25,5 +28,5 @@ namespace Swift {
std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() const {
std::map<std::string, NetworkInterface> interfaces;
-
+#ifndef __ANDROID__
ifaddrs* addrs = 0;
int ret = getifaddrs(&addrs);
@@ -43,5 +46,5 @@ std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() con
address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin6_addr)), 16);
}
- if (address) {
+ if (address && !address->isLocalhost()) {
std::map<std::string, NetworkInterface>::iterator i = interfaces.insert(std::make_pair(name, NetworkInterface(name, a->ifa_flags & IFF_LOOPBACK))).first;
i->second.addAddress(*address);
@@ -50,5 +53,5 @@ std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() con
freeifaddrs(addrs);
-
+#endif
std::vector<NetworkInterface> result;
for (std::map<std::string,NetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) {
diff --git a/Swiften/Network/WindowsNetworkEnvironment.cpp b/Swiften/Network/WindowsNetworkEnvironment.cpp
index 20f559d..e2d1966 100644
--- a/Swiften/Network/WindowsNetworkEnvironment.cpp
+++ b/Swiften/Network/WindowsNetworkEnvironment.cpp
@@ -51,5 +51,5 @@ std::vector<NetworkInterface> WindowsNetworkEnvironment::getNetworkInterfaces()
hostAddress = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin6_addr)), 16);
}
- if (hostAddress) {
+ if (hostAddress && !hostAddress->isLocalhost()) {
std::map<std::string, NetworkInterface>::iterator i = interfaces.insert(std::make_pair(name, NetworkInterface(name, false))).first;
i->second.addAddress(*hostAddress);
diff --git a/Swiften/Network/WindowsNetworkEnvironment.h b/Swiften/Network/WindowsNetworkEnvironment.h
index f43b951..18996ed 100644
--- a/Swiften/Network/WindowsNetworkEnvironment.h
+++ b/Swiften/Network/WindowsNetworkEnvironment.h
@@ -8,10 +8,11 @@
#include <vector>
-#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
+#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Network/NetworkEnvironment.h>
namespace Swift {
- class WindowsNetworkEnvironment : public NetworkEnvironment {
+ class SWIFTEN_API WindowsNetworkEnvironment : public NetworkEnvironment {
public:
std::vector<NetworkInterface> getNetworkInterfaces() const;
diff --git a/Swiften/Network/WindowsProxyProvider.h b/Swiften/Network/WindowsProxyProvider.h
index c2d1f51..12aa18d 100644
--- a/Swiften/Network/WindowsProxyProvider.h
+++ b/Swiften/Network/WindowsProxyProvider.h
@@ -6,8 +6,10 @@
#pragma once
+
+#include <Swiften/Base/API.h>
#include <Swiften/Network/ProxyProvider.h>
namespace Swift {
- class WindowsProxyProvider : public ProxyProvider {
+ class SWIFTEN_API WindowsProxyProvider : public ProxyProvider {
public:
WindowsProxyProvider();