示例#1
0
 async def query_remote_once(self, domain, nameservers=None):
     resolver = self.resolver
     req = DNSMessage(qr=REQUEST)
     if nameservers is None:
         nameservers = resolver.get_nameservers(domain)
     req.qd = [Record(REQUEST, domain, self.qtype)]
     logger.debug('[query_remote_once][%s][%s] %s', types.get_name(self.qtype), domain, nameservers)
     inter_res = await self.request_remote(nameservers, req)
     resolver.cache_message(inter_res)
     return inter_res
示例#2
0
文件: udp.py 项目: zombig/async_dns
async def request(req, addr, timeout=3.0):
    '''
    Send raw data through UDP.
    '''
    dispatcher = await Dispatcher.get(addr.ip_type)
    data = await dispatcher.send(req, addr, timeout)
    result = DNSMessage.parse(data)
    return result
示例#3
0
文件: query.py 项目: zombig/async_dns
 def __init__(self, resolver, fqdn, qtype, tick):
     self.resolver = resolver
     self.fqdn = fqdn
     self.qtype = qtype
     self.tick = tick
     self._cached = False
     self._status = PENDING
     self._result = DNSMessage(ra=resolver.recursive)
     self._result.qd.append(Record(REQUEST, name=fqdn, qtype=qtype))
示例#4
0
 def __init__(self, resolver, loop, fqdn, qtype, tick):
     self.loop = loop
     self.resolver = resolver
     self.fqdn = fqdn
     self.qtype = qtype
     self.tick = tick
     self.future = loop.create_future()
     self.from_cache = False
     self._status = PENDING
     self._result = DNSMessage(ra=resolver.recursive)
     self._result.qd.append(Record(REQUEST, name=fqdn, qtype=qtype))
示例#5
0
async def _resolve_hostname(resolver, hostname, qtype):
    '''Resolve a hostname with the given resolver.'''
    for _ in range(0, 5):
        try:
            message = await resolver.query(hostname, qtype)
            if message.r == 2:
                continue
            if hostname == 'message.acronis.com':
                logging.debug(message)
            return YADBDnsMessage(hostname, qtype, message)
        except asyncio.CancelledError:
            continue
        except AssertionError as ex:
            if str(ex) == 'Remote server fail':
                continue
        except asyncio.exceptions.TimeoutError:
            continue
    message = DNSMessage()
    message.r = 2
    if hostname == 'message.acronis.com':
        logging.debug(message)
    return YADBDnsMessage(hostname, qtype, message)
示例#6
0
文件: tcp.py 项目: zombig/async_dns
async def request(req, addr, timeout=3.0):
    '''
    Send raw data with a connection pool.
    '''
    async with ConnectionHandle(*addr.to_addr(),
                                ssl=addr.protocol == 'tcps') as conn:
        reader = conn.reader
        writer = conn.writer
        qdata = req.pack()
        bsize = struct.pack('!H', len(qdata))
        writer.write(bsize)
        writer.write(qdata)
        await writer.drain()
        size, = struct.unpack('!H', await reader.readexactly(2))
        data = await reader.readexactly(size)
        result = DNSMessage.parse(data)
        return result
示例#7
0
 async def request_remote(self, nameservers, req):
     while not self.future.cancelled():
         addr = nameservers.get()
         if not addr:
             raise InvalidNameServer
         try:
             data = await self.request_once(req, addr)
             inter_res = DNSMessage.parse(data)
             logger.debug('[request_remote] %s', inter_res)
             if inter_res.qd[0].name != req.qd[0].name:
                 raise DNSError(-1, 'Question section mismatch')
             assert inter_res.r != 2, 'Remote server fail'
         except (asyncio.TimeoutError, AssertionError) as e:
             logger.debug('[request_remote][server_error] %s', e)
         except DNSError as e:
             logger.debug('[request_remote][dns_error] %s', e)
         except Exception as e:
             logger.error('[request_remote][error] %s', e)
         else:
             nameservers.success(addr)
             return inter_res
         nameservers.fail(addr)
示例#8
0
async def request(req, addr, timeout=3.0):
    '''
    Send raw data with a connection pool.
    '''
    qdata = req.pack()
    bsize = struct.pack('!H', len(qdata))
    key = str(addr)
    queue = _connections.get(key)
    if queue is None:
        queue = asyncio.Queue(maxsize=DEFAULT_QUEUE_SIZE)
        _connections[key] = queue
    for _retry in range(5):
        reader = writer = None
        try:
            reader, writer = queue.get_nowait()
        except asyncio.QueueEmpty:
            pass
        if reader is None:
            try:
                reader, writer = await asyncio.wait_for(
                    asyncio.open_connection(*addr.to_addr()), timeout)
            except asyncio.TimeoutError:
                pass
        if reader is None:
            continue
        writer.write(bsize)
        writer.write(qdata)
        try:
            await writer.drain()
            size, = struct.unpack('!H', await reader.readexactly(2))
            data = await reader.readexactly(size)
            queue.put_nowait((reader, writer))
        except asyncio.QueueFull:
            pass
        result = DNSMessage.parse(data)
        return result
    else:
        raise DNSConnectionError