1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
cdef extern from "evdns.h":
ctypedef void (*evdns_handler)(int result, char t, int count, int ttl,
void *addrs, void *arg)
int evdns_init()
char *evdns_err_to_string(int err)
int evdns_resolve_ipv4(char *name, int flags, evdns_handler callback,
void *arg)
int evdns_resolve_ipv6(char *name, int flags, evdns_handler callback,
void *arg)
int evdns_resolve_reverse(char *ip, int flags, evdns_handler callback,
void *arg)
int evdns_resolve_reverse_ipv6(char *ip, int flags, evdns_handler callback,
void *arg)
void evdns_shutdown(int fail_requests)
# Result codes
DNS_ERR_NONE = 0
DNS_ERR_FORMAT = 1
DNS_ERR_SERVERFAILED = 2
DNS_ERR_NOTEXIST = 3
DNS_ERR_NOTIMPL = 4
DNS_ERR_REFUSED = 5
DNS_ERR_TRUNCATED = 65
DNS_ERR_UNKNOWN = 66
DNS_ERR_TIMEOUT = 67
DNS_ERR_SHUTDOWN = 68
# Types
DNS_IPv4_A = 1
DNS_PTR = 2
DNS_IPv6_AAAA = 3
# Flags
DNS_QUERY_NO_SEARCH = 1
__evdns_cbargs = {}
def dns_init():
"""Initialize async DNS resolver."""
evdns_init()
__evdns_cbargs.clear()
cdef void __evdns_callback(int result, char t, int count, int ttl,
void *addrs, void *arg) with gil:
cdef int i
(callback, args) = __evdns_cbargs.pop(<int>arg)
if t == DNS_IPv4_A:
x = []
for i from 0 <= i < count:
x.append(PyString_FromStringAndSize(<char *>addrs + (i * 4), 4))
elif t == DNS_IPv6_AAAA:
x = []
for i from 0 <= i < count:
x.append(PyString_FromStringAndSize(<char *>addrs + (i * 16), 16))
elif t == DNS_PTR and count == 1: # only 1 PTR possible
x = PyString_FromString((<char **>addrs)[0])
else:
x = None
try:
callback(result, t, ttl, x, args)
except:
__event_abort()
def dns_resolve_ipv4(char *name, int flags, callback, *args):
"""Lookup an A record for a given name.
Arguments:
name -- DNS hostname
flags -- either 0 or DNS_QUERY_NO_SEARCH
callback -- callback with (result, type, ttl, addrs, *args) prototype
args -- option callback arguments
"""
cdef int i
t = (callback, args)
i = id(t)
__evdns_cbargs[i] = t
evdns_resolve_ipv4(name, flags, __evdns_callback, <void *>i)
def dns_resolve_ipv6(char *name, int flags, callback, *args):
"""Lookup an AAAA record for a given name.
Arguments:
name -- DNS hostname
flags -- either 0 or DNS_QUERY_NO_SEARCH
callback -- callback with (result, type, ttl, addrs, *args) prototype
args -- option callback arguments
"""
cdef int i
t = (callback, args)
i = id(t)
__evdns_cbargs[i] = t
evdns_resolve_ipv6(name, flags, __evdns_callback, <void *>i)
def dns_resolve_reverse(char *ip, int flags, callback, *args):
"""Lookup a PTR record for a given IPv4 address.
Arguments:
name -- IPv4 address (as 4-byte binary string)
flags -- either 0 or DNS_QUERY_NO_SEARCH
callback -- callback with (result, type, ttl, addrs, *args) prototype
args -- option callback arguments
"""
cdef int i
t = (callback, args)
i = id(t)
__evdns_cbargs[i] = t
evdns_resolve_reverse(ip, flags, __evdns_callback, <void *>i)
def dns_resolve_reverse_ipv6(char *ip, int flags, callback, *args):
"""Lookup a PTR record for a given IPv6 address.
Arguments:
name -- IPv6 address (as 16-byte binary string)
flags -- either 0 or DNS_QUERY_NO_SEARCH
callback -- callback with (result, type, ttl, addrs, *args) prototype
args -- option callback arguments
"""
cdef int i
t = (callback, args)
i = id(t)
__evdns_cbargs[i] = t
evdns_resolve_reverse(ip, flags, __evdns_callback, <void *>i)
def dns_shutdown(int fail_requests=0):
"""Shutdown the async DNS resolver and terminate all active requests."""
evdns_shutdown(fail_requests)
__evdns_cbargs.clear()
|