def __init__(self, timeout, tries, servers=None): flags = pycares.ARES_FLAG_NOSEARCH timeout = float(timeout) tries = int(tries) if servers: self.channel = pycares.Channel(flags, timeout, tries, servers=servers) else: self.channel = pycares.Channel(flags, timeout, tries)
def __init__(self): self.chan = pycares.Channel(timeout=TIMEOUT, tries=RETRIES) self.sent_count = 0 self.recv_count = 0 self.active_count = 0 self.error_count = 0 self.last_answer = time.time()
def resolve_cares(name): # create new c-ares channel careschan = pycares.Channel(timeout=DNS_TIMEOUT, tries=1) # if we don't get a response we return the default value result = Resultholder() result.value = DNS_TIMEOUT_VALUE def setresult_cb(res, error): # ignore error and just take first result ip (randomized anyway) if res and res.addresses: result.value = res.addresses[0] # resolve with cb careschan.gethostbyname(name, socket.AF_INET, setresult_cb) # now do the actual work readfds, writefds = careschan.getsock() canreadfds, canwritefds, _ = select.select(readfds, writefds, [], DNS_TIMEOUT) for rfd in canreadfds: careschan.process_fd(rfd, -1) # if the query did not succeed, setresult was not called and we just # return result destroy the channel first to not leak anything careschan.destroy() return result.value
def test_lookup(self): channel = pycares.Channel( lookups="b", timeout=1, tries=1, socket_receive_buffer_size=4096, servers=["8.8.8.8", "8.8.4.4"], tcp_port=53, udp_port=53, rotate=True, ) def on_result(result, errorno): self.result, self.errorno = result, errorno for domain in [ "google.com", "microsoft.com", "apple.com", "amazon.com", "baidu.com", "alipay.com", "tencent.com", ]: self.result, self.errorno = None, None self.channel.query(domain, pycares.QUERY_TYPE_A, on_result) self.wait() self.assertNoError(self.errorno) self.assertTrue(self.result is not None and len(self.result) > 0) for r in self.result: self.assertEqual(type(r), pycares.ares_query_a_result) self.assertNotEqual(r.host, None) self.assertTrue(r.type == 'A')
def test_gethostbyname_small_timeout(self): def cb(result, errorno): self.assertEqual(errorno, None) self.channel = pycares.Channel(timeout=0.5, tries=1) self.channel.gethostbyname('localhost', socket.AF_INET, cb) self.wait()
def test_lookup(self): Resolver.configure("tornado.platform.caresresolver.CaresResolver") resolver = Resolver() resolver.channel = pycares.Channel( lookups="b", sock_state_cb=resolver._sock_state_cb, timeout=5, tries=1, socket_receive_buffer_size=4096, servers=["8.8.8.8", "8.8.4.4"], tcp_port=53, udp_port=53, rotate=True, ) loop = resolver.io_loop sys.stdout.write("\n") for domain in [ "google.com", "microsoft.com", "apple.com", "amazon.com", "baidu.com", "alipay.com", "tencent.com", ]: loop.run_sync(partial(resolver.resolve, domain, None)) r = loop.run_sync(partial(resolver.resolve, domain, None)) assert isinstance( r, list) and len(r) > 0, "Error Resolving: %s" % domain sys.stdout.write("Resolving: %s:%s\n" % (domain, [i[1][0] for i in r if i[1]])) sys.stdout.flush()
def test_channel_nameservers(self): self.result, self.errorno = None, None def cb(result, errorno): self.result, self.errorno = result, errorno self.channel = pycares.Channel(timeout=5.0, tries=1, servers=['8.8.8.8']) self.channel.query('google.com', pycares.QUERY_TYPE_A, cb) self.wait() self.assertNoError(self.errorno)
def __init__(self, nameservers=None, **kwargs): self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb, **kwargs) if nameservers: self._channel.servers = nameservers self._loop = evergreen.current.loop self._read_fds = set() self._write_fds = set() self._timer = None
def test_gethostbyname_small_timeout(self): self.result, self.errorno = None, None def cb(result, errorno): self.result, self.errorno = result, errorno self.channel = pycares.Channel(timeout=0.5, tries=1) self.channel.gethostbyname('localhost', socket.AF_INET, cb) self.wait() self.assertNoError(self.errorno) self.assertEqual(type(self.result), pycares.ares_host_result)
def test_custom_resolvconf(self): self.result, self.errorno = None, None def cb(result, errorno): self.result, self.errorno = result, errorno self.channel = pycares.Channel(tries=1, timeout=2.0, resolvconf_path=os.path.join(FIXTURES_PATH, 'badresolv.conf')) self.channel.query('google.com', pycares.QUERY_TYPE_A, cb) self.wait() self.assertEqual(self.result, None) self.assertEqual(self.errorno, pycares.errno.ARES_ETIMEOUT)
def test_channel_local_ip(self): self.result, self.errorno = None, None def cb(result, errorno): self.result, self.errorno = result, errorno self.channel = pycares.Channel(timeout=5.0, tries=1, servers=['8.8.8.8'], local_ip='127.0.0.1') self.channel.query('google.com', pycares.QUERY_TYPE_A, cb) self.wait() self.assertEqual(self.result, None) self.assertEqual(self.errorno, pycares.errno.ARES_ECONNREFUSED)
def test_query(self): channel = self.mox.CreateMock(pycares.Channel) self.mox.StubOutWithMock(pycares, 'Channel') self.mox.StubOutWithMock(gevent, 'spawn') pycares.Channel().AndReturn(channel) channel.query('example.com', 13, IgnoreArg()) gevent.spawn(IgnoreArg()) self.mox.ReplayAll() DNSResolver.query('example.com', 13)
def __init__(self, nameservers=None, loop=None, **kwargs): self.loop = loop or asyncio.get_event_loop() assert self.loop is not None kwargs.pop('sock_state_cb', None) self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb, **kwargs) if nameservers: self.nameservers = nameservers self._read_fds = set() self._write_fds = set() self._timer = None
def test_channel_timeout(self): def cb(result, errorno): self.assertEqual(errorno, pycares.errno.ARES_ECANCELLED) self.channel = pycares.Channel(timeout=0.5, tries=1) self.channel.gethostbyname('google.com', socket.AF_INET, cb) timeout = self.channel.timeout() self.assertTrue(timeout > 0.0) self.channel.cancel() self.wait()
def test_search(self): self.result, self.errorno = None, None def cb(result, errorno): self.result, self.errorno = result, errorno self.channel = pycares.Channel(timeout=5.0, tries=1, domains=['google.com']) self.channel.search('cloud', pycares.QUERY_TYPE_A, cb) self.wait() self.assertNoError(self.errorno) for r in self.result: self.assertEqual(type(r), pycares.ares_query_a_result) self.assertNotEqual(r.host, None)
def test_query_a_rotate(self): def cb(result, errorno): self.assertEqual(errorno, None) self.count += 1 self.count = 0 self.channel = pycares.Channel(timeout=1.0, tries=1, rotate=True) self.channel.query('google.com', pycares.QUERY_TYPE_A, cb) self.channel.query('google.com', pycares.QUERY_TYPE_A, cb) self.channel.query('google.com', pycares.QUERY_TYPE_A, cb) self.wait() self.assertEqual(self.count, 3)
def __init__(self, nameservers=None, loop=None, **kwargs): # type: (Optional[List[str]], Optional[asyncio.AbstractEventLoop], Any) -> None self.loop = loop or asyncio.get_event_loop() assert self.loop is not None kwargs.pop('sock_state_cb', None) self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb, **kwargs) if nameservers: self.nameservers = nameservers self._read_fds = set() # type: Set[int] self._write_fds = set() # type: Set[int] self._timer = None
def query(cls, name, query_type): """Begin a DNS lookup. The result (or exception) will be in the returned :class:`~gevent.event.AsyncResult` when it is available. :param name: The DNS name to resolve. :type name: str :param query_type: The DNS query type, see :meth:`pycares.Channel.query` for options. A string may be given instead, e.g. ``'MX'``. :rtype: :class:`~gevent.event.AsyncResult` """ result = AsyncResult() query_type = cls._get_query_type(query_type) cls._channel = cls._channel or cls.channel or pycares.Channel() cls._channel.query(name, query_type, partial(cls._result_cb, result)) cls._thread = cls._thread or gevent.spawn(cls._wait_channel) return result
def __init__(self, io_loop=None, **kwargs): """Create a new :class:`~tdns.Channel` instance. :param int flags: Flags controlling the behavior of the resolver. See constants for available values :param float timeout: The number of seconds each name server is given to respond to a query on the first try. The default is five seconds :param int tries: The number of tries the resolver will try contacting each name server before giving up. The default is four tries :param int ndots: The number of dots which must be present in a domain name for it to be queried for "as is" prior to querying for it with the default domain extensions appended. The default value is 1 unless set otherwise by ``resolv.conf`` or the ``RES_OPTIONS`` environment variable :param int tcp_port: The (TCP) port to use for queries. The default is ``53`` :param int udp_port: The (UDP) port to use for queries. The default is ``53`` :param list servers: List of nameservers to be used to do the lookups :param list domains: The domains to search, instead of the domains specified in ``resolv.conf`` or the domain derived from the kernel hostname variable :param str lookup: The lookups to perform for host queries. lookups should be set to a string of the characters ``b`` or ``f``, where ``b`` indicates a DNS lookup and ``f`` indicates a lookup in the hosts file :param bool rotate: If set to ``True``, the nameservers are rotated when doing queries :param tornado.ioloop.IOLoop io_loop: The IOLoop to use. The default is `tornado.ioloop.IOLoop.current` """ self.io_loop = io_loop or ioloop.IOLoop.current() self._fds = {} kwargs['sock_state_cb'] = self._sock_state_cb self._channel = pycares.Channel(**kwargs)
def initialize(self, io_loop=None): self.io_loop = io_loop or IOLoop.current() self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb) self.fds = {}
while True: read_fds, write_fds = channel.getsock() if not read_fds and not write_fds: break timeout = channel.timeout() if not timeout: channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD) continue rlist, wlist, xlist = select.select(read_fds, write_fds, [], timeout) for fd in rlist: channel.process_fd(fd, pycares.ARES_SOCKET_BAD) for fd in wlist: channel.process_fd(pycares.ARES_SOCKET_BAD, fd) if __name__ == '__main__': def cb(result, error): print(result) if error: print(error) current_channel = pycares.Channel() current_channel.gethostbyname('google.com', socket.AF_INET, cb) current_channel.query('www.taobao.com', pycares.QUERY_TYPE_A, cb) current_channel.query('sip2sip.info', pycares.QUERY_TYPE_SOA, cb) wait_channel(current_channel) print("Done!")
def query_blacklists(self, ekey, rec, updates): """ Query all configured blacklists and update the set of blacklists the address is listed on, together with the time of query. Updates 'bl' attribute. Arguments: ekey -- two-tuple of entity type and key, e.g. ('ip', '192.0.2.42') rec -- record currently assigned to the key updates -- list of all attributes whose update triggered this call and their new values (or events and their parameters) as a list of 2-tuples: [(attr, val), (!event, param), ...] Returns: List of following update requests (one for every blacklist the address was found on): ('append', 'bl.'+<blacklist_id>, time) """ etype, key = ekey if etype != 'ip': return None req_time = datetime.utcnow() # Limit of the number of requests per day with self.req_counter_lock: # Increment request counter self.req_counter += 1 # Reset counter when new day starts if req_time.date() > self.req_counter_current_date: self.write_req_count() self.req_counter = 0 self.req_counter_current_date = req_time.date() # Backup counter to file every 1000 requests elif self.req_counter % 1000 == 0: self.write_req_count() # End processing if the limit was reached if self.req_counter >= self.max_req_count: if self.req_counter == self.max_req_count: self.log.warning("Maximal request count reached - no more DNSBL requests will be made today.") return None ip = ekey[1] revip = reverse_ip(ip) self.log.debug("Querying blacklists for {}".format(ekey)) channel = pycares.Channel(servers=self.nameservers) results = [] # Create queries to all blacklists for bl in self.blacklists: channel.query(revip + '.' + bl[1], pycares.QUERY_TYPE_A, _make_result_handler(bl, results) ) # Send all queries and wait for results #(they are handled by self._process_result callback) _wait_channel(channel) self.log.debug("DNSBL for {}: {}".format(ip, results)) actions = [] for bl in self.blacklists: for blname in bl[2].values(): if blname in results: # IP is on blacklist blname self.log.debug("IP address ({0}) is on {1}.".format(key, blname)) actions.append( ('array_upsert', 'bl', {'n': blname}, [('set', 'v', 1), ('set', 't', req_time), ('append', 'h', req_time)]) ) else: # IP is not on blacklist blname self.log.debug("IP address ({0}) is not on {1}.".format(key, blname)) actions.append( ('array_update', 'bl', {'n': blname}, [('set', 'v', 0), ('set', 't', req_time)]) ) # Note: array_update change the record only if the matching element is there, if the IP wasn't on the blacklist before, it does nothing return actions
def setUp(self): self.channel = pycares.Channel(timeout=5.0, tries=1)
def __init__(self): self.channel = pycares.Channel(timeout=5.0, tries=2)
def __init__(self, loop=None): self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb) self._timer = None self._fds = set() self.loop = loop or asyncio.get_event_loop()
def initialize(self) -> None: self.io_loop = IOLoop.current() self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb) self.fds = {} # type: Dict[int, int]
elif r.type == 'PTR': parts.append('%s\t%s' % (txt, r.name)) elif r.type == 'SOA': parts.append('%s\t%s %s %d %d %d %d %d' % (txt, r.nsname, r.hostmaster, r.serial, r.refresh, r.retry, r.expires, r.minttl)) elif r.type == 'SRV': parts.append('%s\t%d %d %d %s' % (txt, r.priority, r.weight, r.port, r.host)) elif r.type == 'TXT': parts.append('%s\t"%s"' % (txt, r.text)) print('\n'.join(parts)) channel = pycares.Channel() if len(sys.argv) not in (2, 3): print('Invalid arguments! Usage: python -m pycares [query_type] hostname') sys.exit(1) if len(sys.argv) == 2: _, hostname = sys.argv qtype = 'A' else: _, qtype, hostname = sys.argv try: query_type = getattr(pycares, 'QUERY_TYPE_%s' % qtype.upper()) except Exception: print('Invalid query type: %s' % qtype)
def __init__(self): self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb) self.poll = selectors.DefaultSelector() self._fd_map = set()
def __init__(self, loop): self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb) self.loop = loop self._timer = pyuv.Timer(self.loop) self._fd_map = {}
def setUp(self): self.channel = pycares.Channel(timeout=10.0, tries=1, servers=['8.8.8.8', '8.8.4.4']) self.is_ci = os.environ.get('APPVEYOR') or os.environ.get( 'TRAVIS') or os.environ.get('GITHUB_ACTION')