});
#endif /* HAVE_CDB */
+ g_lua.registerFunction<std::string(std::shared_ptr<KeyValueStore>::*)(const std::string&)>("lookup", [](std::shared_ptr<KeyValueStore>& kvs, const std::string& keyStr) {
+ std::string result;
+ if (!kvs) {
+ return result;
+ }
+
+ try {
+ ComboAddress ca(keyStr);
+ KeyValueLookupKeySourceIP lookup;
+ for (const auto& key : lookup.getKeys(ca)) {
+ if (kvs->getValue(key, result)) {
+ return result;
+ }
+ }
+ }
+ catch(const std::exception& e) {
+ /* not a valid address, treating it as a DNSName */
+ try {
+ DNSName dn(keyStr);
+ KeyValueLookupKeyQName lookup;
+ for (const auto& key : lookup.getKeys(dn)) {
+ if (kvs->getValue(key, result)) {
+ return result;
+ }
+ }
+ }
+ catch (const std::exception& e) {
+ /* not a valid name, trying to pass it as it is */
+ kvs->getValue(keyStr, result);
+ }
+ }
+
+ return result;
+ });
+
+ g_lua.registerFunction<std::string(std::shared_ptr<KeyValueStore>::*)(const std::string&)>("lookupSuffix", [](std::shared_ptr<KeyValueStore>& kvs, const std::string& keyStr) {
+ std::string result;
+ if (!kvs) {
+ return result;
+ }
+
+ DNSName dn(keyStr);
+ KeyValueLookupKeySuffix lookup;
+ for (const auto& key : lookup.getKeys(dn)) {
+ if (kvs->getValue(key, result)) {
+ return result;
+ }
+ }
+
+ return result;
+ });
+
+ g_lua.registerFunction<bool(std::shared_ptr<KeyValueStore>::*)()>("reload", [](std::shared_ptr<KeyValueStore>& kvs) {
+ if (!kvs) {
+ return false;
+ }
+
+ return kvs->reload();
+ });
+
}
#include <sys/stat.h>
-std::vector<std::string> KeyValueLookupKeySourceIP::getKeys(const DNSQuestion& dq)
+std::vector<std::string> KeyValueLookupKeySourceIP::getKeys(const ComboAddress& addr)
{
std::vector<std::string> result;
- if (dq.remote->sin4.sin_family == AF_INET) {
- result.emplace_back(reinterpret_cast<const char*>(&dq.remote->sin4.sin_addr.s_addr), sizeof(dq.remote->sin4.sin_addr.s_addr));
+ if (addr.sin4.sin_family == AF_INET) {
+ result.emplace_back(reinterpret_cast<const char*>(&addr.sin4.sin_addr.s_addr), sizeof(addr.sin4.sin_addr.s_addr));
}
- else if (dq.remote->sin4.sin_family == AF_INET6) {
- result.emplace_back(reinterpret_cast<const char*>(&dq.remote->sin6.sin6_addr.s6_addr), sizeof(dq.remote->sin6.sin6_addr.s6_addr));
+ else if (addr.sin4.sin_family == AF_INET6) {
+ result.emplace_back(reinterpret_cast<const char*>(&addr.sin6.sin6_addr.s6_addr), sizeof(addr.sin6.sin6_addr.s6_addr));
}
return result;
refreshDBIfNeeded(now);
}
+bool CDBKVStore::reload(const struct stat& st)
+{
+ auto newCDB = make_unique<CDB>(d_fname);
+ {
+ WriteLock wl(&d_lock);
+ d_cdb = std::move(newCDB);
+ }
+ d_mtime = st.st_mtime;
+ return true;
+}
+
+bool CDBKVStore::reload()
+{
+ struct stat st;
+ if (stat(d_fname.c_str(), &st) == 0) {
+ return reload(st);
+ }
+ else {
+ warnlog("Error while retrieving the last modification time of CDB database '%s': %s", d_fname, stringerror());
+ return false;
+ }
+}
+
void CDBKVStore::refreshDBIfNeeded(time_t now)
{
if (d_refreshing.test_and_set()) {
struct stat st;
if (stat(d_fname.c_str(), &st) == 0) {
if (st.st_mtime > d_mtime) {
- auto newCDB = make_unique<CDB>(d_fname);
- {
- WriteLock wl(&d_lock);
- d_cdb = std::move(newCDB);
- }
- d_mtime = st.st_mtime;
+ reload(st);
}
}
else {
class KeyValueLookupKeySourceIP: public KeyValueLookupKey
{
public:
- std::vector<std::string> getKeys(const DNSQuestion& dq) override;
+ std::vector<std::string> getKeys(const ComboAddress& addr);
+
+ std::vector<std::string> getKeys(const DNSQuestion& dq) override
+ {
+ return getKeys(*dq.remote);
+ }
std::string toString() const override
{
}
virtual bool getValue(const std::string& key, std::string& value) = 0;
+ virtual bool reload()
+ {
+ return false;
+ }
};
#ifdef HAVE_LMDB
CDBKVStore(const std::string& fname, time_t refreshDelay);
bool getValue(const std::string& key, std::string& value) override;
+ bool reload() override;
private:
void refreshDBIfNeeded(time_t now);
+ bool reload(const struct stat& st);
std::unique_ptr<CDB> d_cdb{nullptr};
std::string d_fname;