0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 18:18:56 +02:00

ircd: Various client / listener / main related.

This commit is contained in:
Jason Volk 2017-08-23 15:13:57 -06:00
parent c1ef99c0cd
commit 6e44074bad
4 changed files with 138 additions and 86 deletions

View file

@ -44,8 +44,8 @@ struct client
static list clients;
const char *const type;
list::const_iterator clit;
string_view type;
unique_const_iterator<list> clit;
std::shared_ptr<socket> sock;
virtual bool serve();

View file

@ -31,12 +31,12 @@ namespace ircd {
const auto async_timeout
{
15s
3h
};
const auto request_timeout
{
30s
300s
};
ctx::pool request
@ -159,7 +159,13 @@ ircd::write_closure(client &client)
// returns a function that can be called to send an iovector of data to a client
return [&client](const const_buffers &iov)
{
write(*client.sock, iov);
//std::cout << "<<<<" << std::endl;
//std::cout << iov << std::endl;
//std::cout << "----" << std::endl;
const auto written
{
write(*client.sock, iov)
};
};
}
@ -185,6 +191,9 @@ ircd::read_closure(client &client)
{
const char *const got(start);
read(client, start, stop);
//std::cout << ">>>>" << std::endl;
//std::cout << string_view{got, start} << std::endl;
//std::cout << "----" << std::endl;
}
catch(const boost::system::system_error &e)
{
@ -209,7 +218,7 @@ ircd::client::client(const host_port &host_port,
ircd::client::client(std::shared_ptr<socket> sock)
:type{type}
,clit{clients.emplace(end(clients), this)}
,clit{clients, clients.emplace(end(clients), this)}
,sock{std::move(sock)}
{
}
@ -217,7 +226,6 @@ ircd::client::client(std::shared_ptr<socket> sock)
ircd::client::~client()
noexcept
{
clients.erase(clit);
}
bool
@ -228,12 +236,36 @@ noexcept try
}
catch(const boost::system::system_error &e)
{
log::error("system_error: %s", e.what());
using namespace boost::system::errc;
switch(e.code().value())
{
case success:
assert(0);
return true;
case operation_canceled:
return false;
case not_connected:
return false;
default:
break;
}
log::critical("(unexpected) system_error: %s", e.what());
if(ircd::debugmode)
std::terminate();
return false;
}
catch(const std::exception &e)
{
log::error("exception: %s", e.what());
log::critical("exception: %s", e.what());
if(ircd::debugmode)
std::terminate();
return false;
}
@ -248,7 +280,7 @@ bool
ircd::client::serve()
try
{
char buffer[2048];
char buffer[8192];
parse::buffer pb{buffer, buffer + sizeof(buffer)};
parse::capstan pc{pb, read_closure(*this)}; do
{
@ -264,9 +296,12 @@ try
catch(const std::exception &e)
{
log::error("client[%s] [500 Internal Error]: %s",
string(remote_addr(*this)).c_str(),
string(remote_addr(*this)),
e.what());
if(ircd::debugmode)
throw;
return false;
}
@ -296,10 +331,10 @@ try
}
catch(const http::error &e)
{
log::debug("client[%s] http::error(%d): %s",
string(remote_addr(client)).c_str(),
int(e.code),
e.what());
log::debug("client[%s] HTTP %s %s",
string(remote_addr(client)),
e.what(),
e.content);
switch(e.code)
{
@ -314,27 +349,24 @@ void
ircd::handle_request(client &client,
parse::capstan &pc,
const http::request::head &head)
try
{
log::debug("client[%s] requesting resource \"%s\"",
string(remote_addr(client)).c_str(),
std::string(head.resource).c_str());
log::debug("client[%s] HTTP %s `%s' content-length: %zu",
string(remote_addr(client)),
head.method,
head.path,
head.content_length);
auto &resource(*resource::resources.at(head.resource));
auto &resource(ircd::resource::find(head.path));
resource(client, pc, head);
}
catch(const std::out_of_range &e)
{
throw http::error(http::code::NOT_FOUND);
}
std::shared_ptr<ircd::client>
ircd::add_client(std::shared_ptr<socket> s)
{
const auto client(std::make_shared<ircd::client>(std::move(s)));
log::info("New client[%s] on local[%s]",
string(remote_addr(*client)).c_str(),
string(local_addr(*client)).c_str());
log::debug("client[%s] CONNECTED local[%s]",
string(remote_addr(*client)),
string(local_addr(*client)));
async_recv_next(client, async_timeout);
return client;
@ -354,8 +386,9 @@ ircd::disconnect_all()
{
disconnect(*client, socket::dc::RST);
}
catch(...)
catch(const std::exception &e)
{
log::warning("Error disconnecting client @%p: %s", &client, e.what());
}
}
@ -418,6 +451,8 @@ ircd::handle_ec_success(client &client)
bool
ircd::handle_ec_eof(client &client)
{
log::debug("client[%s]: EOF", string(remote_addr(client)));
client.sock->disconnect(socket::FIN_RECV);
return false;
}
@ -425,9 +460,7 @@ bool
ircd::handle_ec_timeout(client &client)
{
auto &sock(*client.sock);
log::debug("client[%s]: disconnecting after inactivity timeout",
string(remote_addr(client)).c_str());
log::debug("client[%s]: disconnecting after inactivity timeout", string(remote_addr(client)));
sock.disconnect();
return false;
}

View file

@ -26,6 +26,7 @@
#include <ircd/socket.h>
#include <ircd/listen.h>
#include <ircd/ctx/continuation.h>
#include <ircd/js/js.h>
namespace ircd
{
@ -92,55 +93,19 @@ try
// These objects are the init()'s and fini()'s for each subsystem. Appearing here ties them
// to the main context. Initialization can also occur in ircd::init() if static initialization
// and destruction is not possible, but there is no complementary destruction up there.
ctx::ole::init _ole_;
//js::init _js_;
socket::init _sock_;
ctx::ole::init _ole_; // Thread OffLoad Engine
js::init _js_; // SpiderMonkey
socket::init _sock_; // Networking
client::init _client_;
module client_versions("client_versions.so");
module client_register("client_register.so");
module client_login("client_login.so");
// module matrix
// {
// "matrix"
// };
listener matrics
{
std::string { json::obj
{
{ "name", "Chat Matrix" },
{ "host", "127.0.0.1" },
{ "port", 6667 },
{
"ssl",
{
{
"certificate",
{
{
"file",
{
{ "pem", "/home/jason/cdc.z.cert" }
}
}
}
},
{
"private_key",
{
{
"file",
{
{ "pem", "/home/jason/cdc.z.key" }
}
}
}
}
}
}
}}
};
// This is the main program loop. Right now all it does is sleep until notified
// to shutdown, but it can do other things eventually. Other subsystems may have
// spawned their own main loops.
// This is the main program loop. Right now all it does is sleep until notified to
// break with a clean shutdown. Other subsystems may have spawned their own main loops.
log::notice("IRCd ready"); do
{
ctx::wait();

View file

@ -25,7 +25,7 @@ namespace ircd {
const size_t DEFAULT_STACK_SIZE
{
256_KiB // can be optimized
1_MiB // can be optimized
};
struct listener::acceptor
@ -110,15 +110,46 @@ try
{
log.debug("%s attempting to open listening socket", std::string(*this));
ssl.set_options
(
ssl.default_workarounds |
ssl.no_sslv2
//ssl.single_dh_use
);
ssl.set_password_callback([this]
(const auto &size, const auto &purpose)
{
log.debug("%s asking for password with purpose '%s' (size: %zu)",
std::string(*this),
purpose,
size);
return "foobar";
});
a.open(ep.protocol());
a.set_option(ip::tcp::acceptor::reuse_address(true));
a.bind(ep);
if(opts.has("ssl.certificate.file.pem"))
if(opts.has("ssl_certificate_chain_file"))
{
const std::string filename
{
unquote(opts["ssl.certificate.file.pem"])
unquote(opts["ssl_certificate_chain_file"])
};
ssl.use_certificate_chain_file(filename);
log.info("%s using certificate chain file '%s'",
std::string(*this),
filename);
}
if(opts.has("ssl_certificate_file_pem"))
{
const std::string filename
{
unquote(opts["ssl_certificate_file_pem"])
};
ssl.use_certificate_file(filename, asio::ssl::context::pem);
@ -127,11 +158,11 @@ try
filename);
}
if(opts.has("ssl.private_key.file.pem"))
if(opts.has("ssl_private_key_file_pem"))
{
const std::string filename
{
unquote(opts["ssl.private_key.file.pem"])
unquote(opts["ssl_private_key_file_pem"])
};
ssl.use_private_key_file(filename, asio::ssl::context::pem);
@ -140,6 +171,19 @@ try
filename);
}
if(opts.has("ssl_tmp_dh_file"))
{
const std::string filename
{
unquote(opts["ssl_tmp_dh_file"])
};
ssl.use_tmp_dh_file(filename);
log.info("%s using tmp dh file '%s'",
std::string(*this),
filename);
}
a.listen(backlog);
// Allow main() to run and print its log message
@ -172,7 +216,9 @@ catch(const ircd::ctx::interrupted &e)
}
catch(const std::exception &e)
{
log.error("%s %s", std::string(*this), e);
log.critical("%s %s", std::string(*this), e.what());
if(ircd::debugmode)
throw;
}
bool
@ -180,8 +226,14 @@ ircd::listener::acceptor::accept()
try
{
auto sock(std::make_shared<ircd::socket>(ssl));
a.async_accept(sock->ssl.lowest_layer(), yield(continuation()));
//log.debug("%s listening with socket(%p)", std::string(*this), sock.get());
a.async_accept(sock->sd, yield(continuation()));
//log.debug("%s accepted %s", std::string(*this), string(sock->remote()));
sock->ssl.async_handshake(socket::handshake_type::server, yield(continuation()));
//log.debug("%s SSL shooks hands with %s", std::string(*this), string(sock->remote()));
add_client(std::move(sock));
return true;
}
@ -193,12 +245,14 @@ catch(const boost::system::system_error &e)
case success: return true;
case operation_canceled: return false;
default: throw;
default:
log.warning("%s: in accept(): %s", std::string(*this), e.what());
return true;
}
}
catch(const std::exception &e)
{
log.error("%s: in accept(): %s", std::string(*this), e);
log.error("%s: in accept(): %s", std::string(*this), e.what());
return true;
}