emailsec._dns_resolver
1import asyncio 2import typing 3 4from emailsec import _errors as errors 5 6import aiodns 7import pycares 8 9_MAX_LOOKUPS = 10 10 11 12class DNSResolver: 13 def __init__(self) -> None: 14 self.__lookups_counter = 0 15 self.__resolver = aiodns.DNSResolver(loop=asyncio.get_running_loop()) 16 17 async def _query(self, name: str, query_type: str) -> typing.Any: 18 self.__lookups_counter += 1 19 if self.__lookups_counter > _MAX_LOOKUPS: 20 raise errors.Permerror("Max DNS lookups exceeded") 21 22 try: 23 return await self.__resolver.query(name, query_type) 24 except aiodns.error.DNSError as dns_error: 25 error_msg = dns_error.args[1] 26 match dns_error.args[0]: 27 case aiodns.error.ARES_ENOTFOUND | aiodns.error.ARES_ENODATA: # type: ignore 28 return None 29 case ( 30 aiodns.error.ARES_EBADQUERY # type: ignore 31 | aiodns.error.ARES_EFORMERR # type: ignore 32 | aiodns.error.ARES_EBADNAME # type: ignore 33 | aiodns.error.ARES_EBADRESP # type: ignore 34 ): 35 raise errors.Permerror( 36 f"DNS error (code {dns_error.args[0]}): {error_msg}" 37 ) 38 case _: 39 raise errors.Temperror( 40 f"DNS error (code {dns_error.args[0]}): {error_msg}" 41 ) 42 43 async def txt(self, name: str) -> list[pycares.ares_query_txt_result] | None: 44 return await self._query(name, "TXT") 45 46 async def mx(self, name: str) -> list[pycares.ares_query_mx_result] | None: 47 return await self._query(name, "MX") 48 49 async def a(self, name: str) -> list[pycares.ares_query_a_result] | None: 50 return await self._query(name, "A") 51 52 async def aaaa(self, name: str) -> list[pycares.ares_query_aaaa_result] | None: 53 return await self._query(name, "AAAA") 54 55 async def ptr(self, name: str) -> pycares.ares_query_ptr_result | None: 56 return await self._query(name, "PTR")
class
DNSResolver:
13class DNSResolver: 14 def __init__(self) -> None: 15 self.__lookups_counter = 0 16 self.__resolver = aiodns.DNSResolver(loop=asyncio.get_running_loop()) 17 18 async def _query(self, name: str, query_type: str) -> typing.Any: 19 self.__lookups_counter += 1 20 if self.__lookups_counter > _MAX_LOOKUPS: 21 raise errors.Permerror("Max DNS lookups exceeded") 22 23 try: 24 return await self.__resolver.query(name, query_type) 25 except aiodns.error.DNSError as dns_error: 26 error_msg = dns_error.args[1] 27 match dns_error.args[0]: 28 case aiodns.error.ARES_ENOTFOUND | aiodns.error.ARES_ENODATA: # type: ignore 29 return None 30 case ( 31 aiodns.error.ARES_EBADQUERY # type: ignore 32 | aiodns.error.ARES_EFORMERR # type: ignore 33 | aiodns.error.ARES_EBADNAME # type: ignore 34 | aiodns.error.ARES_EBADRESP # type: ignore 35 ): 36 raise errors.Permerror( 37 f"DNS error (code {dns_error.args[0]}): {error_msg}" 38 ) 39 case _: 40 raise errors.Temperror( 41 f"DNS error (code {dns_error.args[0]}): {error_msg}" 42 ) 43 44 async def txt(self, name: str) -> list[pycares.ares_query_txt_result] | None: 45 return await self._query(name, "TXT") 46 47 async def mx(self, name: str) -> list[pycares.ares_query_mx_result] | None: 48 return await self._query(name, "MX") 49 50 async def a(self, name: str) -> list[pycares.ares_query_a_result] | None: 51 return await self._query(name, "A") 52 53 async def aaaa(self, name: str) -> list[pycares.ares_query_aaaa_result] | None: 54 return await self._query(name, "AAAA") 55 56 async def ptr(self, name: str) -> pycares.ares_query_ptr_result | None: 57 return await self._query(name, "PTR")