From 7f336200ea4e2f1fe6c5bd3a013e99d7025d816a Mon Sep 17 00:00:00 2001 From: Jason Volk <jason@zemos.net> Date: Fri, 9 Mar 2018 07:42:28 -0800 Subject: [PATCH] ircd::server: Check and clear peer error after timeout. --- include/ircd/server/peer.h | 2 ++ ircd/server.cc | 30 ++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/ircd/server/peer.h b/include/ircd/server/peer.h index 19d674d55..cb862078c 100644 --- a/include/ircd/server/peer.h +++ b/include/ircd/server/peer.h @@ -20,6 +20,7 @@ struct ircd::server::peer static conf::item<size_t> link_min_default; static conf::item<size_t> link_max_default; + static conf::item<seconds> error_clear_default; net::remote remote; std::list<link> links; @@ -84,6 +85,7 @@ struct ircd::server::peer string_view err_msg() const; template<class... A> void err_set(A&&...); void err_clear(); + bool err_check(); // control panel void interrupt(); diff --git a/ircd/server.cc b/ircd/server.cc index 3dd5e64f1..c0695afac 100644 --- a/ircd/server.cc +++ b/ircd/server.cc @@ -363,14 +363,40 @@ const return bool(e); } +decltype(ircd::server::peer::error_clear_default) +ircd::server::peer::error_clear_default +{ + { "name", "ircd.server.peer.error.clear_default" }, + { "default", 305L } +}; + +bool +ircd::server::peer::err_check() +{ + if(!ready) + return false; + + if(!e) + return true; + + //TODO: The specific error type should be switched and finer + //TODO: timeouts should be used depending on the error: i.e + //TODO: NXDOMAIN vs. temporary conn timeout, etc. + if(e->etime + seconds(error_clear_default) > now<steady_point>()) + return false; + + err_clear(); + return true; +} + void ircd::server::peer::submit(request &request) try { - if(unlikely(!ready || !server::ready)) + if(!err_check() || unlikely(!server::ready)) throw unavailable { - "Peer is unable to take any requests." + "Peer is unable to take any requests: %s", err_msg() }; link *const ret