From cb1cc3c0205295002f2cd760cbd801842b30096e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 31 Dec 2009 16:00:15 +0100 Subject: Put a timeout of 60s on connecting & resolving. Resolves: #87. diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 27f3d9c..c704248 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -36,8 +36,9 @@ bool Client::isAvailable() { void Client::connect() { assert(!connector_); - connector_ = boost::shared_ptr<Connector>(new Connector(jid_.getDomain(), &resolver_, connectionFactory_)); + connector_ = boost::shared_ptr<Connector>(new Connector(jid_.getDomain(), &resolver_, connectionFactory_, timerFactory_)); connector_->onConnectFinished.connect(boost::bind(&Client::handleConnectorFinished, this, _1)); + connector_->setTimeoutMilliseconds(60*1000); connector_->start(); } diff --git a/Swiften/Elements/MUCPayload.h b/Swiften/Elements/MUCPayload.h index 205ae46..97932a1 100644 --- a/Swiften/Elements/MUCPayload.h +++ b/Swiften/Elements/MUCPayload.h @@ -1,16 +1,11 @@ -#ifndef SWIFTEN_MUCPayload_H -#define SWIFTEN_MUCPayload_H +#pragma once -#include "Swiften/Base/String.h" #include "Swiften/Elements/Payload.h" namespace Swift { - class MUCPayload : public Payload - { + class MUCPayload : public Payload { public: - MUCPayload() { } - + MUCPayload() { + } }; } - -#endif diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp index 9ea5a7f..d372bf2 100644 --- a/Swiften/Network/Connector.cpp +++ b/Swiften/Network/Connector.cpp @@ -6,10 +6,11 @@ #include "Swiften/Network/ConnectionFactory.h" #include "Swiften/Network/DomainNameResolver.h" #include "Swiften/Network/DomainNameAddressQuery.h" +#include "Swiften/Network/TimerFactory.h" namespace Swift { -Connector::Connector(const String& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), queriedAllHosts(true) { +Connector::Connector(const String& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllHosts(true) { } void Connector::setTimeoutMilliseconds(int milliseconds) { @@ -20,9 +21,15 @@ void Connector::start() { //std::cout << "Connector::start()" << std::endl; assert(!currentConnection); assert(!serviceQuery); + assert(!timer); queriedAllHosts = false; serviceQuery = resolver->createServiceQuery("_xmpp-client._tcp." + hostname); serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, this, _1)); + if (timeoutMilliseconds > 0) { + timer = timerFactory->createTimer(timeoutMilliseconds); + timer->onTick.connect(boost::bind(&Connector::handleTimeout, this)); + timer->start(); + } serviceQuery->run(); } @@ -43,7 +50,7 @@ void Connector::handleServiceQueryResult(const std::vector<DomainNameServiceQuer void Connector::tryNextHostname() { if (queriedAllHosts) { //std::cout << "Connector::tryNextHostName(): Queried all hosts. Error." << std::endl; - onConnectFinished(boost::shared_ptr<Connection>()); + finish(boost::shared_ptr<Connection>()); } else if (serviceQueryResults.empty()) { //std::cout << "Connector::tryNextHostName(): Falling back on A resolution" << std::endl; @@ -76,7 +83,7 @@ void Connector::handleAddressQueryResult(const HostAddress& address, boost::opti //std::cout << "Connector::handleAddressQueryResult(): Fallback address query failed. Giving up" << std::endl; // The fallback address query failed assert(queriedAllHosts); - onConnectFinished(boost::shared_ptr<Connection>()); + finish(boost::shared_ptr<Connection>()); } else { //std::cout << "Connector::handleAddressQueryResult(): Fallback address query succeeded: " << address.toString() << std::endl; @@ -100,8 +107,20 @@ void Connector::handleConnectionConnectFinished(bool error) { tryNextHostname(); } else { - onConnectFinished(currentConnection); + finish(currentConnection); + } +} + +void Connector::finish(boost::shared_ptr<Connection> connection) { + if (timer) { + timer->stop(); + timer.reset(); } + onConnectFinished(connection); +} + +void Connector::handleTimeout() { + finish(boost::shared_ptr<Connection>()); } }; diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h index 6df3970..507f085 100644 --- a/Swiften/Network/Connector.h +++ b/Swiften/Network/Connector.h @@ -6,6 +6,7 @@ #include "Swiften/Network/DomainNameServiceQuery.h" #include "Swiften/Network/Connection.h" +#include "Swiften/Network/Timer.h" #include "Swiften/Network/HostAddressPort.h" #include "Swiften/Base/String.h" #include "Swiften/Network/DomainNameResolveError.h" @@ -14,10 +15,11 @@ namespace Swift { class DomainNameAddressQuery; class DomainNameResolver; class ConnectionFactory; + class TimerFactory; class Connector : public boost::bsignals::trackable { public: - Connector(const String& hostname, DomainNameResolver*, ConnectionFactory*); + Connector(const String& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*); void setTimeoutMilliseconds(int milliseconds); void start(); @@ -33,12 +35,16 @@ namespace Swift { void tryConnect(const HostAddressPort& target); void handleConnectionConnectFinished(bool error); + void finish(boost::shared_ptr<Connection>); + void handleTimeout(); private: String hostname; DomainNameResolver* resolver; ConnectionFactory* connectionFactory; + TimerFactory* timerFactory; int timeoutMilliseconds; + boost::shared_ptr<Timer> timer; boost::shared_ptr<DomainNameServiceQuery> serviceQuery; std::deque<DomainNameServiceQuery::Result> serviceQueryResults; boost::shared_ptr<DomainNameAddressQuery> addressQuery; diff --git a/Swiften/Network/DummyTimerFactory.cpp b/Swiften/Network/DummyTimerFactory.cpp index 72523bb..7626584 100644 --- a/Swiften/Network/DummyTimerFactory.cpp +++ b/Swiften/Network/DummyTimerFactory.cpp @@ -2,8 +2,8 @@ #include <algorithm> -#include "Swiften/Network/Timer.h" #include "Swiften/Base/foreach.h" +#include "Swiften/Network/Timer.h" namespace Swift { @@ -40,7 +40,7 @@ static bool hasZeroTimeout(boost::shared_ptr<DummyTimerFactory::DummyTimer> time void DummyTimerFactory::setTime(int time) { assert(time > currentTime); - int increment = currentTime - time; + int increment = time - currentTime; std::vector< boost::shared_ptr<DummyTimer> > notifyTimers(timers.begin(), timers.end()); foreach(boost::shared_ptr<DummyTimer> timer, notifyTimers) { if (increment >= timer->timeout) { @@ -49,6 +49,9 @@ void DummyTimerFactory::setTime(int time) { } timer->timeout = 0; } + else { + timer->timeout -= increment; + } } timers.erase(std::remove_if(timers.begin(), timers.end(), hasZeroTimeout), timers.end()); currentTime = time; diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp index 08b9bc1..663011c 100644 --- a/Swiften/Network/UnitTest/ConnectorTest.cpp +++ b/Swiften/Network/UnitTest/ConnectorTest.cpp @@ -24,9 +24,9 @@ class ConnectorTest : public CppUnit::TestFixture { CPPUNIT_TEST(testConnect_AllSRVHostsFailWithoutFallbackHost); CPPUNIT_TEST(testConnect_AllSRVHostsFailWithFallbackHost); CPPUNIT_TEST(testConnect_SRVAndFallbackHostsFail); - //CPPUNIT_TEST(testConnect_TimeoutDuringResolve); - //CPPUNIT_TEST(testConnect_TimeoutDuringConnect); - //CPPUNIT_TEST(testConnect_NoTimeout); + CPPUNIT_TEST(testConnect_TimeoutDuringResolve); + CPPUNIT_TEST(testConnect_TimeoutDuringConnect); + CPPUNIT_TEST(testConnect_NoTimeout); CPPUNIT_TEST_SUITE_END(); public: @@ -186,7 +186,7 @@ class ConnectorTest : public CppUnit::TestFixture { private: Connector* createConnector() { - Connector* connector = new Connector("foo.com", resolver, connectionFactory); + Connector* connector = new Connector("foo.com", resolver, connectionFactory, timerFactory); connector->onConnectFinished.connect(boost::bind(&ConnectorTest::handleConnectorFinished, this, _1)); return connector; } -- cgit v0.10.2-6-g49f6