Ejemplo n.º 1
0
    def gethostbyname(hostname):
        """:func:`socket.gethostbyname` implemented using :mod:`gevent.dns`.

        Differs in the following ways:

        * raises :class:`DNSError` (a subclass of :class:`socket.gaierror`) with dns error
          codes instead of standard socket error codes
        * does not support ``/etc/hosts`` but calls the original :func:`socket.gethostbyname`
          if *hostname* has no dots
        * does not iterate through all addresses, instead picks a random one each time
        """
        # TODO: this is supposed to iterate through all the addresses
        # could use a global dict(hostname, iter)
        # - fix these nasty hacks for localhost, ips, etc.
        if not isinstance(hostname, str) or '.' not in hostname:
            return _socket.gethostbyname(hostname)
        if _ip4_re.match(hostname):
            return hostname
        if hostname == _socket.gethostname():
            return _socket.gethostbyname(hostname)
        addrs = None
        try:
            _ttl, addrs = resolve_ipv4(hostname)
        except:
            _ttl, addrs = resolve_ipv6(hostname)
            return inet_ntop(AF_INET6, random.choice(addrs))
        else:
            return inet_ntop(AF_INET, random.choice(addrs))
Ejemplo n.º 2
0
    def gethostbyname(hostname):
        """:func:`socket.gethostbyname` implemented using :mod:`gevent.dns`.

        Differs in the following ways:

        * raises :class:`DNSError` (a subclass of :class:`socket.gaierror`) with dns error
          codes instead of standard socket error codes
        * does not support ``/etc/hosts`` but calls the original :func:`socket.gethostbyname`
          if *hostname* has no dots
        * does not iterate through all addresses, instead picks a random one each time
        """
        # TODO: this is supposed to iterate through all the addresses
        # could use a global dict(hostname, iter)
        # - fix these nasty hacks for localhost, ips, etc.
        if not isinstance(hostname, str) or '.' not in hostname:
            return _socket.gethostbyname(hostname)
        if _ip4_re.match(hostname):
            return hostname
        if hostname == _socket.gethostname():
            return _socket.gethostbyname(hostname)
        addrs = None
        try:
            _ttl, addrs = resolve_ipv4(hostname)
        except:
            _ttl, addrs = resolve_ipv6(hostname)
            return inet_ntop(AF_INET6, random.choice(addrs))
        else:
            return inet_ntop(AF_INET, random.choice(addrs))
Ejemplo n.º 3
0
    def getaddrinfo(host, port, *args, **kwargs):
        """*Some* approximation of :func:`socket.getaddrinfo` implemented using :mod:`gevent.dns`.

        If *host* is not a string, does not has any dots or is a numeric IP address, then
        the standard :func:`socket.getaddrinfo` is called.

        Otherwise, calls either :func:`resolve_ipv4` or :func:`resolve_ipv6` and
        formats the result the way :func:`socket.getaddrinfo` does it.

        Differs in the following ways:

        * raises :class:`DNSError` (a subclass of :class:`gaierror`) with libevent-dns error
          codes instead of standard socket error codes
        * IPv6 support is untested.
        * AF_UNSPEC only tries IPv4
        * only supports TCP, UDP, IP protocols
        * port must be numeric, does not support string service names. see socket.getservbyname
        * *flags* argument is ignored

        Additionally, supports *evdns_flags* keyword arguments (default ``0``) that is passed
        to :mod:`dns` functions.
        """
        family, socktype, proto, _flags = args + (None, ) * (4 - len(args))
        if not isinstance(host, str) or '.' not in host or _ip4_re.match(host):
            return _socket.getaddrinfo(host, port, *args)

        evdns_flags = kwargs.pop('evdns_flags', 0)
        if kwargs:
            raise TypeError('Unsupported keyword arguments: %s' %
                            (kwargs.keys(), ))

        if family in (None, AF_INET, AF_UNSPEC):
            family = AF_INET
            # TODO: AF_UNSPEC means try both AF_INET and AF_INET6
            _ttl, addrs = resolve_ipv4(host, evdns_flags)
        elif family == AF_INET6:
            _ttl, addrs = resolve_ipv6(host, evdns_flags)
        else:
            raise NotImplementedError(
                'family is not among AF_UNSPEC/AF_INET/AF_INET6: %r' %
                (family, ))

        socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)]
        if socktype is not None:
            socktype_proto = [(x, y) for (x, y) in socktype_proto
                              if socktype == x]
        if proto is not None:
            socktype_proto = [(x, y) for (x, y) in socktype_proto
                              if proto == y]

        result = []
        for addr in addrs:
            for socktype, proto in socktype_proto:
                result.append(
                    (family, socktype, proto, '', (inet_ntop(family,
                                                             addr), port)))
        return result
