diff options
Diffstat (limited to 'Swiften/Network')
39 files changed, 566 insertions, 118 deletions
diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp index 377373d..23772eb 100644 --- a/Swiften/Network/BOSHConnection.cpp +++ b/Swiften/Network/BOSHConnection.cpp @@ -110,7 +110,7 @@ std::pair<SafeByteArray, size_t> BOSHConnection::createHTTPRequest(const SafeByt header << ":" << *boshURL.getPort(); } header << "\r\n" - /*<< "Accept-Encoding: deflate\r\n"*/ + // << "Accept-Encoding: deflate\r\n" << "Content-Type: text/xml; charset=utf-8\r\n" << "Content-Length: " << size << "\r\n\r\n"; @@ -156,7 +156,7 @@ void BOSHConnection::startStream(const std::string& to, unsigned long long rid) << " rid='" << 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'" << " xmpp:version='1.0'" @@ -170,7 +170,7 @@ void BOSHConnection::startStream(const std::string& to, unsigned long long rid) header << ":" << *boshURL_.getPort(); } header << "\r\n" - /*<< "Accept-Encoding: deflate\r\n"*/ + // << "Accept-Encoding: deflate\r\n" << "Content-Type: text/xml; charset=utf-8\r\n" << "Content-Length: " << contentString.size() << "\r\n\r\n" << contentString; @@ -208,7 +208,7 @@ void BOSHConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) { waitingForStartResponse_ = false; 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 { requests = boost::lexical_cast<size_t>(requestsString); diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp index e535deb..4517ffb 100644 --- a/Swiften/Network/BOSHConnectionPool.cpp +++ b/Swiften/Network/BOSHConnectionPool.cpp @@ -210,14 +210,14 @@ void BOSHConnectionPool::handleHTTPError(const std::string& /*errorCode*/) { handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition)); } -void BOSHConnectionPool::handleConnectionDisconnected(bool error, BOSHConnection::ref connection) { +void BOSHConnectionPool::handleConnectionDisconnected(bool/* error*/, BOSHConnection::ref connection) { destroyConnection(connection); if (pendingTerminate && sid.empty() && connections.empty()) { handleSessionTerminated(BOSHError::ref()); } - else if (false && error) { - handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition)); - } + //else if (error) { + // handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition)); + //} else { /* We might have just freed up a connection slot to send with */ tryToSendQueuedData(); 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 @@ -14,6 +14,7 @@ #include <boost/asio/placeholders.hpp> #include <boost/asio/write.hpp> #include <boost/smart_ptr/make_shared.hpp> +#include <boost/numeric/conversion/cast.hpp> #include <Swiften/Base/Log.h> #include <Swiften/Base/Algorithm.h> @@ -63,7 +64,7 @@ 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, boost::bind(&BoostConnection::handleConnectFinished, shared_from_this(), boost::asio::placeholders::error)); 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 @@ -9,6 +9,8 @@ #include <boost/bind.hpp> #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> @@ -21,28 +23,36 @@ 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_); if (address_.isValid()) { 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(); } 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 66af2a4..3ad0450 100644 --- a/Swiften/Network/BoostConnectionServer.h +++ b/Swiften/Network/BoostConnectionServer.h @@ -16,17 +16,13 @@ #include <Swiften/Network/BoostConnection.h> #include <Swiften/Network/ConnectionServer.h> #include <Swiften/EventLoop/EventOwner.h> +#include <boost/optional/optional_fwd.hpp> namespace Swift { 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,6 +31,7 @@ namespace Swift { return ref(new BoostConnectionServer(address, port, ioService, eventLoop)); } + virtual boost::optional<Error> tryStart(); // FIXME: This should become the new start virtual void start(); virtual void stop(); diff --git a/Swiften/Network/BoostNetworkFactories.cpp b/Swiften/Network/BoostNetworkFactories.cpp index 488e519..72e826a 100644 --- a/Swiften/Network/BoostNetworkFactories.cpp +++ b/Swiften/Network/BoostNetworkFactories.cpp @@ -1,5 +1,5 @@ /* - * 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,38 +7,60 @@ #include <Swiften/Network/BoostNetworkFactories.h> #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 { BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) : eventLoop(eventLoop){ 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 natTraverser = new PlatformNATTraversalWorker(eventLoop); #else 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(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 1968acd..9c3bab1 100644 --- a/Swiften/Network/BoostNetworkFactories.h +++ b/Swiften/Network/BoostNetworkFactories.h @@ -1,5 +1,5 @@ /* - * 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,6 +7,7 @@ #pragma once #include <Swiften/Base/API.h> +#include <Swiften/Base/Override.h> #include <Swiften/Network/NetworkFactories.h> #include <Swiften/Network/BoostIOServiceThread.h> @@ -20,11 +21,11 @@ namespace Swift { 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,32 +33,44 @@ namespace Swift { return &ioServiceThread; } - 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; TimerFactory* timerFactory; @@ -65,9 +78,12 @@ namespace Swift { DomainNameResolver* domainNameResolver; ConnectionServerFactory* connectionServerFactory; NATTraverser* natTraverser; + NetworkEnvironment* networkEnvironment; XMLParserFactory* xmlParserFactory; PlatformTLSFactories* tlsFactories; ProxyProvider* proxyProvider; EventLoop* eventLoop; + IDNConverter* idnConverter; + CryptoProvider* cryptoProvider; }; } diff --git a/Swiften/Network/ChainedConnector.h b/Swiften/Network/ChainedConnector.h index 4110522..03462bc 100644 --- a/Swiften/Network/ChainedConnector.h +++ b/Swiften/Network/ChainedConnector.h @@ -49,4 +49,4 @@ namespace Swift { boost::shared_ptr<Connector> currentConnector; boost::shared_ptr<Error> lastError; }; -}; +} diff --git a/Swiften/Network/ConnectionServer.h b/Swiften/Network/ConnectionServer.h index e644d90..2e09348 100644 --- a/Swiften/Network/ConnectionServer.h +++ b/Swiften/Network/ConnectionServer.h @@ -12,14 +12,22 @@ #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 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; virtual void stop() = 0; diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp index 5ab3b92..a0155cf 100644 --- a/Swiften/Network/Connector.cpp +++ b/Swiften/Network/Connector.cpp @@ -183,4 +183,4 @@ void Connector::handleTimeout() { handleConnectionConnectFinished(true); } -}; +} diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h index 26a98b8..49ac271 100644 --- a/Swiften/Network/Connector.h +++ b/Swiften/Network/Connector.h @@ -71,4 +71,4 @@ namespace Swift { boost::shared_ptr<Connection> currentConnection; bool foundSomeDNS; }; -}; +} 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,5 +1,5 @@ /* - * 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. */ @@ -13,8 +13,12 @@ #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 { struct ResultPriorityComparator { @@ -22,14 +26,6 @@ namespace { return a.priority < b.priority; } }; - - 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 */; - } - }; } namespace Swift { @@ -39,19 +35,24 @@ 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(); while (i != queries.end()) { std::vector<DomainNameServiceQuery::Result>::iterator next = std::upper_bound(i, queries.end(), *i, comparator); 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/HostAddress.cpp b/Swiften/Network/HostAddress.cpp index f00581f..ff5c1c4 100644 --- a/Swiften/Network/HostAddress.cpp +++ b/Swiften/Network/HostAddress.cpp @@ -1,5 +1,5 @@ /* - * 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. */ @@ -15,6 +15,9 @@ #include <Swiften/Base/foreach.h> #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 { HostAddress::HostAddress() { @@ -28,18 +31,18 @@ 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]; } address_ = boost::asio::ip::address(boost::asio::ip::address_v4(data)); } 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]; } address_ = boost::asio::ip::address(boost::asio::ip::address_v6(data)); @@ -61,4 +64,8 @@ boost::asio::ip::address HostAddress::getRawAddress() const { return address_; } +bool HostAddress::isLocalhost() const { + return address_ == localhost4 || address_ == localhost6; +} + } diff --git a/Swiften/Network/HostAddress.h b/Swiften/Network/HostAddress.h index 621aa5d..c62239b 100644 --- a/Swiften/Network/HostAddress.h +++ b/Swiften/Network/HostAddress.h @@ -1,5 +1,5 @@ /* - * 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. */ @@ -15,7 +15,7 @@ namespace Swift { 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); std::string toString() const; @@ -26,6 +26,7 @@ namespace Swift { } bool isValid() const; + bool isLocalhost() const; private: boost::asio::ip::address address_; diff --git a/Swiften/Network/MacOSXProxyProvider.cpp b/Swiften/Network/MacOSXProxyProvider.cpp index 00fb478..3456c73 100644 --- a/Swiften/Network/MacOSXProxyProvider.cpp +++ b/Swiften/Network/MacOSXProxyProvider.cpp @@ -4,18 +4,27 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * 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> #include <stdio.h> #include <stdlib.h> #include <iostream> +#include <boost/numeric/conversion/cast.hpp> #include <utility> #ifndef SWIFTEN_PLATFORM_IPHONE #include <SystemConfiguration/SystemConfiguration.h> #endif +#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" + using namespace Swift; #ifndef SWIFTEN_PLATFORM_IPHONE @@ -27,6 +36,7 @@ static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabl const int i = 0; CFNumberRef zero = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); CFComparisonResult result = CFNumberCompare(numberValue, zero, NULL); + CFRelease(zero); if(result != kCFCompareEqualTo) { int port = 0; @@ -44,7 +54,7 @@ static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabl // length must be +1 for the ending zero; and the Docu of CFStringGetCString tells it like // 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) { host += *iter; @@ -75,6 +85,7 @@ HostAddressPort MacOSXProxyProvider::getHTTPConnectProxy() const { CFDictionaryRef proxies = SCDynamicStoreCopyProxies(NULL); if(proxies != NULL) { result = getFromDictionary(proxies, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); + CFRelease(proxies); } #endif return result; @@ -86,6 +97,7 @@ HostAddressPort MacOSXProxyProvider::getSOCKS5Proxy() const { CFDictionaryRef proxies = SCDynamicStoreCopyProxies(NULL); if(proxies != NULL) { result = getFromDictionary(proxies, kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort); + CFRelease(proxies); } #endif return result; diff --git a/Swiften/Network/MiniUPnPInterface.cpp b/Swiften/Network/MiniUPnPInterface.cpp index c729371..bfa989f 100644 --- a/Swiften/Network/MiniUPnPInterface.cpp +++ b/Swiften/Network/MiniUPnPInterface.cpp @@ -72,7 +72,16 @@ boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLoca std::string localPort = boost::lexical_cast<std::string>(mapping.getLocalPort()); std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds()); - int ret = UPNP_AddPortMapping(p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), localPort.c_str(), p->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; } diff --git a/Swiften/Network/NATPMPInterface.cpp b/Swiften/Network/NATPMPInterface.cpp index 220e3e9..c7a41ff 100644 --- a/Swiften/Network/NATPMPInterface.cpp +++ b/Swiften/Network/NATPMPInterface.cpp @@ -7,6 +7,7 @@ #include <Swiften/Network/NATPMPInterface.h> #include <boost/smart_ptr/make_shared.hpp> +#include <boost/numeric/conversion/cast.hpp> #include <Swiften/Base/Log.h> @@ -63,9 +64,14 @@ boost::optional<HostAddress> NATPMPInterface::getPublicIP() { boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, int publicPort) { NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP); - if (sendnewportmappingrequest(&p->natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.getLeaseInSeconds(), mapping.getPublicPort(), mapping.getLocalPort()) < 0) { - SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl; - return boost::optional<NATPortMapping>(); + 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>(); } int r = 0; @@ -81,7 +87,7 @@ boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, i } 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; } else { @@ -91,7 +97,7 @@ boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, i } bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) { - if (sendnewportmappingrequest(&p->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; } 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 @@ -13,10 +13,11 @@ namespace Swift { public: 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 35b23c4..48f85ea 100644 --- a/Swiften/Network/NATTraversalForwardPortRequest.h +++ b/Swiften/Network/NATTraversalForwardPortRequest.h @@ -16,7 +16,8 @@ namespace Swift { 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 @@ -14,7 +14,8 @@ namespace Swift { public: 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 @@ -15,7 +15,7 @@ namespace Swift { struct PortMapping { enum Protocol { TCP, - UDP, + UDP }; unsigned int publicPort; @@ -27,7 +27,8 @@ namespace Swift { public: 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/NetworkFactories.h b/Swiften/Network/NetworkFactories.h index c8009a6..dd8e216 100644 --- a/Swiften/Network/NetworkFactories.h +++ b/Swiften/Network/NetworkFactories.h @@ -1,5 +1,5 @@ /* - * 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,6 +17,9 @@ namespace Swift { class CertificateFactory; class ProxyProvider; class EventLoop; + class IDNConverter; + class NetworkEnvironment; + class CryptoProvider; /** * An interface collecting network factories. @@ -30,9 +33,12 @@ namespace Swift { virtual DomainNameResolver* getDomainNameResolver() const = 0; 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 @@ -21,10 +21,13 @@ class NullNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest NullNATTraversalGetPublicIPRequest(EventLoop* eventLoop) : eventLoop(eventLoop) { } - virtual void run() { + virtual void start() { eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<HostAddress>())); } + virtual void stop() { + } + private: EventLoop* eventLoop; }; @@ -34,10 +37,13 @@ class NullNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest NullNATTraversalForwardPortRequest(EventLoop* eventLoop) : eventLoop(eventLoop) { } - virtual void run() { + virtual void start() { eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<NATPortMapping>())); } + virtual void stop() { + } + private: EventLoop* eventLoop; }; @@ -47,10 +53,13 @@ class NullNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePor NullNATTraversalRemovePortForwardingRequest(EventLoop* eventLoop) : eventLoop(eventLoop) { } - 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/PlatformDomainNameResolver.cpp b/Swiften/Network/PlatformDomainNameResolver.cpp index 63f7404..677f1d5 100644 --- a/Swiften/Network/PlatformDomainNameResolver.cpp +++ b/Swiften/Network/PlatformDomainNameResolver.cpp @@ -1,5 +1,5 @@ /* - * 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,7 +16,7 @@ #include <algorithm> #include <string> -#include <Swiften/IDN/IDNA.h> +#include <Swiften/IDN/IDNConverter.h> #include <Swiften/Network/HostAddress.h> #include <Swiften/EventLoop/EventLoop.h> #include <Swiften/Network/HostAddressPort.h> @@ -27,7 +27,7 @@ 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,11 +39,11 @@ PlatformDomainNameResolver::~PlatformDomainNameResolver() { } boost::shared_ptr<DomainNameServiceQuery> PlatformDomainNameResolver::createServiceQuery(const std::string& name) { - return boost::shared_ptr<DomainNameServiceQuery>(new PlatformDomainNameServiceQuery(IDNA::getEncoded(name), eventLoop, this)); + return boost::shared_ptr<DomainNameServiceQuery>(new PlatformDomainNameServiceQuery(idnConverter->getIDNAEncoded(name), 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)); } void PlatformDomainNameResolver::run() { diff --git a/Swiften/Network/PlatformDomainNameResolver.h b/Swiften/Network/PlatformDomainNameResolver.h index 0617d9e..25d87cf 100644 --- a/Swiften/Network/PlatformDomainNameResolver.h +++ b/Swiften/Network/PlatformDomainNameResolver.h @@ -1,5 +1,5 @@ /* - * 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,12 +18,12 @@ #include <Swiften/Network/DomainNameAddressQuery.h> namespace Swift { - + class IDNConverter; class EventLoop; class SWIFTEN_API PlatformDomainNameResolver : public DomainNameResolver { public: - PlatformDomainNameResolver(EventLoop* eventLoop); + PlatformDomainNameResolver(IDNConverter* idnConverter, EventLoop* eventLoop); ~PlatformDomainNameResolver(); virtual DomainNameServiceQuery::ref createServiceQuery(const std::string& name); @@ -36,6 +36,7 @@ namespace Swift { private: friend class PlatformDomainNameServiceQuery; friend class PlatformDomainNameAddressQuery; + IDNConverter* idnConverter; EventLoop* eventLoop; bool stopRequested; boost::thread* thread; diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.cpp b/Swiften/Network/PlatformDomainNameServiceQuery.cpp index b0579a7..5788d2f 100644 --- a/Swiften/Network/PlatformDomainNameServiceQuery.cpp +++ b/Swiften/Network/PlatformDomainNameServiceQuery.cpp @@ -12,6 +12,7 @@ #include <Swiften/Base/Platform.h> #include <stdlib.h> +#include <boost/numeric/conversion/cast.hpp> #ifdef SWIFTEN_PLATFORM_WINDOWS #undef UNICODE #include <windows.h> @@ -121,7 +122,7 @@ void PlatformDomainNameServiceQuery::runBlocking() { emitError(); return; } - record.priority = ns_get16(currentEntry); + record.priority = boost::numeric_cast<int>(ns_get16(currentEntry)); currentEntry += 2; // Weight @@ -129,7 +130,7 @@ void PlatformDomainNameServiceQuery::runBlocking() { emitError(); return; } - record.weight = ns_get16(currentEntry); + record.weight = boost::numeric_cast<int>(ns_get16(currentEntry)); currentEntry += 2; // Port @@ -137,7 +138,7 @@ void PlatformDomainNameServiceQuery::runBlocking() { emitError(); return; } - record.port = ns_get16(currentEntry); + record.port = boost::numeric_cast<int>(ns_get16(currentEntry)); currentEntry += 2; // Hostname diff --git a/Swiften/Network/PlatformDomainNameServiceQuery.h b/Swiften/Network/PlatformDomainNameServiceQuery.h index 3372517..310e639 100644 --- a/Swiften/Network/PlatformDomainNameServiceQuery.h +++ b/Swiften/Network/PlatformDomainNameServiceQuery.h @@ -1,5 +1,5 @@ /* - * 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. */ diff --git a/Swiften/Network/PlatformNATTraversalWorker.cpp b/Swiften/Network/PlatformNATTraversalWorker.cpp index c962b3b..133b006 100644 --- a/Swiften/Network/PlatformNATTraversalWorker.cpp +++ b/Swiften/Network/PlatformNATTraversalWorker.cpp @@ -8,13 +8,18 @@ #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/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 { @@ -49,10 +54,14 @@ class PlatformNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPReq PlatformNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) { } - virtual void run() { + virtual void start() { doRun(); } + virtual void stop() { + // TODO + } + virtual void runBlocking() { onResult(getNATTraversalInterface()->getPublicIP()); } @@ -63,12 +72,16 @@ class PlatformNATTraversalForwardPortRequest : public NATTraversalForwardPortReq PlatformNATTraversalForwardPortRequest(PlatformNATTraversalWorker* worker, unsigned int localIP, unsigned int publicIP) : PlatformNATTraversalRequest(worker), localIP(localIP), publicIP(publicIP) { } - virtual void run() { + virtual void start() { doRun(); } + virtual void stop() { + // TODO + } + virtual void runBlocking() { - onResult(getNATTraversalInterface()->addPortForward(localIP, publicIP)); + onResult(getNATTraversalInterface()->addPortForward(boost::numeric_cast<int>(localIP), boost::numeric_cast<int>(publicIP))); } private: @@ -81,10 +94,14 @@ class PlatformNATTraversalRemovePortForwardingRequest : public NATTraversalRemov PlatformNATTraversalRemovePortForwardingRequest(PlatformNATTraversalWorker* worker, const NATPortMapping& mapping) : PlatformNATTraversalRequest(worker), mapping(mapping) { } - virtual void run() { + virtual void start() { doRun(); } + virtual void stop() { + // TODO + } + virtual void runBlocking() { onResult(getNATTraversalInterface()->removePortForward(mapping)); } @@ -95,7 +112,8 @@ 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)); } PlatformNATTraversalWorker::~PlatformNATTraversalWorker() { @@ -103,12 +121,17 @@ PlatformNATTraversalWorker::~PlatformNATTraversalWorker() { addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>()); 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(); miniUPnPSupported = miniUPnPInterface->isAvailable(); @@ -116,8 +139,9 @@ NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() co if (miniUPnPSupported) { return miniUPnPInterface; } +#endif - +#ifdef HAVE_LIBNATPMP if (boost::logic::indeterminate(natPMPSupported)) { natPMPInterface = new NATPMPInterface(); natPMPSupported = natPMPInterface->isAvailable(); @@ -125,6 +149,7 @@ NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() co if (natPMPSupported) { return natPMPInterface; } +#endif return nullNATTraversalInterface; } @@ -142,7 +167,7 @@ boost::shared_ptr<NATTraversalRemovePortForwardingRequest> PlatformNATTraversalW return boost::make_shared<PlatformNATTraversalRemovePortForwardingRequest>(this, mapping); } -void PlatformNATTraversalWorker::run() { +void PlatformNATTraversalWorker::start() { while (!stopRequested) { PlatformNATTraversalRequest::ref request; { @@ -161,6 +186,10 @@ void PlatformNATTraversalWorker::run() { } } +void PlatformNATTraversalWorker::stop() { + // TODO +} + void PlatformNATTraversalWorker::addRequestToQueue(PlatformNATTraversalRequest::ref request) { { boost::lock_guard<boost::mutex> lock(queueMutex); diff --git a/Swiften/Network/PlatformNATTraversalWorker.h b/Swiften/Network/PlatformNATTraversalWorker.h index 8060e31..6148705 100644 --- a/Swiften/Network/PlatformNATTraversalWorker.h +++ b/Swiften/Network/PlatformNATTraversalWorker.h @@ -43,7 +43,8 @@ namespace Swift { private: NATTraversalInterface* getNATTraversalInterface() const; void addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>); - void run(); + void start(); + void stop(); private: EventLoop* eventLoop; 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 @@ -7,7 +7,6 @@ #pragma once #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 b742bfe..ea0fb62 100644 --- a/Swiften/Network/SConscript +++ b/Swiften/Network/SConscript @@ -2,6 +2,10 @@ Import("swiften_env") myenv = swiften_env.Clone() +if myenv.get("unbound", False) : + myenv.MergeFlags(myenv.get("UNBOUND_FLAGS", {})) + myenv.MergeFlags(myenv.get("LDNS_FLAGS", {})) + sourceList = [ "ProxiedConnection.cpp", "HTTPConnectProxiedConnection.cpp", @@ -30,9 +34,6 @@ sourceList = [ "DomainNameResolver.cpp", "DomainNameAddressQuery.cpp", "DomainNameServiceQuery.cpp", - "PlatformDomainNameResolver.cpp", - "PlatformDomainNameServiceQuery.cpp", - "PlatformDomainNameAddressQuery.cpp", "StaticDomainNameResolver.cpp", "HostAddress.cpp", "HostAddressPort.cpp", @@ -53,8 +54,16 @@ sourceList = [ "NATTraversalRemovePortForwardingRequest.cpp", "NATTraversalInterface.cpp", ] - -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" ] sourceList += [ "UnixNetworkEnvironment.cpp" ] @@ -72,20 +81,24 @@ else : objects = myenv.SwiftenObject(sourceList) -if myenv["experimental"] : +if myenv["experimental"] : # LibNATPMP classes - natpmp_env = myenv.Clone() - natpmp_env.Append(CPPDEFINES = natpmp_env["LIBNATPMP_FLAGS"].get("INTERNAL_CPPDEFINES", [])) - objects += natpmp_env.SwiftenObject([ - "NATPMPInterface.cpp", - ]) + 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", + ]) # LibMINIUPnP classes - upnp_env = myenv.Clone() - upnp_env.Append(CPPDEFINES = upnp_env["LIBMINIUPNPC_FLAGS"].get("INTERNAL_CPPDEFINES", [])) - objects += upnp_env.SwiftenObject([ - "MiniUPnPInterface.cpp", - ]) + 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", + ]) objects += myenv.SwiftenObject([ "PlatformNATTraversalWorker.cpp", ]) diff --git a/Swiften/Network/SOCKS5ProxiedConnection.cpp b/Swiften/Network/SOCKS5ProxiedConnection.cpp index bf7a056..a9243d6 100644 --- a/Swiften/Network/SOCKS5ProxiedConnection.cpp +++ b/Swiften/Network/SOCKS5ProxiedConnection.cpp @@ -65,7 +65,7 @@ void SOCKS5ProxiedConnection::handleProxyInitializeData(boost::shared_ptr<SafeBy else { 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> ((getServer().getPort() >> 8) & 0xFF)); // highbyte of the port. diff --git a/Swiften/Network/SOCKS5ProxiedConnection.h b/Swiften/Network/SOCKS5ProxiedConnection.h index 61092e0..7906879 100644 --- a/Swiften/Network/SOCKS5ProxiedConnection.h +++ b/Swiften/Network/SOCKS5ProxiedConnection.h @@ -30,7 +30,7 @@ namespace Swift { private: enum { ProxyAuthenticating = 0, - ProxyConnecting, + ProxyConnecting } proxyState_; }; } 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 @@ -24,7 +24,7 @@ namespace Swift { TLSConnection(Connection::ref connection, TLSContextFactory* tlsFactory); virtual ~TLSConnection(); - virtual void listen() {assert(false);}; + virtual void listen() {assert(false);} virtual void connect(const HostAddressPort& address); virtual void disconnect(); virtual void write(const SafeByteArray& data); diff --git a/Swiften/Network/UnboundDomainNameResolver.cpp b/Swiften/Network/UnboundDomainNameResolver.cpp new file mode 100755 index 0000000..d986385 --- /dev/null +++ b/Swiften/Network/UnboundDomainNameResolver.cpp @@ -0,0 +1,241 @@ +/* + * 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/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(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) : 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(debug) << "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(debug) << "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& name) { + return boost::make_shared<UnboundDomainNameServiceQuery>(this, ubContext, name); +} + +boost::shared_ptr<DomainNameAddressQuery> UnboundDomainNameResolver::createAddressQuery(const std::string& name) { + return boost::make_shared<UnboundDomainNameAddressQuery>(this, ubContext, name); +} + +} diff --git a/Swiften/Network/UnboundDomainNameResolver.h b/Swiften/Network/UnboundDomainNameResolver.h new file mode 100755 index 0000000..0db8a66 --- /dev/null +++ b/Swiften/Network/UnboundDomainNameResolver.h @@ -0,0 +1,51 @@ +/* + * 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 TimerFactory; + + class UnboundDomainNameResolver; + class UnboundQuery; + + class UnboundDomainNameResolver : public DomainNameResolver, public EventOwner, public boost::enable_shared_from_this<UnboundDomainNameResolver> { + public: + UnboundDomainNameResolver(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop); + virtual ~UnboundDomainNameResolver(); + + virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& name); + 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: + 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 23f1a3c..8a63fcb 100644 --- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp +++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp @@ -170,7 +170,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture { void testConnectionCount_ThreeWritesTwoReads() { boost::shared_ptr<MockConnection> c0; boost::shared_ptr<MockConnection> c1; - long rid = initialRID; + unsigned long long rid = initialRID; PoolRef testling = createTestling(); CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size()); @@ -461,7 +461,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture { std::string port; std::string sid; std::string initial; - long initialRID; + unsigned long long initialRID; int sessionStarted; int sessionTerminated; 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 @@ -14,7 +14,10 @@ #include <sys/socket.h> #include <arpa/inet.h> #include <net/if.h> + +#ifndef __ANDROID__ #include <ifaddrs.h> +#endif #include <Swiften/Base/boost_bsignals.h> #include <Swiften/Network/HostAddress.h> @@ -24,7 +27,7 @@ namespace Swift { std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() const { std::map<std::string, NetworkInterface> interfaces; - +#ifndef __ANDROID__ ifaddrs* addrs = 0; int ret = getifaddrs(&addrs); if (ret != 0) { @@ -42,14 +45,14 @@ std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() con sockaddr_in6* sa = reinterpret_cast<sockaddr_in6*>(a->ifa_addr); 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); } } freeifaddrs(addrs); - +#endif std::vector<NetworkInterface> result; for (std::map<std::string,NetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) { result.push_back(i->second); 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 @@ -50,7 +50,7 @@ std::vector<NetworkInterface> WindowsNetworkEnvironment::getNetworkInterfaces() sockaddr_in6* sa = reinterpret_cast<sockaddr_in6*>(address->Address.lpSockaddr); 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); } |