2019-09-03 15:56:56 +00:00
|
|
|
#ifndef LLARP_NET_IP_RANGE_MAP_HPP
|
|
|
|
#define LLARP_NET_IP_RANGE_MAP_HPP
|
|
|
|
|
2020-05-20 19:14:05 +00:00
|
|
|
#include <net/ip_range.hpp>
|
2020-09-03 22:22:22 +00:00
|
|
|
#include <util/status.hpp>
|
2020-06-24 13:24:07 +00:00
|
|
|
#include <list>
|
2019-09-03 15:56:56 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace net
|
|
|
|
{
|
|
|
|
/// a container that maps an ip range to a value that allows you to lookup
|
|
|
|
/// key by range hit
|
|
|
|
/// TODO: do some kind of magic shit to ensure near constant time for
|
|
|
|
/// lookups
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Value_t>
|
2019-09-03 15:56:56 +00:00
|
|
|
struct IPRangeMap
|
|
|
|
{
|
|
|
|
using Range_t = IPRange;
|
2020-04-07 18:38:56 +00:00
|
|
|
using IP_t = Range_t::Addr_t;
|
2019-09-03 15:56:56 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
using Entry_t = std::pair<Range_t, Value_t>;
|
2020-06-24 13:24:07 +00:00
|
|
|
using Container_t = std::list<Entry_t>;
|
2019-09-03 15:56:56 +00:00
|
|
|
|
|
|
|
/// get a set of all values
|
2020-04-07 18:38:56 +00:00
|
|
|
std::set<Value_t>
|
2019-09-03 15:56:56 +00:00
|
|
|
Values() const
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
std::set<Value_t> all;
|
|
|
|
for (const auto& entry : m_Entries)
|
2019-09-03 15:56:56 +00:00
|
|
|
all.insert(entry.second);
|
|
|
|
return all;
|
|
|
|
}
|
|
|
|
|
2020-09-24 00:28:38 +00:00
|
|
|
bool
|
|
|
|
Empty() const
|
|
|
|
{
|
|
|
|
return m_Entries.empty();
|
|
|
|
}
|
|
|
|
|
2020-06-24 13:24:07 +00:00
|
|
|
bool
|
|
|
|
ContainsValue(const Value_t& val) const
|
|
|
|
{
|
|
|
|
for (const auto& entry : m_Entries)
|
|
|
|
{
|
|
|
|
if (entry.second == val)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-09-03 15:56:56 +00:00
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
ForEachValue(std::function<void(const Value_t&)> functor) const
|
2019-09-03 15:56:56 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
for (const auto& entry : m_Entries)
|
2019-09-03 15:56:56 +00:00
|
|
|
functor(entry.second);
|
|
|
|
}
|
|
|
|
|
2020-06-24 13:24:07 +00:00
|
|
|
template <typename Visit_t>
|
|
|
|
void
|
|
|
|
ForEachEntry(Visit_t visit) const
|
|
|
|
{
|
2020-07-01 14:14:45 +00:00
|
|
|
for (const auto& [range, value] : m_Entries)
|
|
|
|
visit(range, value);
|
2020-06-24 13:24:07 +00:00
|
|
|
}
|
|
|
|
|
2019-09-12 14:34:27 +00:00
|
|
|
/// convert all values into type T using a transformer
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T, typename Transformer>
|
|
|
|
std::set<T>
|
2019-09-03 15:56:56 +00:00
|
|
|
TransformValues(Transformer transform) const
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
std::set<T> transformed;
|
|
|
|
for (const auto& entry : m_Entries)
|
2019-09-03 15:56:56 +00:00
|
|
|
{
|
|
|
|
T val = transform(entry.second);
|
|
|
|
transformed.insert(std::move(val));
|
|
|
|
}
|
|
|
|
return transformed;
|
|
|
|
}
|
|
|
|
|
2020-10-21 09:39:01 +00:00
|
|
|
// get a value for this exact range
|
|
|
|
std::optional<Value_t>
|
|
|
|
GetExact(Range_t range) const
|
|
|
|
{
|
|
|
|
for (const auto& [r, value] : m_Entries)
|
|
|
|
{
|
|
|
|
if (r == range)
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
2019-09-03 15:56:56 +00:00
|
|
|
/// return a set of all values who's range contains this IP
|
2020-04-07 18:38:56 +00:00
|
|
|
std::set<Value_t>
|
|
|
|
FindAll(const IP_t& addr) const
|
2019-09-03 15:56:56 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
std::set<Value_t> found;
|
|
|
|
for (const auto& entry : m_Entries)
|
2019-09-03 15:56:56 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (entry.first.Contains(addr))
|
2019-09-03 15:56:56 +00:00
|
|
|
found.insert(entry.second);
|
|
|
|
}
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CompareEntry
|
|
|
|
{
|
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
operator()(const Entry_t& left, const Entry_t& right) const
|
2019-09-03 15:56:56 +00:00
|
|
|
{
|
|
|
|
return left.first < right.first;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
Insert(const Range_t& addr, const Value_t& val)
|
2019-09-03 15:56:56 +00:00
|
|
|
{
|
|
|
|
m_Entries.emplace_front(addr, val);
|
|
|
|
m_Entries.sort(CompareEntry{});
|
|
|
|
}
|
|
|
|
|
2020-06-24 13:24:07 +00:00
|
|
|
template <typename Visit_t>
|
|
|
|
void
|
|
|
|
RemoveIf(Visit_t visit)
|
|
|
|
{
|
|
|
|
auto itr = m_Entries.begin();
|
|
|
|
while (itr != m_Entries.end())
|
|
|
|
{
|
|
|
|
if (visit(*itr))
|
|
|
|
itr = m_Entries.erase(itr);
|
|
|
|
else
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 22:22:22 +00:00
|
|
|
util::StatusObject
|
|
|
|
ExtractStatus() const
|
|
|
|
{
|
|
|
|
util::StatusObject obj;
|
|
|
|
for (const auto& [range, value] : m_Entries)
|
|
|
|
{
|
|
|
|
obj[range.ToString()] = value.ToString();
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2019-09-03 15:56:56 +00:00
|
|
|
private:
|
|
|
|
Container_t m_Entries;
|
|
|
|
};
|
|
|
|
} // namespace net
|
|
|
|
} // namespace llarp
|
|
|
|
|
2020-05-20 19:14:05 +00:00
|
|
|
#endif
|