only query an ip address once during dnsbl checks

- IP addresses are used for DNSBL queries, only query each unique IP address once per DNSBL provider

- add support for MXs with IPv6 addresses

fixes #1335
This commit is contained in:
Andrew Fyfe
2018-01-04 21:52:03 +00:00
parent 5fb2f55a0a
commit 9ff4ca64e5
@@ -72,13 +72,21 @@ class CheckMXRecords(BaseCommand):
def query_dnsbl(self, mx_list, provider):
"""Check given IP against given DNSBL provider."""
results = {}
for mx in mx_list:
reverse = ".".join(reversed(mx.address.split(".")))
for ip, mxs in mx_list.items():
try:
ip = ipaddress.ip_address(smart_text(ip))
except ValueError as e:
continue
else:
delim = "." if ip.version == 4 else ":"
reverse = delim.join(ip.exploded.split(delim)[::-1])
pattern = "{}.{}.".format(reverse, provider)
try:
results[mx] = socket.gethostbyname(pattern)
result = socket.gethostbyname(pattern)
except socket.gaierror:
results[mx] = False
result = False
for mx in mxs:
results[mx] = result
return provider, results
def store_dnsbl_result(self, domain, provider, results, **options):
@@ -191,8 +199,16 @@ class CheckMXRecords(BaseCommand):
options["no_dnsbl"] is True)
if condition or not mx_list:
return
mx_by_ip = {}
for mx in mx_list:
if mx.address not in mx_by_ip:
mx_by_ip[mx.address] = [mx]
elif mx not in mx_by_ip[mx.address]:
mx_by_ip[mx.address].append(mx)
jobs = [
gevent.spawn(self.query_dnsbl, mx_list, provider)
gevent.spawn(self.query_dnsbl, mx_by_ip, provider)
for provider in self.providers]
gevent.joinall(jobs, timeout)
for job in jobs: