1
0

use async dns interface in dnshacks

This commit is contained in:
f321x
2025-05-16 12:42:59 +02:00
parent f7ad95f42d
commit f90ca34fb9

View File

@@ -7,18 +7,16 @@ import socket
import concurrent import concurrent
from concurrent import futures from concurrent import futures
import ipaddress import ipaddress
from typing import Optional import asyncio
import dns import dns
import dns.resolver import dns.asyncresolver
from .logging import get_logger from .logging import get_logger
from .util import get_asyncio_loop
_logger = get_logger(__name__) _logger = get_logger(__name__)
_dns_threads_executor = None # type: Optional[concurrent.futures.Executor]
def configure_dns_resolver() -> None: def configure_dns_resolver() -> None:
# Store this somewhere so we can un-monkey-patch: # Store this somewhere so we can un-monkey-patch:
@@ -38,16 +36,11 @@ def configure_dns_resolver() -> None:
def _prepare_windows_dns_hack(): def _prepare_windows_dns_hack():
# enable dns cache # enable dns cache
resolver = dns.resolver.get_default_resolver() resolver = dns.asyncresolver.get_default_resolver()
if resolver.cache is None: if resolver.cache is None:
resolver.cache = dns.resolver.Cache() resolver.cache = dns.resolver.Cache()
# ensure overall timeout for requests is long enough # ensure overall timeout for requests is long enough
resolver.lifetime = max(resolver.lifetime or 1, 30.0) resolver.lifetime = max(resolver.lifetime or 1, 30.0)
# prepare threads
global _dns_threads_executor
if _dns_threads_executor is None:
_dns_threads_executor = concurrent.futures.ThreadPoolExecutor(max_workers=20,
thread_name_prefix='dns_resolver')
def _is_force_system_dns_for_host(host: str) -> bool: def _is_force_system_dns_for_host(host: str) -> bool:
@@ -69,8 +62,15 @@ def _fast_getaddrinfo(host, *args, **kwargs):
addrs = [] addrs = []
expected_errors = (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, expected_errors = (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer,
concurrent.futures.CancelledError, concurrent.futures.TimeoutError) concurrent.futures.CancelledError, concurrent.futures.TimeoutError)
ipv6_fut = _dns_threads_executor.submit(dns.resolver.resolve, host, dns.rdatatype.AAAA) loop = get_asyncio_loop()
ipv4_fut = _dns_threads_executor.submit(dns.resolver.resolve, host, dns.rdatatype.A) ipv6_fut = asyncio.run_coroutine_threadsafe(
dns.asyncresolver.resolve(host, dns.rdatatype.AAAA),
loop,
)
ipv4_fut = asyncio.run_coroutine_threadsafe(
dns.asyncresolver.resolve(host, dns.rdatatype.A),
loop,
)
# try IPv6 # try IPv6
try: try:
answers = ipv6_fut.result() answers = ipv6_fut.result()