diff options
Diffstat (limited to 'Swiften/Session/BasicSessionStream.cpp')
-rw-r--r-- | Swiften/Session/BasicSessionStream.cpp | 238 |
1 files changed, 122 insertions, 116 deletions
diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp index 2bd8d66..c44961d 100644 --- a/Swiften/Session/BasicSessionStream.cpp +++ b/Swiften/Session/BasicSessionStream.cpp @@ -1,210 +1,216 @@ /* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. + * Copyright (c) 2010-2018 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. */ #include <Swiften/Session/BasicSessionStream.h> +#include <memory> + #include <boost/bind.hpp> -#include <boost/smart_ptr/make_shared.hpp> -#include <Swiften/StreamStack/XMPPLayer.h> -#include <Swiften/StreamStack/StreamStack.h> -#include <Swiften/StreamStack/ConnectionLayer.h> -#include <Swiften/StreamStack/WhitespacePingLayer.h> #include <Swiften/StreamStack/CompressionLayer.h> +#include <Swiften/StreamStack/ConnectionLayer.h> +#include <Swiften/StreamStack/StreamStack.h> #include <Swiften/StreamStack/TLSLayer.h> -#include <Swiften/TLS/TLSContextFactory.h> +#include <Swiften/StreamStack/WhitespacePingLayer.h> +#include <Swiften/StreamStack/XMPPLayer.h> #include <Swiften/TLS/TLSContext.h> +#include <Swiften/TLS/TLSContextFactory.h> namespace Swift { BasicSessionStream::BasicSessionStream( - StreamType streamType, - boost::shared_ptr<Connection> connection, - PayloadParserFactoryCollection* payloadParserFactories, - PayloadSerializerCollection* payloadSerializers, - TLSContextFactory* tlsContextFactory, - TimerFactory* timerFactory, - XMLParserFactory* xmlParserFactory) : - available(false), - connection(connection), - tlsContextFactory(tlsContextFactory), - timerFactory(timerFactory), - compressionLayer(NULL), - tlsLayer(NULL), - whitespacePingLayer(NULL) { - xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, xmlParserFactory, streamType); - xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); - xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); - xmppLayer->onError.connect(boost::bind(&BasicSessionStream::handleXMPPError, this)); - xmppLayer->onDataRead.connect(boost::bind(&BasicSessionStream::handleDataRead, this, _1)); - xmppLayer->onWriteData.connect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1)); - - connection->onDisconnected.connect(boost::bind(&BasicSessionStream::handleConnectionFinished, this, _1)); - connectionLayer = new ConnectionLayer(connection); - - streamStack = new StreamStack(xmppLayer, connectionLayer); - - available = true; + StreamType streamType, + std::shared_ptr<Connection> connection, + PayloadParserFactoryCollection* payloadParserFactories, + PayloadSerializerCollection* payloadSerializers, + TLSContextFactory* tlsContextFactory, + TimerFactory* timerFactory, + XMLParserFactory* xmlParserFactory, + const TLSOptions& tlsOptions) : + available(false), + connection(connection), + tlsContextFactory(tlsContextFactory), + timerFactory(timerFactory), + tlsOptions_(tlsOptions) { + auto xmppLayer = std::make_unique<XMPPLayer>(payloadParserFactories, payloadSerializers, xmlParserFactory, streamType); + xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); + xmppLayer->onStreamEnd.connect(boost::bind(&BasicSessionStream::handleStreamEndReceived, this)); + xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); + xmppLayer->onError.connect(boost::bind(&BasicSessionStream::handleXMPPError, this)); + xmppLayer->onDataRead.connect(boost::bind(&BasicSessionStream::handleDataRead, this, _1)); + xmppLayer->onWriteData.connect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1)); + + connection->onDisconnected.connect(boost::bind(&BasicSessionStream::handleConnectionFinished, this, _1)); + + streamStack = std::make_unique<StreamStack>(std::move(xmppLayer), std::unique_ptr<ConnectionLayer>(new ConnectionLayer(connection))); + available = true; } BasicSessionStream::~BasicSessionStream() { - delete compressionLayer; - if (tlsLayer) { - tlsLayer->onError.disconnect(boost::bind(&BasicSessionStream::handleTLSError, this)); - tlsLayer->onConnected.disconnect(boost::bind(&BasicSessionStream::handleTLSConnected, this)); - delete tlsLayer; - } - delete whitespacePingLayer; - delete streamStack; + if (auto tlsLayer = streamStack->getLayer<TLSLayer>()) { + tlsLayer->onError.disconnect(boost::bind(&BasicSessionStream::handleTLSError, this, _1)); + tlsLayer->onConnected.disconnect(boost::bind(&BasicSessionStream::handleTLSConnected, this)); + } - connection->onDisconnected.disconnect(boost::bind(&BasicSessionStream::handleConnectionFinished, this, _1)); - delete connectionLayer; + connection->onDisconnected.disconnect(boost::bind(&BasicSessionStream::handleConnectionFinished, this, _1)); - xmppLayer->onStreamStart.disconnect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); - xmppLayer->onElement.disconnect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); - xmppLayer->onError.disconnect(boost::bind(&BasicSessionStream::handleXMPPError, this)); - xmppLayer->onDataRead.disconnect(boost::bind(&BasicSessionStream::handleDataRead, this, _1)); - xmppLayer->onWriteData.disconnect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1)); - delete xmppLayer; + auto xmppLayer = streamStack->getLayer<XMPPLayer>(); + xmppLayer->onStreamStart.disconnect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); + xmppLayer->onStreamEnd.disconnect(boost::bind(&BasicSessionStream::handleStreamEndReceived, this)); + xmppLayer->onElement.disconnect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); + xmppLayer->onError.disconnect(boost::bind(&BasicSessionStream::handleXMPPError, this)); + xmppLayer->onDataRead.disconnect(boost::bind(&BasicSessionStream::handleDataRead, this, _1)); + xmppLayer->onWriteData.disconnect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1)); } void BasicSessionStream::writeHeader(const ProtocolHeader& header) { - assert(available); - xmppLayer->writeHeader(header); + assert(available); + auto* xmppLayer = streamStack->getLayer<XMPPLayer>(); + xmppLayer->writeHeader(header); } -void BasicSessionStream::writeElement(boost::shared_ptr<Element> element) { - assert(available); - xmppLayer->writeElement(element); +void BasicSessionStream::writeElement(std::shared_ptr<ToplevelElement> element) { + assert(available); + auto* xmppLayer = streamStack->getLayer<XMPPLayer>(); + xmppLayer->writeElement(element); } void BasicSessionStream::writeFooter() { - assert(available); - xmppLayer->writeFooter(); + assert(available); + auto* xmppLayer = streamStack->getLayer<XMPPLayer>(); + xmppLayer->writeFooter(); } void BasicSessionStream::writeData(const std::string& data) { - assert(available); - xmppLayer->writeData(data); + assert(available); + auto* xmppLayer = streamStack->getLayer<XMPPLayer>(); + xmppLayer->writeData(data); } void BasicSessionStream::close() { - connection->disconnect(); + connection->disconnect(); } bool BasicSessionStream::isOpen() { - return available; + return available; } bool BasicSessionStream::supportsTLSEncryption() { - return tlsContextFactory && tlsContextFactory->canCreate(); + return tlsContextFactory && tlsContextFactory->canCreate(); } void BasicSessionStream::addTLSEncryption() { - assert(available); - tlsLayer = new TLSLayer(tlsContextFactory); - if (hasTLSCertificate() && !tlsLayer->setClientCertificate(getTLSCertificate())) { - onClosed(boost::make_shared<SessionStreamError>(SessionStreamError::InvalidTLSCertificateError)); - } - else { - streamStack->addLayer(tlsLayer); - tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this, _1)); - tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this)); - tlsLayer->connect(); - } + assert(available); + auto tlsContext = tlsContextFactory->createTLSContext(tlsOptions_); + auto tlsLayer = std::make_unique<TLSLayer>(std::move(tlsContext)); + if (hasTLSCertificate() && !tlsLayer->setClientCertificate(getTLSCertificate())) { + onClosed(std::make_shared<SessionStreamError>(SessionStreamError::InvalidTLSCertificateError)); + } + else { + streamStack->addLayer(std::move(tlsLayer)); + auto tlsLayer = streamStack->getLayer<TLSLayer>(); + tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this, _1)); + tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this)); + tlsLayer->connect(); + } } bool BasicSessionStream::isTLSEncrypted() { - return tlsLayer; + return streamStack->getLayer<TLSLayer>(); } Certificate::ref BasicSessionStream::getPeerCertificate() const { - return tlsLayer->getPeerCertificate(); + return streamStack->getLayer<TLSLayer>()->getPeerCertificate(); } std::vector<Certificate::ref> BasicSessionStream::getPeerCertificateChain() const { - return tlsLayer->getPeerCertificateChain(); + return streamStack->getLayer<TLSLayer>()->getPeerCertificateChain(); } -boost::shared_ptr<CertificateVerificationError> BasicSessionStream::getPeerCertificateVerificationError() const { - return tlsLayer->getPeerCertificateVerificationError(); +std::shared_ptr<CertificateVerificationError> BasicSessionStream::getPeerCertificateVerificationError() const { + return streamStack->getLayer<TLSLayer>()->getPeerCertificateVerificationError(); } ByteArray BasicSessionStream::getTLSFinishMessage() const { - return tlsLayer->getContext()->getFinishMessage(); + return streamStack->getLayer<TLSLayer>()->getContext()->getFinishMessage(); } bool BasicSessionStream::supportsZLibCompression() { - return true; + return true; } void BasicSessionStream::addZLibCompression() { - compressionLayer = new CompressionLayer(); - streamStack->addLayer(compressionLayer); + streamStack->addLayer(std::make_unique<CompressionLayer>()); } void BasicSessionStream::setWhitespacePingEnabled(bool enabled) { - if (enabled) { - if (!whitespacePingLayer) { - whitespacePingLayer = new WhitespacePingLayer(timerFactory); - streamStack->addLayer(whitespacePingLayer); - } - whitespacePingLayer->setActive(); - } - else if (whitespacePingLayer) { - whitespacePingLayer->setInactive(); - } + auto whitespacePingLayer = streamStack->getLayer<WhitespacePingLayer>(); + if (enabled) { + if (!whitespacePingLayer) { + streamStack->addLayer(std::make_unique<WhitespacePingLayer>(timerFactory)); + whitespacePingLayer = streamStack->getLayer<WhitespacePingLayer>(); + } + whitespacePingLayer->setActive(); + } + else if (whitespacePingLayer) { + whitespacePingLayer->setInactive(); + } } void BasicSessionStream::resetXMPPParser() { - xmppLayer->resetParser(); + auto* xmppLayer = streamStack->getLayer<XMPPLayer>(); + xmppLayer->resetParser(); } void BasicSessionStream::handleStreamStartReceived(const ProtocolHeader& header) { - onStreamStartReceived(header); + onStreamStartReceived(header); +} + +void BasicSessionStream::handleStreamEndReceived() { + onStreamEndReceived(); } -void BasicSessionStream::handleElementReceived(boost::shared_ptr<Element> element) { - onElementReceived(element); +void BasicSessionStream::handleElementReceived(std::shared_ptr<ToplevelElement> element) { + onElementReceived(element); } void BasicSessionStream::handleXMPPError() { - available = false; - onClosed(boost::make_shared<SessionStreamError>(SessionStreamError::ParseError)); + available = false; + onClosed(std::make_shared<SessionStreamError>(SessionStreamError::ParseError)); } void BasicSessionStream::handleTLSConnected() { - onTLSEncrypted(); + onTLSEncrypted(); } -void BasicSessionStream::handleTLSError(boost::shared_ptr<TLSError> error) { - available = false; - onClosed(error); +void BasicSessionStream::handleTLSError(std::shared_ptr<TLSError> error) { + available = false; + onClosed(error); } void BasicSessionStream::handleConnectionFinished(const boost::optional<Connection::Error>& error) { - available = false; - if (error == Connection::ReadError) { - onClosed(boost::make_shared<SessionStreamError>(SessionStreamError::ConnectionReadError)); - } - else if (error) { - onClosed(boost::make_shared<SessionStreamError>(SessionStreamError::ConnectionWriteError)); - } - else { - onClosed(boost::shared_ptr<SessionStreamError>()); - } + available = false; + if (error == Connection::ReadError) { + onClosed(std::make_shared<SessionStreamError>(SessionStreamError::ConnectionReadError)); + } + else if (error) { + onClosed(std::make_shared<SessionStreamError>(SessionStreamError::ConnectionWriteError)); + } + else { + onClosed(std::shared_ptr<SessionStreamError>()); + } } void BasicSessionStream::handleDataRead(const SafeByteArray& data) { - onDataRead(data); + onDataRead(data); } void BasicSessionStream::handleDataWritten(const SafeByteArray& data) { - onDataWritten(data); + onDataWritten(data); } } |