37 #ifndef FIX8_SESSIONWRAPPER_HPP_
38 #define FIX8_SESSIONWRAPPER_HPP_
40 #include <Poco/Net/ServerSocket.h>
41 #ifdef FIX8_HAVE_OPENSSL
42 #include <Poco/Net/SecureStreamSocket.h>
43 #include <Poco/Net/SecureServerSocket.h>
44 #include <Poco/SharedPtr.h>
45 #include <Poco/Net/PrivateKeyPassphraseHandler.h>
46 #include <Poco/Net/InvalidCertificateHandler.h>
47 #include <Poco/Net/SSLManager.h>
54 #ifdef FIX8_HAVE_OPENSSL
58 class Fix8CertificateHandler:
public Poco::Net::InvalidCertificateHandler
62 Fix8CertificateHandler(
bool handleErrorsOnServerSide) : Poco::Net::InvalidCertificateHandler(handleErrorsOnServerSide) {}
65 virtual ~Fix8CertificateHandler() {}
69 F8API void onInvalidCertificate(
const void* pSender, Poco::Net::VerificationErrorArgs& errorCert);
75 class Fix8PassPhraseHandler :
public Poco::Net::PrivateKeyPassphraseHandler
79 Fix8PassPhraseHandler(
bool server) : Poco::Net::PrivateKeyPassphraseHandler(server) {}
82 ~Fix8PassPhraseHandler() {}
84 F8API void onPrivateKeyRequested(
const void* pSender, std::string& privateKey);
90 PocoSslContext(
const SslContext&
ctx,
bool client)
94 Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler> phrase_handler(
new Fix8PassPhraseHandler(!client));
95 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> cert_handler(
new Fix8CertificateHandler(!client));
96 #if POCO_VERSION >= 0x01040000
97 Poco::Net::initializeSSL();
99 _context =
new Poco::Net::Context(
100 client ? Poco::Net::Context::CLIENT_USE : Poco::Net::Context::SERVER_USE,
101 ctx._private_key_file, ctx._certificate_file, ctx._ca_location,
102 static_cast<Poco::Net::Context::VerificationMode>(ctx._verification_mode), ctx._verification_depth,
103 ctx._load_default_cas, ctx._cipher_list);
105 Poco::Net::SSLManager::instance().initializeClient(phrase_handler, cert_handler, _context);
107 Poco::Net::SSLManager::instance().initializeServer(phrase_handler, cert_handler, _context);
113 #if POCO_VERSION >= 0x01040000
115 Poco::Net::uninitializeSSL();
119 Poco::Net::Context::Ptr _context;
120 bool is_secure()
const {
return _context.get() != 0; }
191 virtual void start(
bool wait,
unsigned send_seqnum=0,
unsigned recv_seqnum=0,
const f8String davi=
f8String()) = 0;
207 Poco::Net::StreamSocket *
_sock =
nullptr;
210 #ifdef FIX8_HAVE_OPENSSL
217 const std::string& session_name,
bool init_con_later=
false) :
220 _id(
_ctx._beginStr, _sci, _tci),
224 _session(new T(
_ctx, _id, _persist, _log, _plog)),
226 #ifdef FIX8_HAVE_OPENSSL
227 ,_ssl(get_ssl_context(
_ses), true)
232 #ifdef FIX8_HAVE_OPENSSL
233 bool secured(_ssl.is_secure());
235 ?
new Poco::Net::SecureStreamSocket(_ssl._context)
236 :
new Poco::Net::StreamSocket;
239 _sock =
new Poco::Net::StreamSocket;
245 _session->set_session_config(
this);
271 { _session->start(_cc, wait, send_seqnum, recv_seqnum, davi); }
295 :
ClientSession<T>(ctx, conf_file, session_name, true), _thread(
std::ref(*this)),
322 _send_seqnum = send_seqnum;
344 : idx < _failover_cnt ? &_servers[idx] :
nullptr;
351 while(!_cancellation_token)
355 bool excepted(_failover_cnt == 0);
360 std::ostringstream ostr;
361 ostr <<
"Trying " << _servers[
_current]._hostname <<
'(' << (1 + _servers[
_current]._retries) <<
"), "
368 #ifdef FIX8_HAVE_OPENSSL
369 bool secured(this->_ssl.is_secure());
370 this->_sock = secured
371 ?
new Poco::Net::SecureStreamSocket(this->_ssl._context)
372 :
new Poco::Net::StreamSocket;
375 this->_sock =
new Poco::Net::StreamSocket;
380 this->_session->set_session_config(
this);
384 catch (Poco::TimeoutException& e)
395 catch (Poco::Net::InvalidAddressException& e)
400 #if POCO_VERSION >= 0x01040000
401 catch (Poco::Net::InvalidSocketException& e)
407 catch (Poco::Net::ServiceNotFoundException& e)
413 catch (Poco::Net::ConnectionRefusedException& e)
418 catch (Poco::Net::DNSException& e)
423 catch (Poco::Net::InterfaceNotFoundException& e)
428 catch (Poco::Net::NetException& e)
433 catch (std::exception& e)
443 this->_session->stop();
449 catch (Poco::Net::NetException& e)
453 catch (std::exception& e)
461 this->_sock =
nullptr;
463 if (!excepted || (_failover_cnt == 0
471 while (!_cancellation_token)
514 _server_sock =
nullptr;
524 bool poll(
const Poco::Timespan& span=Poco::Timespan(250000))
const
525 {
return _server_sock->poll(span, Poco::Net::Socket::SELECT_READ); }
530 Poco::Net::StreamSocket
accept(Poco::Net::SocketAddress& claddr)
531 {
return _server_sock->acceptConnection(claddr); }
547 #ifdef FIX8_HAVE_OPENSSL
556 #ifdef FIX8_HAVE_OPENSSL
557 ,_ssl(get_ssl_context(
_ses), false)
561 #ifdef FIX8_HAVE_OPENSSL
562 _ssl.is_secure() ?
new Poco::Net::SecureServerSocket(_addr, 64, _ssl._context) :
564 new Poco::Net::ServerSocket(_addr);
583 #ifdef FIX8_HAVE_OPENSSL
584 {
return _ssl.is_secure(); }
609 virtual void start(
bool wait,
unsigned send_seqnum=0,
unsigned recv_seqnum=0) {}
619 class SessionInstance :
public SessionInstanceBase
631 _sock(new Poco::Net::StreamSocket(_sf.accept(_claddr))),
632 _session(new T(_sf._ctx, _sf.get_sender_comp_id(_sf._ses))),
633 _psc(new
ServerConnection(_sock, _claddr, *_session, _sf.get_heartbeat_interval(_sf._ses), _sf.get_process_model(_sf._ses),
634 _sf.get_tcp_nodelay(_sf._ses), _sf.get_tcp_reuseaddr(_sf._ses), _sf.get_tcp_linger(_sf._ses),
635 _sf.get_tcp_keepalive(_sf._ses),
636 #ifdef FIX8_HAVE_OPENSSL
644 _session->set_session_config(&_sf);
663 catch (Poco::Exception& e)
667 catch (std::exception& e)
681 catch (Poco::Exception& e)
685 catch (std::exception& e)
699 catch (Poco::Exception& e)
703 catch (std::exception& e)
717 virtual void start(
bool wait,
unsigned send_seqnum=0,
unsigned recv_seqnum=0)
override
718 { _session->start(_psc, wait, send_seqnum, recv_seqnum); }
721 virtual void stop()
override { _session->stop(); }
732 #endif // FIX8_SESSIONWRAPPER_HPP_
std::vector< Server > _servers
Client (initiator) specialisation of Connection.
bool get_permissive_mode_flag(const XmlElement *from, const bool def=false) const
LoginParameters _loginParameters
virtual bool is_secure() const
ServerSessionBase(const F8MetaCntx &ctx, const std::string &conf_file, const std::string &session_name)
Ctor. Prepares session for receiving inbbound connections (acceptor).
f8_thread delegated async logging class
bool get_reset_sequence_number_flag(const XmlElement *from, const bool def=false) const
unsigned get_tcp_sendbuf_sz(const XmlElement *from, const unsigned def=0) const
virtual ~ClientSessionBase()
Dtor.
virtual bool is_secure() const
std::unique_ptr< SessionInstance< T >> SessionInstance_ptr
Convenient scoped pointer for your session instance.
Fix8 Base Session. User sessions are derived from this class.
Base Server session instance.
static void set_recv_buf_sz(const unsigned sz, Poco::Net::Socket *sock)
const Server * get_server(unsigned idx=no_servers_configured) const
unsigned _login_retry_interval
bool get_silent_disconnect(const XmlElement *from, const bool def=false) const
virtual void stop()
Stop the session. Cleanup.
Base (ABC) Persister class.
virtual void start(bool wait, unsigned send_seqnum=0, unsigned recv_seqnum=0)
default_appl_ver_id _davi
F8API void stop()
Stop the reader and writer threads.
Class to hold server settings for failoverable sessions.
bool poll(const Poco::Timespan &span=Poco::Timespan(250000)) const
f8_thread_cancellation_token _cancellation_token
f8_thread_cancellation_token & cancellation_token()
F8API Poco::Net::SocketAddress get_address(const XmlElement *from) const
Server (acceptor) specialisation of Connection.
unsigned get_tcp_recvbuf_sz(const XmlElement *from, const unsigned def=0) const
size_t get_attempts_cnt() const
size_t get_server_cnt() const
unsigned get_retry_interval(const XmlElement *from, const unsigned def=defaults::retry_interval) const
Poco::Net::ServerSocket * _server_sock
virtual ~SessionConfig()
Dtor.
Thread wrapper. Ctor provides T instance and specifies ptr to member to call or defaults to operator(...
const size_t _failover_cnt
Quickfix style sessionid.
virtual ~SessionInstance()
Dtor.
SessionInstance(ServerSession< T > &sf)
Ctor. Prepares session instance with inbound connection.
Thread cancellation token.
virtual Session * session_ptr()=0
F8API Persister * create_persister(const XmlElement *from, const SessionID *sid=nullptr, bool flag=false) const
F8API size_t get_addresses(const XmlElement *from, std::vector< Server > &target) const
virtual SessionInstanceBase * create_server_instance()
ClientSession(const F8MetaCntx &ctx, const std::string &conf_file, const std::string &session_name, bool init_con_later=false)
Ctor. Prepares session for connection as an initiator.
Poco::Net::StreamSocket * _sock
static void set_send_buf_sz(const unsigned sz, Poco::Net::Socket *sock)
Poco::Net::StreamSocket * _sock
virtual ~ReliableClientSession()
Dtor.
const F8MetaCntx & ctx()
Compiler generated metadata object, accessed through this function.
virtual int join(int timeoutInMs=0)
A simple xml parser with Xpath style lookup.
default_appl_ver_id get_default_appl_ver_id(const XmlElement *from) const
unsigned get_heartbeat_interval(const XmlElement *from, const unsigned def=defaults::hb_interval) const
SessionConfig(const F8MetaCntx &ctx, const std::string &conf_file, const std::string &session_name)
Ctor. Loads configuration, obtains session details, sets up logfile flags.
int hypersleep< h_milliseconds >(unsigned amt)
unsigned get_connect_timeout(const XmlElement *from, const unsigned def=defaults::connect_timeout) const
F8API void start()
Start the reader and writer threads.
unsigned get_tabsize(const XmlElement *from, const unsigned def=defaults::tabsize) const
virtual void start(bool wait, unsigned send_seqnum=0, unsigned recv_seqnum=0) override
std::unique_ptr< ServerSession< T >> ServerSession_ptr
Convenient scoped pointer for your session.
virtual T * session_ptr() override
virtual void stop() override
Stop the session. Cleanup.
virtual void start(bool wait, unsigned send_seqnum=0, unsigned recv_seqnum=0, const f8String davi=f8String())=0
virtual ~ServerSessionBase()
Dtor.
std::atomic< T > f8_atomic
Class to encapsulate a Fix8 configuration.
Poco::Net::StreamSocket accept(Poco::Net::SocketAddress &claddr)
f8_atomic< bool > _giving_up
static void set_tabsize(unsigned tabsize)
virtual ~SessionInstanceBase()
Dtor.
const XmlElement * get_session_element() const
An invalid configuration parameter was passed.
bool _reset_sequence_numbers
const std::string _session_name
unsigned get_retry_count(const XmlElement *from, const int def=defaults::login_retries) const
sender_comp_id get_sender_comp_id(const XmlElement *from) const
virtual bool has_given_up() const
ClientSessionBase(const F8MetaCntx &ctx, const std::string &conf_file, const std::string &session_name)
ServerSession(const F8MetaCntx &ctx, const std::string &conf_file, const std::string &session_name)
Ctor. Prepares session for receiving inbbound connections (acceptor).
virtual SessionInstanceBase * create_server_instance()=0
virtual void start(bool wait, unsigned send_seqnum=0, unsigned recv_seqnum=0, const f8String davi=f8String())
F8API Schedule create_login_schedule(const XmlElement *from) const
bool get_enforce_compids_flag(const XmlElement *from, const bool def=true) const
f8_thread< ReliableClientSession< T > > _thread
ReliableClientSession(const F8MetaCntx &ctx, const std::string &conf_file, const std::string &session_name)
Ctor. Prepares session for connection as an initiator.
F8API Clients create_clients(const XmlElement *from) const
Poco::Net::SocketAddress _addr
const char * what() const
std::unique_ptr< ReliableClientSession< T >> ReliableClientSession_ptr
Convenient scoped pointer for your session.
bool has_given_up() const
virtual ~ServerSession()
Dtor.
F8API Logger * create_logger(const XmlElement *from, const Logtype ltype, const SessionID *sid=nullptr) const
Poco::Net::SocketAddress _addr
target_comp_id get_target_comp_id(const XmlElement *from) const
virtual ~ClientSession()
Dtor.
Poco::Net::SocketAddress _claddr
F8API ProcessModel get_process_model(const XmlElement *from) const
bool get_always_seqnum_assign(const XmlElement *from, const bool def=false) const
std::unique_ptr< ClientSession< T >> ClientSession_ptr
Convenient scoped pointer for your session.
SessionInstanceBase()=default
Ctor. Prepares session instance with inbound connection.
Reliable Client wrapper. This client attempts to recover from disconnects and login rejects...
bool get_no_chksum_flag(const XmlElement *from, const bool def=false) const
virtual Session * session_ptr()=0
virtual void start(bool wait, unsigned send_seqnum=0, unsigned recv_seqnum=0, const f8String davi=f8String())
const XmlElement * find_group(group_types type, const std::string &tag) const