3 #include <boost/format.hpp>
4 #include <boost/bind.hpp>
5 #include <boost/filesystem/path.hpp>
6 #include <loki/ScopeGuard.h>
7 #include <Scorpion/BIO.h>
9 #include <openssl/bio.h>
10 #include <openssl/ssl.h>
12 #include "Connection.h"
13 #include "Private/ConnectionHandler.h"
14 #include "Handlers/NewConnectionHandler.h"
15 #include "Exceptions/Connection/UnusableListener.h"
19 Listener::Listener(Details::Address local_address
, boost::uint16_t local_port
)
20 : bio_(createBIO_(constructLocalAddress_(local_address
, local_port
))),
21 new_connection_handler_(0)
24 Listener::Listener(const Scorpion::Context
& security_context
, Details::Address local_address
, boost::uint16_t local_port
)
25 : security_context_(security_context
),
26 bio_(createSSLBIO_(constructLocalAddress_(local_address
, local_port
))),
27 new_connection_handler_(0)
32 clearNewConnectionHandler();
35 boost::shared_ptr
< Connection
> Listener::accept()
38 throw Exceptions::Connection::UnusableListener();
41 return boost::shared_ptr
< Connection
>(new Connection(bio_
->accept()));
44 void Listener::abort()
47 throw Exceptions::Connection::UnusableListener();
53 void Listener::setNewConnectionHandler(Handlers::NewConnectionHandler
& handler
)
55 new_connection_handler_
= &handler
;
57 throw Exceptions::Connection::UnusableListener();
60 Private::ConnectionHandler::getInstance().attach(bio_
->getFD(), boost::bind(&Listener::onNewConnection_
, this));
63 void Listener::clearNewConnectionHandler()
65 if (new_connection_handler_
)
68 throw Exceptions::Connection::UnusableListener();
71 Private::ConnectionHandler::getInstance().detach(bio_
->getFD());
72 new_connection_handler_
= 0;
75 { /* nothing to clear */ }
78 std::string
Listener::constructLocalAddress_(Details::Address local_address
, boost::uint16_t local_port
)
80 std::string local_address_s
;
81 if (local_address
.u_
.u32_
== 0)
82 local_address_s
= "*";
85 boost::format
fmt("%1%.%2%.%3%.%4%");
86 fmt
% (unsigned int)local_address
.u_
.u8_
[0]
87 % (unsigned int)local_address
.u_
.u8_
[1]
88 % (unsigned int)local_address
.u_
.u8_
[2]
89 % (unsigned int)local_address
.u_
.u8_
[3]
91 local_address_s
= fmt
.str();
93 boost::format
fmt("%1%:%2%");
94 fmt
% local_address_s
;
103 Scorpion::BIO
* Listener::createBIO_(const std::string
& local_address
)
105 return Scorpion::createAcceptBIO(local_address
, Scorpion::BIO::non_blocking__
);
108 Scorpion::BIO
* Listener::createSSLBIO_(const std::string
& local_address
)
110 return Scorpion::createSSLAcceptBIO(local_address
, security_context_
, Scorpion::BIO::auto_retry__
| Scorpion::BIO::non_blocking__
);
113 void Listener::onNewConnection_()
115 if (new_connection_handler_
)
116 (*new_connection_handler_
)(accept());
118 { /* no new connection handler set */ }