mirror of https://github.com/sipwise/sems.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
2.7 KiB
129 lines
2.7 KiB
#include "tr_blacklist.h"
|
|
#include <string.h>
|
|
|
|
#include "hash.h"
|
|
|
|
#define BLACKLIST_HT_POWER 6
|
|
#define BLACKLIST_HT_SIZE (1 << BLACKLIST_HT_POWER)
|
|
#define BLACKLIST_HT_MASK (BLACKLIST_HT_SIZE - 1)
|
|
|
|
#define DBG_BL INFO
|
|
|
|
bl_addr::bl_addr()
|
|
{
|
|
ss_family = AF_INET;
|
|
}
|
|
|
|
bl_addr::bl_addr(const bl_addr& addr)
|
|
{
|
|
memcpy(this,&addr,SA_len(&addr));
|
|
}
|
|
|
|
bl_addr::bl_addr(const sockaddr_storage* p_addr)
|
|
{
|
|
memcpy((sockaddr_storage*)this,p_addr,SA_len(p_addr));
|
|
}
|
|
|
|
unsigned int bl_addr::hash()
|
|
{
|
|
return hashlittle((sockaddr_storage*)this, SA_len(this), 0)
|
|
& BLACKLIST_HT_MASK;
|
|
}
|
|
|
|
bool bl_addr_less::operator() (const bl_addr& l, const bl_addr& r) const
|
|
{
|
|
if(l.ss_family != r.ss_family)
|
|
return l.ss_family < r.ss_family;
|
|
|
|
return memcmp(&l,&r,SA_len(&l));
|
|
}
|
|
|
|
void bl_timer::fire()
|
|
{
|
|
DBG_BL("blacklist: %s/%i expired",
|
|
am_inet_ntop(&addr).c_str(),am_get_port(&addr));
|
|
tr_blacklist::instance()->remove(&addr);
|
|
}
|
|
|
|
bool blacklist_bucket::insert(const bl_addr& addr, uint64_t duration /* ms */,
|
|
const char* reason)
|
|
{
|
|
wheeltimer* wt = wheeltimer::instance();
|
|
uint64_t expires = duration * 1000;
|
|
|
|
bl_timer* t = new bl_timer(addr);
|
|
bl_entry* bl_e = new bl_entry(t);
|
|
|
|
if(!bl_bucket_base::insert(addr,bl_e)) {
|
|
delete t;
|
|
return false;
|
|
}
|
|
|
|
DBG_BL("blacklist: added %s/%i (%s/TTL=%.1fs)",
|
|
am_inet_ntop(&addr).c_str(),am_get_port(&addr),
|
|
reason,(float)duration/1000.0);
|
|
|
|
wt->insert_timer(t, expires);
|
|
return true;
|
|
}
|
|
|
|
bool blacklist_bucket::remove(const bl_addr& addr)
|
|
{
|
|
value_map::iterator it = find(addr);
|
|
|
|
if(it != elmts.end()){
|
|
bl_entry* v = it->second;
|
|
wheeltimer::instance()->remove_timer(v->t);
|
|
elmts.erase(it);
|
|
allocator().dispose(v);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
_tr_blacklist::_tr_blacklist()
|
|
: blacklist_ht(BLACKLIST_HT_SIZE)
|
|
{
|
|
}
|
|
|
|
_tr_blacklist::~_tr_blacklist()
|
|
{
|
|
}
|
|
|
|
bool _tr_blacklist::exist(const sockaddr_storage* addr)
|
|
{
|
|
bool res;
|
|
blacklist_bucket* bucket = get_bucket(hashlittle(addr, SA_len(addr), 0)
|
|
& BLACKLIST_HT_MASK);
|
|
bucket->lock();
|
|
res = bucket->exist(*(const bl_addr*)addr);
|
|
bucket->unlock();
|
|
|
|
return res;
|
|
}
|
|
|
|
void _tr_blacklist::insert(const sockaddr_storage* addr, unsigned int duration,
|
|
const char* reason)
|
|
{
|
|
if(!duration)
|
|
return;
|
|
|
|
blacklist_bucket* bucket = get_bucket(hashlittle(addr, SA_len(addr), 0)
|
|
& BLACKLIST_HT_MASK);
|
|
bucket->lock();
|
|
if(!bucket->exist(*(const bl_addr*)addr)) {
|
|
bucket->insert(*(const bl_addr*)addr,duration,reason);
|
|
}
|
|
bucket->unlock();
|
|
}
|
|
|
|
void _tr_blacklist::remove(const sockaddr_storage* addr)
|
|
{
|
|
blacklist_bucket* bucket = get_bucket(hashlittle(addr, SA_len(addr), 0)
|
|
& BLACKLIST_HT_MASK);
|
|
bucket->lock();
|
|
bucket->remove(*(const bl_addr*)addr);
|
|
bucket->unlock();
|
|
}
|