Select Git revision
SSLSession.cpp
-
Robert Butora authored
works around a warning from protobuf: ByteSize() deprecated use ByteSizeLong() (Note downcast: protobuf SerializeToArray() still uses int)
Robert Butora authoredworks around a warning from protobuf: ByteSize() deprecated use ByteSizeLong() (Note downcast: protobuf SerializeToArray() still uses int)
SSLSession.cpp 8.31 KiB
#include <SSLSession.h>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
namespace DataExporter_ns
{
//==============================================================================
// SSLSession::SSLSession()
//==============================================================================
SSLSession::SSLSession(Tango::DeviceImpl* deviceImpl_p,
Configuration::SP configuration_sp, DBManager::SP dBManager_sp,
boost::shared_ptr<boost::asio::io_service> ioService_sp,
boost::shared_ptr<boost::asio::ssl::context> context_sp) :
Session::Session(deviceImpl_p, configuration_sp, dBManager_sp, ioService_sp),
m_sslSocket(*ioService_sp, *context_sp)
{
DEBUG_STREAM << "SSLSession::SSLSession()" << endl;
}
//==============================================================================
// SSLSession::~SSLSession()
//==============================================================================
SSLSession::~SSLSession()
{
DEBUG_STREAM << "SSLSession::~SSLSession()" << endl;
INFO_STREAM << "SSLSession::~SSLSession() Disconnection from "
<< m_remoteEndpoint << endl;
boost::system::error_code errorCode;
m_sslSocket.shutdown(errorCode);
m_sslSocket.lowest_layer().shutdown(
boost::asio::ip::tcp::socket::shutdown_both, errorCode);
m_sslSocket.lowest_layer().close(errorCode);
}
//==============================================================================
// SSLSession::create()
//==============================================================================
Session::SP SSLSession::create(Tango::DeviceImpl* deviceImpl_p,
Configuration::SP configuration_sp, DBManager::SP dBManager_sp,
boost::shared_ptr<boost::asio::io_service> ioService_sp,
boost::shared_ptr<boost::asio::ssl::context> context_sp)
{
Session::SP s_sp(new SSLSession(deviceImpl_p, configuration_sp,
dBManager_sp, ioService_sp, context_sp), SSLSession::Deleter());
return s_sp;
}
//==============================================================================
// SSLSession::getSocket()
//==============================================================================
boost::asio::ip::tcp::socket& SSLSession::getSocket()
{
DEBUG_STREAM << "SSLSession::getSocket()" << endl;
return m_sslSocket.next_layer();
}
//==============================================================================
// SSLSession::start()
//==============================================================================
void SSLSession::start()
{
DEBUG_STREAM << "SSLSession::start()" << endl;
m_remoteEndpoint = boost::lexical_cast<std::string>(
m_sslSocket.lowest_layer().remote_endpoint());
INFO_STREAM << "SSLSession::start() Connection from "
<< m_remoteEndpoint << endl;
m_protocolManager_sp->setRemoteEndpoint(m_remoteEndpoint);
startHandShake();
}
//==============================================================================
// SSLSession::startHandShake()
//==============================================================================
void SSLSession::startHandShake()
{
DEBUG_STREAM << "SSLSession::startHandShake()" << endl;
m_sslSocket.async_handshake(boost::asio::ssl::stream_base::server,
boost::bind(&SSLSession::handleHandShake, shared_from_this(),
boost::asio::placeholders::error));
}
//==============================================================================
// SSLSession::handleRequest()
//==============================================================================
void SSLSession::handleHandShake(const boost::system::error_code& errorCode)
{
DEBUG_STREAM << "SSLSession::handleHandShake()" << endl;
if(!errorCode)
{
startReadRequestHeader();
}
else
{
ERROR_STREAM << "SSLSession::handleHandShake() error "
<< errorCode.message() << " from " << m_remoteEndpoint << endl;
}
}
//==============================================================================
// SSLSession::startReadRequestHeader()
//==============================================================================
void SSLSession::startReadRequestHeader()
{
DEBUG_STREAM << "SSLSession::startReadRequestHeader()" << endl;
m_readBuff.resize(HEADER_SIZE);
boost::asio::async_read(m_sslSocket, boost::asio::buffer(m_readBuff),
m_strand.wrap(boost::bind(&SSLSession::handleReadRequestHeader,
shared_from_this(), boost::asio::placeholders::error)));
}
//==============================================================================
// SSLSession::startReadRequestBody()
//==============================================================================
void SSLSession::startReadRequestBody(boost::uint32_t bodySize)
{
DEBUG_STREAM << "SSLSession::startReadRequestBody()" << endl;
m_readBuff.resize(HEADER_SIZE + bodySize);
boost::asio::mutable_buffers_1 mutableBuffer =
boost::asio::buffer(&m_readBuff[HEADER_SIZE], bodySize);
#ifdef VERBOSE_DEBUG
INFO_STREAM << "SSLSession::startReadRequestBody() "
<< m_remoteEndpoint << " >>>> " << bodySize << " byte" << endl;
#endif
boost::asio::async_read(m_sslSocket, mutableBuffer,
m_strand.wrap(boost::bind(&SSLSession::handleReadRequestBody,
shared_from_this(), boost::asio::placeholders::error)));
}
//==============================================================================
// SSLSession::startWriteResponse()
//==============================================================================
void SSLSession::startWriteResponse()
{
DEBUG_STREAM << "SSLSession::startWriteResponse()" << endl;
try
{
RequestSP request_sp(new Request);
request_sp->ParseFromArray(&m_readBuff[HEADER_SIZE],
m_readBuff.size() - HEADER_SIZE);
ResponseSP response_sp = m_protocolManager_sp->prepareResponse(request_sp);
boost::uint32_t bodySize = response_sp->ByteSizeLong();
std::vector<boost::uint8_t> writeBuff;
writeBuff.resize(HEADER_SIZE + bodySize);
encodeHeader(writeBuff, bodySize);
response_sp->SerializeToArray(&writeBuff[HEADER_SIZE], bodySize);
#ifdef VERBOSE_DEBUG
INFO_STREAM << "SSLSession::startWriteResponse() "
<< m_remoteEndpoint << " <<<< " << bodySize << " byte" << endl;
#endif
boost::asio::async_write(m_sslSocket, boost::asio::buffer(writeBuff),
m_strand.wrap(boost::bind(&SSLSession::handleWriteResponse,
shared_from_this(), boost::asio::placeholders::error)));
}
catch(std::exception& ec)
{
ERROR_STREAM << "SSLSession::startWriteResponse() "
<< ec.what() << " from " << m_remoteEndpoint << endl;
}
catch(...)
{
ERROR_STREAM << "SSLSession::startWriteResponse() unknown error from "
<< m_remoteEndpoint << endl;
}
}
//==============================================================================
// SSLSession::startWriteData()
//==============================================================================
void SSLSession::startWriteData(FileWrapper::SP fileWrapper_sp)
{
try
{
if(!fileWrapper_sp->isBad())
{
if(!fileWrapper_sp->isCompleted())
{
std::vector<char> writeBuff;
fileWrapper_sp->read(writeBuff);
boost::asio::async_write(m_sslSocket, boost::asio::buffer(writeBuff),
m_strand.wrap(boost::bind(&SSLSession::handleWriteData,
shared_from_this(), fileWrapper_sp,
boost::asio::placeholders::error)));
}
else
{
INFO_STREAM << "SSLSession::startWriteData() "
<< " transfer completed " << endl;
startReadRequestHeader();
}
}
else
{
ERROR_STREAM << "SSLSession::startWriteData() error on file I/O "
<< "from " << m_remoteEndpoint << endl;
}
}
catch(std::exception& ec)
{
ERROR_STREAM << "SSLSession::startWriteData() "
<< ec.what() << " from " << m_remoteEndpoint << endl;
}
catch(...)
{
ERROR_STREAM << "SSLSession::startWriteData() unknown error from "
<< m_remoteEndpoint << endl;
}
}
} //namespace