aboutsummaryrefslogtreecommitdiff
path: root/src/modules/m_dnsbl.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2023-07-07 08:59:21 +0100
committerGravatar Sadie Powell2023-07-07 09:59:41 +0100
commit33758b207ffc0f5b9105d4d8520792af4dd6f32f (patch)
treed329e46db368fff2dfade9b3da1e67ad3db1158f /src/modules/m_dnsbl.cpp
parentImprove the inlining of some channel functions. (diff)
Move DNSBL lookup code to SharedData to allow it to be called from several places.
Diffstat (limited to 'src/modules/m_dnsbl.cpp')
-rw-r--r--src/modules/m_dnsbl.cpp155
1 files changed, 86 insertions, 69 deletions
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 4a397557a..ab215bddd 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -184,18 +184,58 @@ public:
}
};
+typedef std::vector<std::shared_ptr<DNSBLEntry>> DNSBLEntries;
typedef SimpleExtItem<DNSBLMask> MaskExtItem;
typedef ListExtItem<std::vector<std::string>> MarkExtItem;
// Data which is shared with DNS lookup classes.
class SharedData final
{
+private:
+ std::string ReverseIP(const irc::sockets::sockaddrs& sa)
+ {
+ switch (sa.family())
+ {
+ case AF_INET:
+ {
+ auto a = (unsigned int) sa.in4.sin_addr.s_addr & 0xFF;
+ auto b = (unsigned int) (sa.in4.sin_addr.s_addr >> 8) & 0xFF;
+ auto c = (unsigned int) (sa.in4.sin_addr.s_addr >> 16) & 0xFF;
+ auto d = (unsigned int) (sa.in4.sin_addr.s_addr >> 24) & 0xFF;
+ return INSP_FORMAT("{}.{}.{}.{}", d, c, b, a);
+ }
+
+ case AF_INET6:
+ {
+ const std::string hexaddr = Hex::Encode(sa.in6.sin6_addr.s6_addr, 16);
+ std::string reversedip;
+ reversedip.reserve(hexaddr.length() * 2);
+ for (const auto hexchr : insp::reverse_range(hexaddr))
+ {
+ reversedip.push_back(hexchr);
+ reversedip.push_back('.');
+ }
+ reversedip.pop_back();
+ return reversedip;
+ }
+
+ default:
+ break;
+ }
+
+ // Clients can't be in a DNSBL if they aren't connected via IPv4 or IPv6.
+ return {};
+ }
+
public:
+ // Counts the number of DNSBL lookups waiting for this user.
+ IntExtItem countext;
+
// Reference to the DNS manager.
DNS::ManagerRef dns;
- // Counts the number of DNSBL lookups waiting for this user.
- IntExtItem countext;
+ // The DNSBL entries from the config.
+ DNSBLEntries dnsbls;
// The DNSBL marks which are set on a user.
MarkExtItem markext;
@@ -204,12 +244,15 @@ public:
MaskExtItem maskext;
SharedData(Module* mod)
- : dns(mod)
- , countext(mod, "dnsbl-pending", ExtensionType::USER)
+ : countext(mod, "dnsbl-pending", ExtensionType::USER)
+ , dns(mod)
, markext(mod, "dnsbl-match", ExtensionType::USER)
, maskext(mod, "dnsbl-mask", ExtensionType::USER)
{
}
+
+ // Performs one or more DNSBL lookups on the specified user.
+ void Lookup(LocalUser* user);
};
class DNSBLResolver final
@@ -221,7 +264,6 @@ private:
const irc::sockets::sockaddrs sa;
const std::string uuid;
-
template <typename Line, typename... Extra>
void AddLine(const char* type, const std::string& reason, unsigned long duration, Extra&&... extra)
{
@@ -398,7 +440,41 @@ public:
}
};
-typedef std::vector<std::shared_ptr<DNSBLEntry>> DNSBLEntries;
+void SharedData::Lookup(LocalUser* user)
+{
+ if (!dns)
+ return; // The core_dns module is not loaded.
+
+ if (user->exempt || !user->GetClass()->config->getBool("usednsbl", true))
+ return; // The user is exempt from DNSBL lookups.
+
+ const std::string reversedip = ReverseIP(user->client_sa);
+ ServerInstance->Logs.Debug(MODNAME, "Reversed IP {} => {}", user->GetAddress(), reversedip);
+
+ countext.Set(user, dnsbls.size());
+
+ // For each DNSBL, we will run through this lookup
+ for (const auto& dnsbl : dnsbls)
+ {
+ // Fill hostname with a dnsbl style host (d.c.b.a.domain.tld)
+ const std::string hostname = reversedip + "." + dnsbl->domain;
+
+ // Try to do the DNSBL lookup.
+ auto* r = new DNSBLResolver(dns->creator, *this, hostname, user, dnsbl);
+ try
+ {
+ dns->Process(r);
+ }
+ catch (const DNS::Exception& ex)
+ {
+ delete r;
+ ServerInstance->Logs.Debug(MODNAME, "DNSBL lookup error: {}", ex.GetReason());
+ }
+
+ if (user->quitting)
+ break; // DNS resolver found a cached hit.
+ }
+}
class ModuleDNSBL final
: public Module
@@ -406,7 +482,6 @@ class ModuleDNSBL final
{
private:
SharedData data;
- DNSBLEntries dnsbls;
public:
ModuleDNSBL()
@@ -435,71 +510,13 @@ public:
auto entry = std::make_shared<DNSBLEntry>(this, tag);
newdnsbls.push_back(entry);
}
- dnsbls.swap(newdnsbls);
+ data.dnsbls.swap(newdnsbls);
}
void OnChangeRemoteAddress(LocalUser* user) override
{
- if (user->exempt || user->quitting || !data.dns || !user->GetClass())
- return;
-
- // Clients can't be in a DNSBL if they aren't connected via IPv4 or IPv6.
- if (!user->client_sa.is_ip())
- return;
-
- if (!user->GetClass()->config->getBool("usednsbl", true))
- return;
-
- std::string reversedip;
- if (user->client_sa.family() == AF_INET)
- {
- unsigned int a = (unsigned int) user->client_sa.in4.sin_addr.s_addr & 0xFF;
- unsigned int b = (unsigned int) (user->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF;
- unsigned int c = (unsigned int) (user->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF;
- unsigned int d = (unsigned int) (user->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF;
-
- reversedip = ConvToStr(d) + "." + ConvToStr(c) + "." + ConvToStr(b) + "." + ConvToStr(a);
- }
- else if (user->client_sa.family() == AF_INET6)
- {
- const unsigned char* ip = user->client_sa.in6.sin6_addr.s6_addr;
-
- const std::string buf = Hex::Encode(ip, 16);
- for (const auto chr : insp::reverse_range(buf))
- {
- reversedip.push_back(chr);
- reversedip.push_back('.');
- }
- reversedip.erase(reversedip.length() - 1, 1);
- }
- else
- return;
-
- ServerInstance->Logs.Debug(MODNAME, "Reversed IP {} -> {}", user->GetAddress(), reversedip);
-
- data.countext.Set(user, dnsbls.size());
-
- // For each DNSBL, we will run through this lookup
- for (const auto& dnsbl : dnsbls)
- {
- // Fill hostname with a dnsbl style host (d.c.b.a.domain.tld)
- std::string hostname = reversedip + "." + dnsbl->domain;
-
- /* now we'd need to fire off lookups for `hostname'. */
- auto* r = new DNSBLResolver(this, data, hostname, user, dnsbl);
- try
- {
- data.dns->Process(r);
- }
- catch (const DNS::Exception& ex)
- {
- delete r;
- ServerInstance->Logs.Debug(MODNAME, ex.GetReason());
- }
-
- if (user->quitting)
- break;
- }
+ if (user->quitting && user->GetClass())
+ data.Lookup(user);
}
ModResult OnPreChangeConnectClass(LocalUser* user, const std::shared_ptr<ConnectClass>& klass, std::optional<Numeric::Numeric>& errnum) override
@@ -563,7 +580,7 @@ public:
unsigned long total_hits = 0;
unsigned long total_misses = 0;
unsigned long total_errors = 0;
- for (const auto& dnsbl : dnsbls)
+ for (const auto& dnsbl : data.dnsbls)
{
total_hits += dnsbl->stats_hits;
total_misses += dnsbl->stats_misses;