/* * Copyright (c) 2012-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include #include #include #include #include #include using namespace Swift; ProxiedConnection::ProxiedConnection( DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, const std::string& proxyHost, int proxyPort) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) { connected_ = false; } ProxiedConnection::~ProxiedConnection() { cancelConnector(); if (connection_) { connection_->onDataRead.disconnect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1)); connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1)); } if (connected_) { std::cerr << "Warning: Connection was still established." << std::endl; } } void ProxiedConnection::cancelConnector() { if (connector_) { connector_->onConnectFinished.disconnect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1)); connector_->stop(); connector_.reset(); } } void ProxiedConnection::connect(const HostAddressPort& server) { server_ = server; connector_ = Connector::create(proxyHost_, proxyPort_, boost::optional(), resolver_, connectionFactory_, timerFactory_); connector_->onConnectFinished.connect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1)); connector_->start(); } void ProxiedConnection::listen() { assert(false); connection_->listen(); } void ProxiedConnection::disconnect() { connected_ = false; connection_->disconnect(); } void ProxiedConnection::handleDisconnected(const boost::optional& error) { onDisconnected(error); } void ProxiedConnection::write(const SafeByteArray& data) { connection_->write(data); } void ProxiedConnection::handleConnectFinished(Connection::ref connection) { cancelConnector(); if (connection) { connection_ = connection; connection_->onDataRead.connect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1)); connection_->onDisconnected.connect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1)); initializeProxy(); } else { onConnectFinished(true); } } void ProxiedConnection::handleDataRead(boost::shared_ptr data) { if (!connected_) { handleProxyInitializeData(data); } else { onDataRead(data); } } HostAddressPort ProxiedConnection::getLocalAddress() const { return connection_->getLocalAddress(); } HostAddressPort ProxiedConnection::getRemoteAddress() const { return connection_->getRemoteAddress(); } void ProxiedConnection::setProxyInitializeFinished(bool success) { connected_ = success; if (!success) { disconnect(); } onConnectFinished(!success); } void ProxiedConnection::reconnect() { if (connected_) { connection_->onDataRead.disconnect(boost::bind(&ProxiedConnection::handleDataRead, shared_from_this(), _1)); connection_->onDisconnected.disconnect(boost::bind(&ProxiedConnection::handleDisconnected, shared_from_this(), _1)); connection_->disconnect(); } connect(server_); }