1
2
3
4
5
6 import select
7 import socket
8 import threading
9
10 try:
11 import pycares
12 HAVE_CARES = True
13 except:
14 HAVE_CARES = False
15
16
17
18
19
20 HAVE_GEVENT = False
21
22
23
24 DNS_TIMEOUT = 5
25 DNS_TIMEOUT_VALUE = ""
26
30
34
35
36
37
39 """This function will spawn a thread and run the given function
40 using the args, kwargs and return the given default value if the
41 timeout_duration is exceeded.
42 """
43 class ResultThread(threading.Thread):
44 daemon = True
45 def __init__(self):
46 threading.Thread.__init__(self)
47 self.result, self.error = None, None
48 def run(self):
49 try:
50 self.result = func(*args, **kwargs)
51 except Exception, e:
52 self.error = e
53
54 it = ResultThread()
55 it.start()
56 it.join(DNS_TIMEOUT)
57 if it.isAlive():
58 return DNS_TIMEOUT_VALUE
59 else:
60 if it.error:
61 raise it.error
62 return it.result
63
66
73
74
75
77
78 careschan = pycares.Channel(timeout=DNS_TIMEOUT, tries=1)
79
80
81 result = Resultholder()
82 result.value = DNS_TIMEOUT_VALUE
83
84 def setresult_cb(res, error):
85
86 if res and res.addresses:
87 result.value = res.addresses[0]
88
89
90 careschan.gethostbyname(name, socket.AF_INET, setresult_cb)
91
92
93 readfds, writefds = careschan.getsock()
94 canreadfds, canwritefds, _ = select.select(readfds, writefds, [],
95 DNS_TIMEOUT)
96 for rfd in canreadfds:
97 careschan.process_fd(rfd, -1)
98
99
100
101 careschan.destroy()
102 return result.value
103
104
107
108
109
110 """def resolve_gevent(name):
111 result = resolve_gevent_real(name)
112 # if it failed, do this a second time because of strange libevent behavior
113 # basically sometimes the Timeout fires immediately instead of after
114 # DNS_TIMEOUT
115 if result == DNS_TIMEOUT_VALUE:
116 result = resolve_gevent_real(name)
117 return result
118
119 def resolve_gevent_real(name):
120 result = DNS_TIMEOUT_VALUE
121 with gevent.Timeout(DNS_TIMEOUT, False):
122 try:
123 result = gevent.socket.gethostbyname(name)
124 except socket.gaierror:
125 pass
126
127 return result
128 """
129
130
138
139
140 resolve_best = resolve
141