Ejemplo n.º 4
0
    def getaddrinfo(host, port, *args, **kwargs):
        """*Some* approximation of :func:`socket.getaddrinfo` implemented using :mod:`gevent.dns`.

        If *host* is not a string, does not has any dots or is a numeric IP address, then
        the standard :func:`socket.getaddrinfo` is called.

        Otherwise, calls either :func:`resolve_ipv4` or :func:`resolve_ipv6` and
        formats the result the way :func:`socket.getaddrinfo` does it.

        Differs in the following ways:

        * raises :class:`DNSError` (a subclass of :class:`gaierror`) with libevent-dns error
          codes instead of standard socket error codes
        * IPv6 support is untested.
        * AF_UNSPEC only tries IPv4
        * only supports TCP, UDP, IP protocols
        * port must be numeric, does not support string service names. see socket.getservbyname
        * *flags* argument is ignored

        Additionally, supports *evdns_flags* keyword arguments (default ``0``) that is passed
        to :mod:`dns` functions.
        """
        family, socktype, proto, _flags = args + (None, ) * (4 - len(args))
        if isinstance(host, unicode):
            host = host.encode('idna')
        if not isinstance(host, str) or '.' not in host or _ip4_re.match(host):
            return _socket.getaddrinfo(host, port, *args)

        evdns_flags = kwargs.pop('evdns_flags', 0)
        if kwargs:
            raise TypeError('Unsupported keyword arguments: %s' % (kwargs.keys(), ))

        if family in (None, AF_INET, AF_UNSPEC):
            family = AF_INET
            # TODO: AF_UNSPEC means try both AF_INET and AF_INET6
            _ttl, addrs = resolve_ipv4(host, evdns_flags)
        elif family == AF_INET6:
            _ttl, addrs = resolve_ipv6(host, evdns_flags)
        else:
            raise NotImplementedError('family is not among AF_UNSPEC/AF_INET/AF_INET6: %r' % (family, ))

        socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)]
        if socktype:
            socktype_proto = [(x, y) for (x, y) in socktype_proto if socktype == x]
        if proto:
            socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y]

        result = []
        for addr in addrs:
            for socktype, proto in socktype_proto:
                result.append((family, socktype, proto, '', (inet_ntop(family, addr), port)))
        return result
Ejemplo n.º 5
0
        if socktype:
            socktype_proto = [(x, y) for (x, y) in socktype_proto
                              if socktype == x]
        if proto:
            socktype_proto = [(x, y) for (x, y) in socktype_proto
                              if proto == y]

        result = []

        if family == AF_INET:
            for res in resolve_ipv4(host, evdns_flags)[1]:
                sockaddr = (inet_ntop(family, res), port)
                for socktype, proto in socktype_proto:
                    result.append((family, socktype, proto, '', sockaddr))
        elif family == AF_INET6:
            for res in resolve_ipv6(host, evdns_flags)[1]:
                sockaddr = (inet_ntop(family, res), port, 0, 0)
                for socktype, proto in socktype_proto:
                    result.append((family, socktype, proto, '', sockaddr))
        else:

            ipv4_res = None
            ipv6_res = None
            try:
                ipv4_res = resolve_ipv4(host, evdns_flags)[1]
            except:
                pass
            if not ipv4_res:
                ipv4_res = None
                ipv6_res = resolve_ipv6(host, evdns_flags)[1]
Ejemplo n.º 6
0
        socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)]
        if socktype:
            socktype_proto = [(x, y) for (x, y) in socktype_proto if socktype == x]
        if proto:
            socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y]

        result = []

        if family == AF_INET:
            for res in resolve_ipv4(host, evdns_flags)[1]:
                sockaddr = (inet_ntop(family, res), port)
                for socktype, proto in socktype_proto:
                    result.append((family, socktype, proto, '', sockaddr))
        elif family == AF_INET6:
            for res in resolve_ipv6(host, evdns_flags)[1]:
                sockaddr = (inet_ntop(family, res), port, 0, 0)
                for socktype, proto in socktype_proto:
                    result.append((family, socktype, proto, '', sockaddr))
        else:
            failure = None
            job = spawn(wrap_errors(gaierror, resolve_ipv6), host, evdns_flags)
            try:
                try:
                    ipv4_res = resolve_ipv4(host, evdns_flags)[1]
                except gaierror, failure:
                    ipv4_res = None
                ipv6_res = job.get()
                if isinstance(ipv6_res, gaierror):
                    ipv6_res = None
                    if failure is not None: