diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-07-19 11:44:20 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-07-19 11:59:04 (GMT) |
commit | 1de12ed346fc0018527afe082886129088e27a95 (patch) | |
tree | 16013a9294588f505a559a99fe27a603584f2ac2 | |
parent | 5d504472c63b7acaa7df99ff1097024cf463f1bd (diff) | |
download | swift-1de12ed346fc0018527afe082886129088e27a95.zip swift-1de12ed346fc0018527afe082886129088e27a95.tar.bz2 |
(Client)Session & Connection refactoring.
ClientSession no longer sets up a connection.
Connection no longer resolves addresses.
-rw-r--r-- | Swiften/Client/Client.cpp | 48 | ||||
-rw-r--r-- | Swiften/Client/Client.h | 2 | ||||
-rw-r--r-- | Swiften/Client/Session.cpp | 46 | ||||
-rw-r--r-- | Swiften/Client/Session.h | 13 | ||||
-rw-r--r-- | Swiften/Client/UnitTest/SessionTest.cpp | 139 | ||||
-rw-r--r-- | Swiften/LinkLocal/OutgoingLinkLocalSession.cpp | 15 | ||||
-rw-r--r-- | Swiften/LinkLocal/OutgoingLinkLocalSession.h | 2 | ||||
-rw-r--r-- | Swiften/Network/BoostConnection.cpp | 14 | ||||
-rw-r--r-- | Swiften/Network/BoostConnection.h | 1 | ||||
-rw-r--r-- | Swiften/Network/Connection.h | 5 | ||||
-rw-r--r-- | Swiften/QA/NetworkTest/BoostConnectionTest.cpp | 9 |
11 files changed, 119 insertions, 175 deletions
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index d87673b..04a24bf 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -2,9 +2,11 @@ #include <boost/bind.hpp> +#include "Swiften/Network/DomainNameResolver.h" #include "Swiften/Client/Session.h" #include "Swiften/StreamStack/PlatformTLSLayerFactory.h" #include "Swiften/Network/BoostConnectionFactory.h" +#include "Swiften/Network/DomainNameResolveException.h" #include "Swiften/TLS/PKCS12Certificate.h" namespace Swift { @@ -23,17 +25,37 @@ Client::~Client() { void Client::connect() { delete session_; - session_ = new Session(jid_, connectionFactory_, tlsLayerFactory_, &payloadParserFactories_, &payloadSerializers_); - if (!certificate_.isEmpty()) { - session_->setCertificate(PKCS12Certificate(certificate_, password_)); + session_ = 0; + + DomainNameResolver resolver; + try { + HostAddressPort remote = resolver.resolve(jid_.getDomain().getUTF8String()); + connection_ = connectionFactory_->createConnection(); + connection_->onConnectFinished.connect(boost::bind(&Client::handleConnectionConnectFinished, this, _1)); + connection_->connect(remote); + } + catch (const DomainNameResolveException& e) { + onError(ClientError::DomainNameResolveError); + } +} + +void Client::handleConnectionConnectFinished(bool error) { + if (error) { + onError(ClientError::ConnectionError); + } + else { + session_ = new Session(jid_, connection_, tlsLayerFactory_, &payloadParserFactories_, &payloadSerializers_); + if (!certificate_.isEmpty()) { + session_->setCertificate(PKCS12Certificate(certificate_, password_)); + } + session_->onSessionStarted.connect(boost::bind(boost::ref(onConnected))); + session_->onError.connect(boost::bind(&Client::handleSessionError, this, _1)); + session_->onNeedCredentials.connect(boost::bind(&Client::handleNeedCredentials, this)); + session_->onDataRead.connect(boost::bind(&Client::handleDataRead, this, _1)); + session_->onDataWritten.connect(boost::bind(&Client::handleDataWritten, this, _1)); + session_->onElementReceived.connect(boost::bind(&Client::handleElement, this, _1)); + session_->start(); } - session_->onSessionStarted.connect(boost::bind(boost::ref(onConnected))); - session_->onError.connect(boost::bind(&Client::handleSessionError, this, _1)); - session_->onNeedCredentials.connect(boost::bind(&Client::handleNeedCredentials, this)); - session_->onDataRead.connect(boost::bind(&Client::handleDataRead, this, _1)); - session_->onDataWritten.connect(boost::bind(&Client::handleDataWritten, this, _1)); - session_->onElementReceived.connect(boost::bind(&Client::handleElement, this, _1)); - session_->start(); } void Client::disconnect() { @@ -92,12 +114,6 @@ void Client::handleSessionError(Session::SessionError error) { case Session::NoError: assert(false); break; - case Session::DomainNameResolveError: - clientError = ClientError(ClientError::DomainNameResolveError); - break; - case Session::ConnectionError: - clientError = ClientError(ClientError::ConnectionError); - break; case Session::ConnectionReadError: clientError = ClientError(ClientError::ConnectionReadError); break; diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index d876302..66f9b01 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -43,6 +43,7 @@ namespace Swift { boost::signal<void (const String&)> onDataWritten; private: + void handleConnectionConnectFinished(bool error); void send(boost::shared_ptr<Stanza>); virtual String getNewIQID(); void handleElement(boost::shared_ptr<Element>); @@ -61,6 +62,7 @@ namespace Swift { FullPayloadParserFactoryCollection payloadParserFactories_; FullPayloadSerializerCollection payloadSerializers_; Session* session_; + boost::shared_ptr<Connection> connection_; String certificate_; }; } diff --git a/Swiften/Client/Session.cpp b/Swiften/Client/Session.cpp index 6c2a873..1bd2b22 100644 --- a/Swiften/Client/Session.cpp +++ b/Swiften/Client/Session.cpp @@ -24,16 +24,21 @@ namespace Swift { -Session::Session(const JID& jid, ConnectionFactory* connectionFactory, TLSLayerFactory* tlsLayerFactory, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers) : - jid_(jid), - connectionFactory_(connectionFactory), - tlsLayerFactory_(tlsLayerFactory), - payloadParserFactories_(payloadParserFactories), - payloadSerializers_(payloadSerializers), - state_(Initial), - error_(NoError), - streamStack_(0), - needSessionStart_(false) { +Session::Session( + const JID& jid, + boost::shared_ptr<Connection> connection, + TLSLayerFactory* tlsLayerFactory, + PayloadParserFactoryCollection* payloadParserFactories, + PayloadSerializerCollection* payloadSerializers) : + jid_(jid), + tlsLayerFactory_(tlsLayerFactory), + payloadParserFactories_(payloadParserFactories), + payloadSerializers_(payloadSerializers), + state_(Initial), + error_(NoError), + connection_(connection), + streamStack_(0), + needSessionStart_(false) { } Session::~Session() { @@ -42,11 +47,11 @@ Session::~Session() { void Session::start() { assert(state_ == Initial); - state_ = Connecting; - connection_ = connectionFactory_->createConnection(); - connection_->onConnected.connect(boost::bind(&Session::handleConnected, this)); + connection_->onDisconnected.connect(boost::bind(&Session::handleDisconnected, this, _1)); - connection_->connect(jid_.getDomain()); + initializeStreamStack(); + state_ = WaitingForStreamStart; + sendStreamHeader(); } void Session::stop() { @@ -54,13 +59,6 @@ void Session::stop() { connection_->disconnect(); } -void Session::handleConnected() { - assert(state_ == Connecting); - initializeStreamStack(); - state_ = WaitingForStreamStart; - sendStreamHeader(); -} - void Session::sendStreamHeader() { ProtocolHeader header; header.setTo(jid_.getDomain()); @@ -81,18 +79,12 @@ void Session::initializeStreamStack() { void Session::handleDisconnected(const boost::optional<Connection::Error>& error) { if (error) { switch (*error) { - case Connection::DomainNameResolveError: - setError(DomainNameResolveError); - break; case Connection::ReadError: setError(ConnectionReadError); break; case Connection::WriteError: setError(ConnectionWriteError); break; - case Connection::ConnectionError: - setError(ConnectionError); - break; } } } diff --git a/Swiften/Client/Session.h b/Swiften/Client/Session.h index 17c10b9..58531b3 100644 --- a/Swiften/Client/Session.h +++ b/Swiften/Client/Session.h @@ -26,7 +26,6 @@ namespace Swift { public: enum State { Initial, - Connecting, WaitingForStreamStart, Negotiating, Compressing, @@ -40,8 +39,6 @@ namespace Swift { }; enum SessionError { NoError, - DomainNameResolveError, - ConnectionError, ConnectionReadError, ConnectionWriteError, XMLError, @@ -55,7 +52,12 @@ namespace Swift { ClientCertificateError }; - Session(const JID& jid, ConnectionFactory*, TLSLayerFactory*, PayloadParserFactoryCollection*, PayloadSerializerCollection*); + Session( + const JID& jid, + boost::shared_ptr<Connection>, + TLSLayerFactory*, + PayloadParserFactoryCollection*, + PayloadSerializerCollection*); ~Session(); State getState() const { @@ -72,6 +74,7 @@ namespace Swift { void start(); void stop(); + void sendCredentials(const String& password); void sendElement(boost::shared_ptr<Element>); void setCertificate(const PKCS12Certificate& certificate); @@ -86,7 +89,6 @@ namespace Swift { void sendStreamHeader(); void sendSessionStart(); - void handleConnected(); void handleDisconnected(const boost::optional<Connection::Error>&); void handleElement(boost::shared_ptr<Element>); void handleStreamStart(); @@ -106,7 +108,6 @@ namespace Swift { private: JID jid_; - ConnectionFactory* connectionFactory_; TLSLayerFactory* tlsLayerFactory_; PayloadParserFactoryCollection* payloadParserFactories_; PayloadSerializerCollection* payloadSerializers_; diff --git a/Swiften/Client/UnitTest/SessionTest.cpp b/Swiften/Client/UnitTest/SessionTest.cpp index a11ddde..eb7281c 100644 --- a/Swiften/Client/UnitTest/SessionTest.cpp +++ b/Swiften/Client/UnitTest/SessionTest.cpp @@ -39,10 +39,8 @@ using namespace Swift; class SessionTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(SessionTest); CPPUNIT_TEST(testConstructor); - CPPUNIT_TEST(testConnect); - CPPUNIT_TEST(testConnect_Error); - CPPUNIT_TEST(testConnect_ErrorAfterSuccesfulConnect); - CPPUNIT_TEST(testConnect_XMLError); + CPPUNIT_TEST(testStart_Error); + CPPUNIT_TEST(testStart_XMLError); CPPUNIT_TEST(testStartTLS); CPPUNIT_TEST(testStartTLS_ServerError); CPPUNIT_TEST(testStartTLS_NoTLSSupport); @@ -68,7 +66,7 @@ class SessionTest : public CppUnit::TestFixture { void setUp() { eventLoop_ = new DummyEventLoop(); - connectionFactory_ = new MockConnectionFactory(); + connection_ = boost::shared_ptr<MockConnection>(new MockConnection()); tlsLayerFactory_ = new MockTLSLayerFactory(); sessionStarted_ = false; needCredentials_ = false; @@ -76,7 +74,6 @@ class SessionTest : public CppUnit::TestFixture { void tearDown() { delete tlsLayerFactory_; - delete connectionFactory_; delete eventLoop_; } @@ -85,51 +82,26 @@ class SessionTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(Session::Initial, session->getState()); } - void testConnect() { + void testStart_Error() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - CPPUNIT_ASSERT_EQUAL(Session::Connecting, session->getState()); - getMockServer()->expectStreamStart(); - - processEvents(); - CPPUNIT_ASSERT_EQUAL(Session::WaitingForStreamStart, session->getState()); - } - - void testConnect_Error() { - std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->onSessionStarted.connect(boost::bind(&SessionTest::setSessionStarted, this)); - - connectionFactory_->setCreateFailingConnections(); session->start(); processEvents(); - - CPPUNIT_ASSERT_EQUAL(Session::Error, session->getState()); - CPPUNIT_ASSERT(!sessionStarted_); - CPPUNIT_ASSERT_EQUAL(Session::ConnectionError, session->getError()); - } - - void testConnect_ErrorAfterSuccesfulConnect() { - std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - - session->start(); - getMockServer()->expectStreamStart(); - processEvents(); CPPUNIT_ASSERT_EQUAL(Session::WaitingForStreamStart, session->getState()); - connectionFactory_->connections_[0]->setError(); + getMockServer()->setError(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::Error, session->getState()); - CPPUNIT_ASSERT_EQUAL(Session::ConnectionError, session->getError()); + CPPUNIT_ASSERT_EQUAL(Session::ConnectionReadError, session->getError()); } - void testConnect_XMLError() { + void testStart_XMLError() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); getMockServer()->expectStreamStart(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::WaitingForStreamStart, session->getState()); @@ -143,25 +115,23 @@ class SessionTest : public CppUnit::TestFixture { void testStartTLS_NoTLSSupport() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); tlsLayerFactory_->setTLSSupported(false); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithStartTLS(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::SessionStarted, session->getState()); } void testStartTLS() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithStartTLS(); getMockServer()->expectStartTLS(); // FIXME: Test 'encrypting' state getMockServer()->sendTLSProceed(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::Encrypting, session->getState()); CPPUNIT_ASSERT(session->getTLSLayer()); @@ -178,13 +148,12 @@ class SessionTest : public CppUnit::TestFixture { void testStartTLS_ServerError() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithStartTLS(); getMockServer()->expectStartTLS(); getMockServer()->sendTLSFailure(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::Error, session->getState()); @@ -193,13 +162,12 @@ class SessionTest : public CppUnit::TestFixture { void testStartTLS_ConnectError() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithStartTLS(); getMockServer()->expectStartTLS(); getMockServer()->sendTLSProceed(); + session->start(); processEvents(); session->getTLSLayer()->setError(); @@ -209,13 +177,12 @@ class SessionTest : public CppUnit::TestFixture { void testStartTLS_ErrorAfterConnect() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithStartTLS(); getMockServer()->expectStartTLS(); getMockServer()->sendTLSProceed(); + session->start(); processEvents(); getMockServer()->resetParser(); getMockServer()->expectStreamStart(); @@ -232,11 +199,10 @@ class SessionTest : public CppUnit::TestFixture { void testAuthenticate() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); session->onNeedCredentials.connect(boost::bind(&SessionTest::setNeedCredentials, this)); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithAuthentication(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::WaitingForCredentials, session->getState()); CPPUNIT_ASSERT(needCredentials_); @@ -253,10 +219,10 @@ class SessionTest : public CppUnit::TestFixture { void testAuthenticate_Unauthorized() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithAuthentication(); + session->start(); processEvents(); getMockServer()->expectAuth("me", "mypass"); @@ -270,10 +236,10 @@ class SessionTest : public CppUnit::TestFixture { void testAuthenticate_NoValidAuthMechanisms() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithUnsupportedAuthentication(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::Error, session->getState()); @@ -282,14 +248,14 @@ class SessionTest : public CppUnit::TestFixture { void testResourceBind() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithResourceBind(); getMockServer()->expectResourceBind("Bar", "session-bind"); // FIXME: Check CPPUNIT_ASSERT_EQUAL(Session::BindingResource, session->getState()); getMockServer()->sendResourceBindResponse("me@foo.com/Bar", "session-bind"); + session->start(); + processEvents(); CPPUNIT_ASSERT_EQUAL(Session::SessionStarted, session->getState()); @@ -298,13 +264,12 @@ class SessionTest : public CppUnit::TestFixture { void testResourceBind_ChangeResource() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithResourceBind(); getMockServer()->expectResourceBind("Bar", "session-bind"); getMockServer()->sendResourceBindResponse("me@foo.com/Bar123", "session-bind"); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::SessionStarted, session->getState()); @@ -313,13 +278,12 @@ class SessionTest : public CppUnit::TestFixture { void testResourceBind_EmptyResource() { std::auto_ptr<MockSession> session(createSession("me@foo.com")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithResourceBind(); getMockServer()->expectResourceBind("", "session-bind"); getMockServer()->sendResourceBindResponse("me@foo.com/NewResource", "session-bind"); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::SessionStarted, session->getState()); @@ -328,13 +292,12 @@ class SessionTest : public CppUnit::TestFixture { void testResourceBind_Error() { std::auto_ptr<MockSession> session(createSession("me@foo.com")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithResourceBind(); getMockServer()->expectResourceBind("", "session-bind"); getMockServer()->sendError("session-bind"); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::Error, session->getState()); @@ -344,14 +307,13 @@ class SessionTest : public CppUnit::TestFixture { void testSessionStart() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); session->onSessionStarted.connect(boost::bind(&SessionTest::setSessionStarted, this)); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithSession(); getMockServer()->expectSessionStart("session-start"); // FIXME: Check CPPUNIT_ASSERT_EQUAL(Session::StartingSession, session->getState()); getMockServer()->sendSessionStartResponse("session-start"); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::SessionStarted, session->getState()); @@ -360,13 +322,12 @@ class SessionTest : public CppUnit::TestFixture { void testSessionStart_Error() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); - getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithSession(); getMockServer()->expectSessionStart("session-start"); getMockServer()->sendError("session-start"); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::Error, session->getState()); @@ -376,7 +337,6 @@ class SessionTest : public CppUnit::TestFixture { void testSessionStart_AfterResourceBind() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); session->onSessionStarted.connect(boost::bind(&SessionTest::setSessionStarted, this)); - session->start(); getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeaturesWithResourceBindAndSession(); @@ -384,6 +344,7 @@ class SessionTest : public CppUnit::TestFixture { getMockServer()->sendResourceBindResponse("me@foo.com/Bar", "session-bind"); getMockServer()->expectSessionStart("session-start"); getMockServer()->sendSessionStartResponse("session-start"); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(Session::SessionStarted, session->getState()); @@ -392,20 +353,20 @@ class SessionTest : public CppUnit::TestFixture { void testWhitespacePing() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeatures(); + session->start(); processEvents(); CPPUNIT_ASSERT(session->getWhitespacePingLayer()); } void testReceiveElementAfterSessionStarted() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); - session->start(); getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeatures(); + session->start(); processEvents(); getMockServer()->expectMessage(); @@ -415,11 +376,11 @@ class SessionTest : public CppUnit::TestFixture { void testSendElement() { std::auto_ptr<MockSession> session(createSession("me@foo.com/Bar")); session->onElementReceived.connect(boost::bind(&SessionTest::addReceivedElement, this, _1)); - session->start(); getMockServer()->expectStreamStart(); getMockServer()->sendStreamStart(); getMockServer()->sendStreamFeatures(); getMockServer()->sendMessage(); + session->start(); processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(receivedElements_.size())); @@ -430,8 +391,7 @@ class SessionTest : public CppUnit::TestFixture { struct MockConnection; boost::shared_ptr<MockConnection> getMockServer() const { - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connectionFactory_->connections_.size())); - return connectionFactory_->connections_[0]; + return connection_; } void processEvents() { @@ -468,9 +428,9 @@ class SessionTest : public CppUnit::TestFixture { boost::shared_ptr<Element> element; }; - MockConnection(bool fail) : - fail_(fail), + MockConnection() : resetParser_(false), + domain_("foo.com"), parser_(0), serializer_(&payloadSerializers_) { parser_ = new XMPPParser(this, &payloadParserFactories_); @@ -480,26 +440,17 @@ class SessionTest : public CppUnit::TestFixture { delete parser_; } - void disconnect() { - } + void disconnect() { } void listen() { assert(false); } void connect(const HostAddressPort&) { assert(false); } - void connect(const String& domain) { - if (fail_) { - MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), Connection::ConnectionError)); - } - else { - domain_ = domain; - MainEventLoop::postEvent(boost::bind(boost::ref(onConnected))); - } - } + void connect(const String&) { assert(false); } void setError() { - MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), Connection::ConnectionError)); + MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), Connection::ReadError)); } void write(const ByteArray& data) { @@ -565,6 +516,9 @@ class SessionTest : public CppUnit::TestFixture { } void assertNoMoreExpectations() { + foreach (const Event& event, events_) { + std::cout << "Unprocessed event: " << serializeEvent(event) << std::endl; + } CPPUNIT_ASSERT(events_.empty()); } @@ -683,7 +637,6 @@ class SessionTest : public CppUnit::TestFixture { events_.push_back(Event(Event::Out, Event::ElementEvent, IQ::createResult(JID(), id, boost::shared_ptr<StartSession>(new StartSession())))); } - bool fail_; bool resetParser_; String domain_; FullPayloadParserFactoryCollection payloadParserFactories_; @@ -693,20 +646,6 @@ class SessionTest : public CppUnit::TestFixture { std::deque<Event> events_; }; - struct MockConnectionFactory : public ConnectionFactory { - MockConnectionFactory() : fail_(false) {} - boost::shared_ptr<Connection> createConnection() { - boost::shared_ptr<MockConnection> result(new MockConnection(fail_)); - connections_.push_back(result); - return result; - } - void setCreateFailingConnections() { - fail_ = true; - } - std::vector<boost::shared_ptr<MockConnection> > connections_; - bool fail_; - }; - struct MockTLSLayer : public TLSLayer { MockTLSLayer() : connecting_(false) {} bool setClientCertificate(const PKCS12Certificate&) { return true; } @@ -735,7 +674,7 @@ class SessionTest : public CppUnit::TestFixture { }; struct MockSession : public Session { - MockSession(const JID& jid, ConnectionFactory* connectionFactory, TLSLayerFactory* tlsLayerFactory, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers) : Session(jid, connectionFactory, tlsLayerFactory, payloadParserFactories, payloadSerializers) {} + MockSession(const JID& jid, boost::shared_ptr<Connection> connection, TLSLayerFactory* tlsLayerFactory, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers) : Session(jid, connection, tlsLayerFactory, payloadParserFactories, payloadSerializers) {} boost::shared_ptr<MockTLSLayer> getTLSLayer() const { return getStreamStack()->getLayer<MockTLSLayer>(); @@ -746,12 +685,12 @@ class SessionTest : public CppUnit::TestFixture { }; MockSession* createSession(const String& jid) { - return new MockSession(JID(jid), connectionFactory_, tlsLayerFactory_, &payloadParserFactories_, &payloadSerializers_); + return new MockSession(JID(jid), connection_, tlsLayerFactory_, &payloadParserFactories_, &payloadSerializers_); } DummyEventLoop* eventLoop_; - MockConnectionFactory* connectionFactory_; + boost::shared_ptr<MockConnection> connection_; MockTLSLayerFactory* tlsLayerFactory_; FullPayloadParserFactoryCollection payloadParserFactories_; FullPayloadSerializerCollection payloadSerializers_; diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp index f32bcdd..f97520a 100644 --- a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp +++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp @@ -55,7 +55,7 @@ void OutgoingLinkLocalSession::handleHostnameResolved(const String& hostname, co boost::shared_ptr<Connection> connection = connectionFactory_->createConnection(); setConnection(connection); initializeStreamStack(); - connection->onConnected.connect(boost::bind(&OutgoingLinkLocalSession::handleConnected, boost::dynamic_pointer_cast<OutgoingLinkLocalSession>(shared_from_this()))); + connection->onConnectFinished.connect(boost::bind(&OutgoingLinkLocalSession::handleConnected, boost::dynamic_pointer_cast<OutgoingLinkLocalSession>(shared_from_this()), _1)); connection->connect(HostAddressPort(*address, port_)); } else { @@ -65,10 +65,15 @@ void OutgoingLinkLocalSession::handleHostnameResolved(const String& hostname, co } } -void OutgoingLinkLocalSession::handleConnected() { - ProtocolHeader header; - header.setFrom(getLocalJID()); - getXMPPLayer()->writeHeader(header); +void OutgoingLinkLocalSession::handleConnected(bool error) { + if (!error) { + ProtocolHeader header; + header.setFrom(getLocalJID()); + getXMPPLayer()->writeHeader(header); + } + else { + // TODO: Error + } } void OutgoingLinkLocalSession::handleStreamStart(const ProtocolHeader&) { diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.h b/Swiften/LinkLocal/OutgoingLinkLocalSession.h index abbec80..76ab803 100644 --- a/Swiften/LinkLocal/OutgoingLinkLocalSession.h +++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.h @@ -41,7 +41,7 @@ namespace Swift { void handleElement(boost::shared_ptr<Element>); void handleStreamStart(const ProtocolHeader&); void handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address); - void handleConnected(); + void handleConnected(bool error); private: bool resolving_; diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp index b064c7a..9f2a7da 100644 --- a/Swiften/Network/BoostConnection.cpp +++ b/Swiften/Network/BoostConnection.cpp @@ -48,16 +48,6 @@ void BoostConnection::listen() { doRead(); } -void BoostConnection::connect(const String& domain) { - DomainNameResolver resolver; - try { - connect(resolver.resolve(domain.getUTF8String())); - } - catch (const DomainNameResolveException& e) { - onDisconnected(DomainNameResolveError); - } -} - void BoostConnection::connect(const HostAddressPort& addressPort) { boost::asio::ip::tcp::endpoint endpoint( boost::asio::ip::address::from_string(addressPort.getAddress().toString()), addressPort.getPort()); @@ -78,11 +68,11 @@ void BoostConnection::write(const ByteArray& data) { void BoostConnection::handleConnectFinished(const boost::system::error_code& error) { if (!error) { - MainEventLoop::postEvent(boost::bind(boost::ref(onConnected)), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onConnectFinished), false), shared_from_this()); doRead(); } else if (error != boost::asio::error::operation_aborted) { - MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), ConnectionError), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onConnectFinished), true), shared_from_this()); } } diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h index 0ed6874..ae09fb8 100644 --- a/Swiften/Network/BoostConnection.h +++ b/Swiften/Network/BoostConnection.h @@ -20,7 +20,6 @@ namespace Swift { ~BoostConnection(); virtual void listen(); - virtual void connect(const String& domain); virtual void connect(const HostAddressPort& address); virtual void disconnect(); virtual void write(const ByteArray& data); diff --git a/Swiften/Network/Connection.h b/Swiften/Network/Connection.h index 25f9a16..a995774 100644 --- a/Swiften/Network/Connection.h +++ b/Swiften/Network/Connection.h @@ -11,8 +11,6 @@ namespace Swift { class Connection { public: enum Error { - DomainNameResolveError, - ConnectionError, ReadError, WriteError }; @@ -22,12 +20,11 @@ namespace Swift { virtual void listen() = 0; virtual void connect(const HostAddressPort& address) = 0; - virtual void connect(const String& domain) = 0; virtual void disconnect() = 0; virtual void write(const ByteArray& data) = 0; public: - boost::signal<void ()> onConnected; + boost::signal<void (bool /* error */)> onConnectFinished; boost::signal<void (const boost::optional<Error>&)> onDisconnected; boost::signal<void (const ByteArray&)> onDataRead; }; diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp index e38b895..9929eaa 100644 --- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp +++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp @@ -5,9 +5,13 @@ #include "Swiften/Base/String.h" #include "Swiften/Base/sleep.h" #include "Swiften/Network/BoostConnection.h" +#include "Swiften/Network/HostAddress.h" +#include "Swiften/Network/HostAddressPort.h" #include "Swiften/Network/BoostIOServiceThread.h" #include "Swiften/EventLoop/DummyEventLoop.h" +const unsigned char* address = reinterpret_cast<const unsigned char*>("\x41\x63\xde\x89"); + using namespace Swift; class BoostConnectionTest : public CppUnit::TestFixture { @@ -31,16 +35,15 @@ class BoostConnectionTest : public CppUnit::TestFixture { void testDestructor() { { - std::string domain("el-tramo.be"); boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService())); - testling->connect(domain); + testling->connect(HostAddressPort(HostAddress(address, 4), 5222)); } } void testDestructor_PendingEvents() { { boost::shared_ptr<BoostConnection> testling(new BoostConnection(&boostIOServiceThread_->getIOService())); - testling->connect("el-tramo.be"); + testling->connect(HostAddressPort(HostAddress(address, 4), 5222)); while (!eventLoop_->hasEvents()) { Swift::sleep(10); } |