lokinet/llarp/util/decaying_hashtable.hpp
Jeff 21930cf667
LNS (#1342)
* initial relay side lns

* fix typo

* add reserved names and refactor test for dns

* lns name decryption

* all wired up (allegedly)

* refact to use service::EncryptedName for LNS responses to include nonce with ciphertext

* fully rwemove tag_lookup_job

* replace lns cache with DecayingHashTable

* check for lns name validity against the following rules:

* not localhost.loki, loki.loki, or snode.loki

* if it contains no dash then max 32 characters long, not including the .loki tld (and also assuming a leading subdomain has been stripped)

* These are from general DNS requirements, and also enforced in
registrations:

* Must be all [A-Za-z0-9-]. (A-Z will be lower-cased by the RPC call).

* cannot start or end with a -

* max 63 characters long if it does contain a dash

* cannot contain -- in the third and fourth characters unless it starts with xn--

* handle timeout in name lookup job by calling the right handler with std::nullopt
2020-09-17 15:18:08 -04:00

68 lines
1.5 KiB
C++

#pragma once
#include <util/time.hpp>
#include <unordered_map>
namespace llarp::util
{
template <typename Key_t, typename Value_t, typename Hash_t = typename Key_t::Hash>
struct DecayingHashTable
{
DecayingHashTable(std::chrono::milliseconds cacheInterval = 1h) : m_CacheInterval(cacheInterval)
{
}
void
Decay(llarp_time_t now)
{
EraseIf([&](const auto& item) { return item.second.second + m_CacheInterval <= now; });
}
bool
Has(const Key_t& k) const
{
return m_Values.find(k) != m_Values.end();
}
/// return true if inserted
/// return false if not inserted
bool
Put(Key_t key, Value_t value, llarp_time_t now = 0s)
{
if (now == 0s)
now = llarp::time_now_ms();
return m_Values.try_emplace(std::move(key), std::make_pair(std::move(value), now)).second;
}
std::optional<Value_t>
Get(Key_t k) const
{
const auto itr = m_Values.find(k);
if (itr == m_Values.end())
return std::nullopt;
return itr->second.first;
}
private:
template <typename Predicate_t>
void
EraseIf(Predicate_t pred)
{
for (auto i = m_Values.begin(), last = m_Values.end(); i != last;)
{
if (pred(*i))
{
i = m_Values.erase(i);
}
else
{
++i;
}
}
}
llarp_time_t m_CacheInterval;
std::unordered_map<Key_t, std::pair<Value_t, llarp_time_t>, Hash_t> m_Values;
};
} // namespace llarp::util