Improve corebill and graylisting. (#154)

This commit is contained in:
Savinda Senevirathne
2020-11-19 08:40:15 +05:30
committed by GitHub
parent f475dcb1fb
commit 9160b2ee15
10 changed files with 129 additions and 75 deletions

View File

@@ -6,82 +6,87 @@
namespace corebill
{
// How many violations can occur for a host before being escalated.
constexpr uint32_t VIOLATION_THRESHOLD = 10;
// How many violations can occur for a host before being escalated.
constexpr uint32_t VIOLATION_THRESHOLD = 10;
// Violation cooldown interval.
constexpr uint32_t VIOLATION_REFRESH_INTERVAL = 600 * 1000; // 10 minutes
// Violation cooldown interval.
constexpr uint32_t VIOLATION_REFRESH_INTERVAL = 600 * 1000; // 10 minutes
// Keeps track of violation count against offending hosts.
std::unordered_map<std::string, violation_stat> violation_counter;
// Keeps track of violation count against offending hosts.
std::unordered_map<std::string, violation_stat> violation_counter;
// Keeps the graylisted hosts.
util::ttl_set graylist;
// Graylist mutex.
std::mutex graylist_mutex;
// Keeps the whitelisted hosts who would be ignored in all violation tracking.
std::unordered_set<std::string> whitelist;
// Keeps the graylisted hosts.
util::ttl_set graylist;
/**
// Keeps the whitelisted hosts who would be ignored in all violation tracking.
std::unordered_set<std::string> whitelist;
/**
* Report a violation. Violation means a force disconnection of a socket due to some threshold exceeding.
*/
void report_violation(const std::string host)
{
if (whitelist.find(host) != whitelist.end()) // Is in whitelist
void report_violation(const std::string host)
{
LOG_DEBUG << host << " is whitelisted. Ignoring the violation.";
return;
}
violation_stat &stat = violation_counter[host];
const uint64_t time_now = util::get_epoch_milliseconds();
stat.counter++;
if (stat.timestamp == 0)
{
// Reset counter timestamp.
stat.timestamp = time_now;
}
else
{
// Check whether we have exceeded the threshold within the monitering interval.
const uint64_t elapsed_time = time_now - stat.timestamp;
if (elapsed_time <= VIOLATION_REFRESH_INTERVAL && stat.counter > VIOLATION_THRESHOLD)
if (whitelist.find(host) != whitelist.end()) // Is in whitelist
{
// IP exceeded violation threshold.
stat.timestamp = 0;
stat.counter = 0;
graylist.emplace(host, VIOLATION_REFRESH_INTERVAL);
LOG_WARNING << host << " placed on graylist.";
LOG_DEBUG << host << " is whitelisted. Ignoring the violation.";
return;
}
else if (elapsed_time > VIOLATION_REFRESH_INTERVAL)
violation_stat &stat = violation_counter[host];
const uint64_t time_now = util::get_epoch_milliseconds();
stat.counter++;
if (stat.timestamp == 0)
{
// Start the counter fresh.
// Reset counter timestamp.
stat.timestamp = time_now;
stat.counter = 1;
}
else
{
// Check whether we have exceeded the threshold within the monitering interval.
const uint64_t elapsed_time = time_now - stat.timestamp;
if (elapsed_time <= VIOLATION_REFRESH_INTERVAL && stat.counter > VIOLATION_THRESHOLD)
{
// IP exceeded violation threshold.
stat.timestamp = 0;
stat.counter = 0;
std::scoped_lock<std::mutex> gray_list_lock(graylist_mutex);
graylist.emplace(host, VIOLATION_REFRESH_INTERVAL);
LOG_WARNING << host << " placed on graylist.";
}
else if (elapsed_time > VIOLATION_REFRESH_INTERVAL)
{
// Start the counter fresh.
stat.timestamp = time_now;
stat.counter = 1;
}
}
}
}
void add_to_whitelist(const std::string host)
{
// Add to whitelist and remove from all other offender lists.
whitelist.emplace(host);
graylist.erase(host);
violation_counter.erase(host);
}
void add_to_whitelist(const std::string host)
{
// Add to whitelist and remove from all other offender lists.
whitelist.emplace(host);
std::scoped_lock<std::mutex> gray_list_lock(graylist_mutex);
graylist.erase(host);
violation_counter.erase(host);
}
void remove_from_whitelist(const std::string host)
{
whitelist.erase(host);
}
void remove_from_whitelist(const std::string host)
{
whitelist.erase(host);
}
bool is_banned(const std::string &host)
{
return graylist.exists(host);
}
bool is_banned(const std::string &host)
{
std::scoped_lock<std::mutex> gray_list_lock(graylist_mutex);
return graylist.exists(host);
}
} // namespace corebill