From 7ad4ebe136faf53a759efdc3605cc0edc524f36d Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Fri, 5 Jul 2013 19:59:49 +0200 Subject: [PATCH] new class: TimedTcpConnection. And SslConnection now uses it instead of TcpConnection. --- include/SslConnection.hpp | 29 ++++---- include/TimedTcpConnection.hpp | 69 ++++++++++++++++++ src/SslConnection.cpp | 90 +++++++++++++---------- src/TimedTcpConnection.cpp | 128 +++++++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 55 deletions(-) create mode 100644 include/TimedTcpConnection.hpp create mode 100644 src/TimedTcpConnection.cpp diff --git a/include/SslConnection.hpp b/include/SslConnection.hpp index 6bd9fdf..d207d65 100644 --- a/include/SslConnection.hpp +++ b/include/SslConnection.hpp @@ -3,14 +3,10 @@ #include "StreamConnection.hpp" -#include "TcpConnection.hpp" -#include "Message.hpp" +#include "TimedTcpConnection.hpp" #include - -// #include #include -// #include @@ -22,10 +18,6 @@ public: static void init(); static void destroy(); - SslConnection ( const int socket, - Message *message, - const size_t bufferLength = 1024 ); - SslConnection ( const std::string host, const std::string port, Message *message, @@ -47,12 +39,17 @@ public: bool bind(); bool listen( const int maxPendingQueueLen = 64 ); - int accept(); + bool accept(int &client_socket); + bool closed() const; int getSocket() const; private: + SslConnection ( TimedTcpConnection *timedTcpConnection, + Message *message, + const size_t bufferLength = 1024 ); + SslConnection(const SslConnection&); SslConnection& operator=(const SslConnection&); @@ -64,12 +61,12 @@ private: void showCertificates(); - TcpConnection m_tcpConnection; - Message *m_message; - unsigned char *m_buffer; - size_t m_bufferLength; - SSL *m_sslHandle; - SSL_CTX *m_sslContext; + TimedTcpConnection *m_timedTcpConnection; + Message *m_message; + unsigned char *m_buffer; + size_t m_bufferLength; + SSL *m_sslHandle; + SSL_CTX *m_sslContext; }; diff --git a/include/TimedTcpConnection.hpp b/include/TimedTcpConnection.hpp new file mode 100644 index 0000000..9e5ed20 --- /dev/null +++ b/include/TimedTcpConnection.hpp @@ -0,0 +1,69 @@ +#ifndef TIMED_TCP_CONNECTION_HPP +#define TIMED_TCP_CONNECTION_HPP + + +#include "StreamConnection.hpp" +#include "TimerUser.hpp" +#include "TcpConnection.hpp" + + +/** @brief Inactivity monitored TCP connection. + * + * The timer is created at: + * - ctor, clone + * + * The timer is restarted after: + * - connect, send, receive + * + * The timer is destroyed at: + * - dtor, disconnect + */ + +class TimedTcpConnection : public StreamConnection + , public TimerUser +{ +public: + + TimedTcpConnection(const std::string host, + const std::string port, + Message *message, + const size_t bufferLength = 1024, + const unsigned long timeOutSec = 30); + + virtual ~TimedTcpConnection(); + + // inherited from TimerUser + virtual void timerExpired(); + + Connection* clone(const int socket); + + /// @todo mention inheritance + bool connect(); + bool disconnect(); + + bool send( const void* message, const size_t length ); + bool receive(); + + int getSocket() const; + + bool bind(); + bool listen( const int maxPendingQueueLen = 64 ); + bool accept(int &client_socket); + + bool closed() const; + +private: + + TimedTcpConnection(TcpConnection *tcpConnection, + const unsigned long timeOutSec = 30); + + TimedTcpConnection(const TimedTcpConnection&); + TimedTcpConnection& operator=(const TimedTcpConnection&); + + TcpConnection *m_tcpConnection; + unsigned long m_timeOutSec; + +}; + + +#endif // TIMED_TCP_CONNECTION_HPP \ No newline at end of file diff --git a/src/SslConnection.cpp b/src/SslConnection.cpp index 088c78b..e9865ef 100644 --- a/src/SslConnection.cpp +++ b/src/SslConnection.cpp @@ -26,33 +26,12 @@ void SslConnection::destroy() } -SslConnection::SslConnection ( const int socket, - Message *message, - const size_t bufferLength ) - : StreamConnection("invalid", "invalid") - , m_tcpConnection(socket, message, 0) - , m_message(message) - , m_buffer(0) - , m_bufferLength(bufferLength) - , m_sslHandle(0) - , m_sslContext(0) -{ - TRACE; - - setHost(m_tcpConnection.getHost()); - setPort(m_tcpConnection.getPort()); - - m_buffer = new unsigned char[m_bufferLength]; - m_message->setConnection(this); -} - - SslConnection::SslConnection ( const std::string host, const std::string port, Message *message, const size_t bufferLength ) : StreamConnection(host, port) - , m_tcpConnection(host, port, message, 0) + , m_timedTcpConnection(new TimedTcpConnection(host, port, message, 0)) , m_message(message) , m_buffer(0) , m_bufferLength(bufferLength) @@ -70,6 +49,7 @@ SslConnection::~SslConnection() TRACE; disconnect(); delete m_buffer; + delete m_timedTcpConnection; } @@ -77,9 +57,14 @@ Connection* SslConnection::clone(const int socket) { TRACE; - SslConnection *conn = new SslConnection( socket, m_message->clone(), m_bufferLength ); - conn->setHandle(m_sslHandle); - return conn; + Connection* conn = m_timedTcpConnection->clone(socket); + + SslConnection *sslConn = new SslConnection( + dynamic_cast(conn), + m_message->clone(), + m_bufferLength); + sslConn->setHandle(m_sslHandle); + return sslConn; } @@ -87,10 +72,10 @@ bool SslConnection::connect() { TRACE; - if ( !m_tcpConnection.connect() ) + if ( !m_timedTcpConnection->connect() ) return false; - if ( SSL_set_fd(m_sslHandle, m_tcpConnection.getSocket() ) == 0 ) { + if ( SSL_set_fd(m_sslHandle, m_timedTcpConnection->getSocket() ) == 0 ) { LOG( Logger::ERR, getSslError("SSL set connection socket failed. ").c_str() ); return -1; } @@ -110,36 +95,35 @@ bool SslConnection::bind() { TRACE; - return m_tcpConnection.bind(); + return m_timedTcpConnection->bind(); } bool SslConnection::listen( const int maxPendingQueueLen ) { TRACE; - return m_tcpConnection.listen(maxPendingQueueLen); + return m_timedTcpConnection->listen(maxPendingQueueLen); } -int SslConnection::accept() +bool SslConnection::accept(int &client_socket) { TRACE; - int client_socket = m_tcpConnection.accept(); - if ( client_socket == -1) - return client_socket; + if(!m_timedTcpConnection->accept(client_socket)) + return false; if ( SSL_set_fd(m_sslHandle, client_socket) == 0 ) { LOG( Logger::ERR, getSslError("SSL set connection socket failed. ").c_str() ); - return -1; + return false; } if ( SSL_accept(m_sslHandle) == -1 ) { LOG( Logger::ERR, getSslError("SSL accept failed. ").c_str() ); - return -1; + return false; } - return client_socket; + return true; } /// @todo this function shall be refactored @@ -148,8 +132,8 @@ bool SslConnection::disconnect() TRACE; /// @note do I have to call this? - if ( m_tcpConnection.getSocket() != -1 ) - m_tcpConnection.disconnect(); + if ( m_timedTcpConnection->getSocket() != -1 ) + m_timedTcpConnection->disconnect(); if ( m_sslHandle == 0 || m_sslContext == 0 ) return false; @@ -253,10 +237,38 @@ bool SslConnection::receive() } +bool SslConnection::closed() const +{ + TRACE; + return m_timedTcpConnection->closed(); +} + + int SslConnection::getSocket() const { TRACE; - return m_tcpConnection.getSocket(); + return m_timedTcpConnection->getSocket(); +} + + +SslConnection::SslConnection(TimedTcpConnection *timedTcpConnection, + Message *message, + const size_t bufferLength) + : StreamConnection("invalid", "invalid") + , m_timedTcpConnection(timedTcpConnection) + , m_message(message) + , m_buffer(0) + , m_bufferLength(bufferLength) + , m_sslHandle(0) + , m_sslContext(0) +{ + TRACE; + + setHost(m_timedTcpConnection->getHost()); + setPort(m_timedTcpConnection->getPort()); + + m_buffer = new unsigned char[m_bufferLength]; + m_message->setConnection(this); } diff --git a/src/TimedTcpConnection.cpp b/src/TimedTcpConnection.cpp new file mode 100644 index 0000000..c56b788 --- /dev/null +++ b/src/TimedTcpConnection.cpp @@ -0,0 +1,128 @@ +#include "TimedTcpConnection.hpp" + +#include "Logger.hpp" + + +TimedTcpConnection::TimedTcpConnection(const std::string host, + const std::string port, + Message *message, + const size_t bufferLength, + const unsigned long timeOutSec) + : StreamConnection(host, port) + , TimerUser() + , m_tcpConnection(new TcpConnection(host, port, message, bufferLength)) + , m_timeOutSec(timeOutSec) +{ + TRACE; +} + + +TimedTcpConnection::~TimedTcpConnection() +{ + TRACE; + delete m_tcpConnection; +} + + +void TimedTcpConnection::timerExpired() +{ + TRACE; + m_tcpConnection->setState(TcpConnection::CLOSED); +} + + +Connection* TimedTcpConnection::clone(const int socket) +{ + Connection *conn = m_tcpConnection->clone(socket); + + TimedTcpConnection *timedTcpConnection = new TimedTcpConnection( + dynamic_cast(conn), + m_timeOutSec); + + return timedTcpConnection; +} + + +bool TimedTcpConnection::connect() +{ + TRACE; + + startTimer(m_timeOutSec); + return m_tcpConnection->connect(); +} + + +bool TimedTcpConnection::bind() +{ + TRACE; + return m_tcpConnection->bind(); +} + + +bool TimedTcpConnection::listen( const int maxPendingQueueLen ) +{ + TRACE; + return m_tcpConnection->listen(maxPendingQueueLen); +} + + +bool TimedTcpConnection::accept(int &client_socket) +{ + TRACE; + return m_tcpConnection->accept(client_socket); +} + + +bool TimedTcpConnection::disconnect() +{ + TRACE; + + stopTimer(); + return m_tcpConnection->disconnect(); +} + + +bool TimedTcpConnection::send(const void* message, const size_t length) +{ + TRACE; + + startTimer(m_timeOutSec); + return m_tcpConnection->send(message, length); +} + + +bool TimedTcpConnection::receive() +{ + TRACE; + + startTimer(m_timeOutSec); + return m_tcpConnection->receive(); +} + + +int TimedTcpConnection::getSocket() const +{ + TRACE; + return m_tcpConnection->getSocket(); +} + + +bool TimedTcpConnection::closed() const +{ + TRACE; + return m_tcpConnection->closed(); +} + + +TimedTcpConnection::TimedTcpConnection(TcpConnection *tcpConnection, + const unsigned long timeOutSec) + : StreamConnection("invalid", "invalid") + , TimerUser() + , m_tcpConnection(tcpConnection) + , m_timeOutSec(timeOutSec) +{ + TRACE; + + setHost(m_tcpConnection->getHost()); + setPort(m_tcpConnection->getPort()); +}