Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
 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()
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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')
Exemplo n.º 5
0
    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()
Exemplo n.º 6
0
 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()
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
 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
Exemplo n.º 9
0
 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)
Exemplo n.º 10
0
 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)
Exemplo n.º 11
0
 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)
Exemplo n.º 12
0
 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)
Exemplo n.º 13
0
 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
Exemplo n.º 14
0
    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()
Exemplo n.º 15
0
 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)
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
 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
Exemplo n.º 18
0
    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
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
 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!")
Exemplo n.º 22
0
    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
Exemplo n.º 23
0
 def setUp(self):
     self.channel = pycares.Channel(timeout=5.0, tries=1)
Exemplo n.º 24
0
 def __init__(self):
     self.channel = pycares.Channel(timeout=5.0, tries=2)
Exemplo n.º 25
0
 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()
Exemplo n.º 26
0
 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]
Exemplo n.º 27
0
            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)
Exemplo n.º 28
0
 def __init__(self):
     self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb)
     self.poll = selectors.DefaultSelector()
     self._fd_map = set()
Exemplo n.º 29
0
 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 = {}
Exemplo n.º 30
0
 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')