0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-27 11:18:51 +02:00

ircd::client: Improve the acceptance pattern; condition on conf limits.

This commit is contained in:
Jason Volk 2018-09-01 22:03:25 -07:00
parent 384f5917d0
commit 168b82a972
3 changed files with 81 additions and 47 deletions

View file

@ -18,8 +18,6 @@ namespace ircd
//TODO: want to upgrade
char *read(client &, char *&start, char *const &stop);
parse::read_closure read_closure(client &);
std::shared_ptr<client> add_client(std::shared_ptr<socket>); // Creates a client.
}
/// Remote party connecting to our daemon to make requests.
@ -37,7 +35,7 @@ struct ircd::client
static ctx::pool pool;
static uint64_t ctr; // monotonic
static size_t count(const net::ipport &remote);
static size_t count(net::ipport remote);
static void interrupt_all();
static void close_all();
static void wait_all();
@ -102,6 +100,8 @@ struct ircd::client::settings
{
static ircd::conf::item<size_t> stack_size;
static ircd::conf::item<size_t> pool_size;
static ircd::conf::item<size_t> max_client;
static ircd::conf::item<size_t> max_client_per_peer;
};
struct ircd::client::init

View file

@ -13,14 +13,26 @@
namespace ircd
{
ctx::dock dock;
template<class... args> std::shared_ptr<client> make_client(args&&...);
}
//
// client::settings conf::item's
//
ircd::conf::item<size_t>
ircd::client::settings::max_client
{
{ "name", "ircd.client.max_client" },
{ "default", 16384L },
};
ircd::conf::item<size_t>
ircd::client::settings::max_client_per_peer
{
{ "name", "ircd.client.max_client_per_peer" },
{ "default", 24L },
};
ircd::conf::item<size_t>
ircd::client::settings::stack_size
{
@ -231,8 +243,9 @@ ircd::client::wait_all()
}
size_t
ircd::client::count(const net::ipport &remote)
ircd::client::count(net::ipport remote)
{
std::get<remote.PORT>(remote) = 0;
return client::map.count(remote);
}
@ -267,38 +280,6 @@ ircd::read(client &client,
return base;
}
std::shared_ptr<ircd::client>
ircd::add_client(std::shared_ptr<socket> s)
{
if(unlikely(ircd::runlevel != ircd::runlevel::RUN))
{
log::dwarning
{
"Refusing to add new client from %s in runlevel %s",
string(remote_ipport(*s)),
reflect(ircd::runlevel)
};
net::close(*s, net::dc::RST, net::close_ignore);
return {};
}
const auto client
{
make_client(std::move(s))
};
client->async();
return client;
}
template<class... args>
std::shared_ptr<ircd::client>
ircd::make_client(args&&... a)
{
return std::make_shared<client>(std::forward<args>(a)...);
}
ircd::ipport
ircd::local(const client &client)
{
@ -593,10 +574,15 @@ ircd::handle_ec_default(client &client,
//
ircd::client::client(std::shared_ptr<socket> sock)
:instance_multimap
:instance_multimap{[&sock]
() -> net::ipport
{
remote_ipport(*sock)
}
assert(bool(sock));
auto remote(remote_ipport(*sock));
assert(bool(remote));
std::get<remote.PORT>(remote) = 0;
return remote;
}()}
,head_buffer
{
conf->header_max_size

View file

@ -150,6 +150,59 @@ load_listener(const m::event &event)
return load_listener(name, opts);
}
void
_listener_action(const std::shared_ptr<socket> &sock)
{
const auto client
{
std::make_shared<ircd::client>(sock)
};
client->async();
}
bool
_listener_proffer(const net::ipport &ipport)
{
if(unlikely(ircd::runlevel != ircd::runlevel::RUN))
{
log::dwarning
{
"Refusing to add new client from %s in runlevel %s",
string(ipport),
reflect(ircd::runlevel)
};
return false;
}
if(unlikely(client::map.size() >= size_t(client::settings::max_client)))
{
log::warning
{
"Refusing to add new client from %s because maximum of %zu reached",
string(ipport),
size_t(client::settings::max_client)
};
return false;
}
if(client::count(ipport) >= size_t(client::settings::max_client_per_peer))
{
log::dwarning
{
"Refusing to add new client from %s: maximum of %zu connections for peer.",
string(ipport),
size_t(client::settings::max_client_per_peer)
};
return false;
}
return true;
}
bool
load_listener(const string_view &name,
const json::object &opts)
@ -161,12 +214,7 @@ try
"A listener with the name '%s' is already loaded", name
};
listeners.emplace_back(name, opts, []
(const auto &sock)
{
ircd::add_client(sock);
});
listeners.emplace_back(name, opts, _listener_action, _listener_proffer);
return true;
}
catch(const std::exception &e)