bool DynBPFFilter::block(const ComboAddress& addr, const struct timespec& until)
{
bool inserted = false;
- std::lock_guard<std::mutex> lock(d_mutex);
+ auto data = d_data.lock();
- if (d_excludedSubnets.match(addr)) {
+ if (data->d_excludedSubnets.match(addr)) {
/* do not add a block for excluded subnets */
return inserted;
}
- const container_t::iterator it = d_entries.find(addr);
- if (it != d_entries.end()) {
+ const container_t::iterator it = data->d_entries.find(addr);
+ if (it != data->d_entries.end()) {
if (it->d_until < until) {
- d_entries.replace(it, BlockEntry(addr, until));
+ data->d_entries.replace(it, BlockEntry(addr, until));
}
}
else {
- d_bpf->block(addr);
- d_entries.insert(BlockEntry(addr, until));
+ data->d_bpf->block(addr);
+ data->d_entries.insert(BlockEntry(addr, until));
inserted = true;
}
return inserted;
void DynBPFFilter::purgeExpired(const struct timespec& now)
{
- std::lock_guard<std::mutex> lock(d_mutex);
+ auto data = d_data.lock();
typedef nth_index<container_t,1>::type ordered_until;
- ordered_until& ou = get<1>(d_entries);
+ ordered_until& ou = get<1>(data->d_entries);
- for (ordered_until::iterator it=ou.begin(); it != ou.end(); ) {
+ for (ordered_until::iterator it = ou.begin(); it != ou.end(); ) {
if (it->d_until < now) {
ComboAddress addr = it->d_addr;
it = ou.erase(it);
- d_bpf->unblock(addr);
+ data->d_bpf->unblock(addr);
}
else {
break;
std::vector<std::tuple<ComboAddress, uint64_t, struct timespec> > DynBPFFilter::getAddrStats()
{
std::vector<std::tuple<ComboAddress, uint64_t, struct timespec> > result;
- if (!d_bpf) {
+ auto data = d_data.lock();
+
+ if (!data->d_bpf) {
return result;
}
- const auto& stats = d_bpf->getAddrStats();
+ const auto& stats = data->d_bpf->getAddrStats();
result.reserve(stats.size());
for (const auto& stat : stats) {
- const container_t::iterator it = d_entries.find(stat.first);
- if (it != d_entries.end()) {
+ const container_t::iterator it = data->d_entries.find(stat.first);
+ if (it != data->d_entries.end()) {
result.push_back(std::make_tuple(stat.first, stat.second, it->d_until));
}
}
return result;
}
-
class DynBPFFilter
{
public:
- DynBPFFilter(std::shared_ptr<BPFFilter>& bpf): d_bpf(bpf)
+ DynBPFFilter(std::shared_ptr<BPFFilter>& bpf)
{
+ d_data.lock()->d_bpf = bpf;
}
~DynBPFFilter()
{
}
void excludeRange(const Netmask& range)
{
- std::unique_lock<std::mutex> lock(d_mutex);
- d_excludedSubnets.addMask(range);
+ d_data.lock()->d_excludedSubnets.addMask(range);
}
void includeRange(const Netmask& range)
{
- std::unique_lock<std::mutex> lock(d_mutex);
- d_excludedSubnets.addMask(range, false);
+ d_data.lock()->d_excludedSubnets.addMask(range, false);
}
/* returns true if the addr wasn't already blocked, false otherwise */
bool block(const ComboAddress& addr, const struct timespec& until);
ordered_non_unique< member<BlockEntry,struct timespec,&BlockEntry::d_until> >
>
> container_t;
- container_t d_entries;
- std::mutex d_mutex;
- std::shared_ptr<BPFFilter> d_bpf;
- NetmaskGroup d_excludedSubnets;
+ struct Data {
+ container_t d_entries;
+ std::shared_ptr<BPFFilter> d_bpf{nullptr};
+ NetmaskGroup d_excludedSubnets;
+ };
+ LockGuarded<Data> d_data;
};