dnsbl: cap the number of blocklist zones checked per client at 16 — each zone is a serial blocking DNS lookup, so a long (mis)configured zone list could stall a connecting client's registration for zones.len()*timeout
This commit is contained in:
parent
b63458816e
commit
8f5b37bf8d
1 changed files with 7 additions and 1 deletions
|
|
@ -30,13 +30,19 @@ pub enum Outcome {
|
||||||
Hit { zone: String, reply: Ipv4Addr },
|
Hit { zone: String, reply: Ipv4Addr },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Most blocklist zones consulted per connecting client (latency bound).
|
||||||
|
const MAX_ZONES: usize = 16;
|
||||||
|
|
||||||
/// Check `ip` against every blocklist `zone`; the first listing wins. Runs off the
|
/// Check `ip` against every blocklist `zone`; the first listing wins. Runs off the
|
||||||
/// core thread (called from the resolver worker), so it may block on DNS.
|
/// core thread (called from the resolver worker), so it may block on DNS.
|
||||||
pub fn check(ip: IpAddr, zones: &[String], timeout: Duration) -> Outcome {
|
pub fn check(ip: IpAddr, zones: &[String], timeout: Duration) -> Outcome {
|
||||||
if zones.is_empty() {
|
if zones.is_empty() {
|
||||||
return Outcome::Skipped;
|
return Outcome::Skipped;
|
||||||
}
|
}
|
||||||
for zone in zones {
|
// Each zone is a serial blocking lookup, so total latency is bounded by the
|
||||||
|
// number checked × timeout; cap it so a long (mis)configured zone list can't
|
||||||
|
// stall a client's registration for a very long time.
|
||||||
|
for zone in zones.iter().take(MAX_ZONES) {
|
||||||
let z = zone.trim().trim_end_matches('.');
|
let z = zone.trim().trim_end_matches('.');
|
||||||
let qname = format!("{}.{z}", resolver::reverse_labels(ip));
|
let qname = format!("{}.{z}", resolver::reverse_labels(ip));
|
||||||
if let Some(reply) = resolver::a_lookup(&qname, timeout) {
|
if let Some(reply) = resolver::a_lookup(&qname, timeout) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue