summaryrefslogtreecommitdiffstats
path: root/src/Net/Listener.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Net/Listener.cpp')
-rw-r--r--src/Net/Listener.cpp95
1 files changed, 31 insertions, 64 deletions
diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp
index 11cbaf5..6f49a74 100644
--- a/src/Net/Listener.cpp
+++ b/src/Net/Listener.cpp
@@ -18,8 +18,6 @@
*/
#include "Listener.h"
-#include "FdManager.h"
-#include "ServerConnection.h"
#include <Common/Logger.h>
@@ -30,26 +28,29 @@
namespace Mad {
namespace Net {
-void Listener::acceptHandler(int) {
- int sd;
- struct sockaddr_in sa;
- socklen_t addrlen = sizeof(sa);
+void Listener::handleAccept(const boost::system::error_code &error, boost::shared_ptr<ServerConnection> con) {
+ if(error)
+ return;
+
+ {
+ boost::lock_guard<boost::shared_mutex> lock(con->connectionLock);
+ con->state = ServerConnection::CONNECT;
- while((sd = accept(sock, (struct sockaddr*)&sa, &addrlen)) >= 0) {
- ServerConnection *con = new ServerConnection(sd, IPAddress(sa), dh_params, x905CertFile, x905KeyFile);
- boost::signals::connection con1 = con->signalConnected().connect(boost::bind(&Listener::connectHandler, this, con));
- boost::signals::connection con2 = con->signalDisconnected().connect(boost::bind(&Listener::disconnectHandler, this, con));
+ boost::signals::connection con1 = con->signalConnected().connect(boost::bind(&Listener::handleConnect, this, con));
+ boost::signals::connection con2 = con->signalDisconnected().connect(boost::bind(&Listener::handleDisconnect, this, con));
connections.insert(std::make_pair(con, std::make_pair(con1, con2)));
- addrlen = sizeof(sa);
+ con->socket.async_handshake(boost::asio::ssl::stream_base::server, boost::bind(&ServerConnection::handleHandshake, con, boost::asio::placeholders::error));
}
-}
+ con.reset(new ServerConnection(sslContext));
+ acceptor.async_accept(con->socket.lowest_layer(), boost::bind(&Listener::handleAccept, this, boost::asio::placeholders::error, con));
+}
-void Listener::connectHandler(ServerConnection *con) {
- std::map<ServerConnection*, std::pair<boost::signals::connection, boost::signals::connection> >::iterator it = connections.find(con);
+void Listener::handleConnect(boost::shared_ptr<ServerConnection> con) {
+ std::map<boost::shared_ptr<ServerConnection>, std::pair<boost::signals::connection, boost::signals::connection> >::iterator it = connections.find(con);
if(it == connections.end())
return;
@@ -62,67 +63,33 @@ void Listener::connectHandler(ServerConnection *con) {
signal(con);
}
-void Listener::disconnectHandler(ServerConnection *con) {
- std::map<ServerConnection*, std::pair<boost::signals::connection, boost::signals::connection> >::iterator it = connections.find(con);
-
- if(it == connections.end())
- return;
-
- delete it->first;
- connections.erase(it);
+void Listener::handleDisconnect(boost::shared_ptr<ServerConnection> con) {
+ connections.erase(con);
}
-Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0) throw(Exception)
-: x905CertFile(x905CertFile0), x905KeyFile(x905KeyFile0), address(address0) {
- gnutls_dh_params_init(&dh_params);
- gnutls_dh_params_generate2(dh_params, 768);
+Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0,
+ const boost::asio::ip::tcp::endpoint &address0) throw(Exception)
+: x905CertFile(x905CertFile0), x905KeyFile(x905KeyFile0), address(address0), acceptor(Connection::ioService, address),
+sslContext(Connection::ioService, boost::asio::ssl::context::sslv23)
+{
+ sslContext.set_options(boost::asio::ssl::context::default_workarounds
+ | boost::asio::ssl::context::no_sslv2
+ | boost::asio::ssl::context::single_dh_use);
+ sslContext.use_certificate_chain_file(x905CertFile0);
+ sslContext.use_private_key_file(x905KeyFile0, boost::asio::ssl::context::pem);
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if(sock < 0)
- throw Exception("socket()", Exception::INTERNAL_ERRNO, errno);
- // Set non-blocking flag
- int flags = fcntl(sock, F_GETFL, 0);
-
- if(flags < 0) {
- close(sock);
-
- throw Exception("fcntl()", Exception::INTERNAL_ERRNO, errno);
- }
-
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-
- // Don't linger
- struct linger linger = {1, 0};
- setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
-
- if(bind(sock, address.getSockAddr(), address.getSockAddrLength()) < 0) {
- close(sock);
-
- throw Exception("bind()", Exception::INTERNAL_ERRNO, errno);
- }
-
- if(listen(sock, 64) < 0) {
- close(sock);
-
- throw Exception("listen()", Exception::INTERNAL_ERRNO, errno);
- }
-
- FdManager::get()->registerFd(sock, boost::bind(&Listener::acceptHandler, this, _1), POLLIN);
+ boost::shared_ptr<ServerConnection> con(new ServerConnection(sslContext));
+ acceptor.async_accept(con->socket.lowest_layer(), boost::bind(&Listener::handleAccept, this, boost::asio::placeholders::error, con));
}
Listener::~Listener() {
- for(std::map<ServerConnection*,std::pair<boost::signals::connection, boost::signals::connection> >::iterator con = connections.begin(); con != connections.end(); ++con) {
+ for(std::map<boost::shared_ptr<ServerConnection>,std::pair<boost::signals::connection, boost::signals::connection> >::iterator con = connections.begin(); con != connections.end(); ++con) {
con->first->disconnect();
- delete con->first;
+ // TODO wait...
}
-
- shutdown(sock, SHUT_RDWR);
- close(sock);
-
- gnutls_dh_params_deinit(dh_params);
}
}