mirror of
https://github.com/matrix-construct/construct
synced 2025-02-18 01:30:12 +01:00
ircd: Various client / listener / main related.
This commit is contained in:
parent
c1ef99c0cd
commit
6e44074bad
4 changed files with 138 additions and 86 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
57
ircd/ircd.cc
57
ircd/ircd.cc
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue