Trees | Indices | Help |
|
---|
|
1 # Copyright (C) 2010-2014 Cuckoo Foundation. 2 # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 3 # See the file 'docs/LICENSE' for copying permission. 4 5 import select 6 import socket 7 import threading 8 9 try: 10 import pycares 11 HAVE_CARES = True 12 except: 13 HAVE_CARES = False 14 15 #try: 16 # import gevent, gevent.socket 17 # HAVE_GEVENT = True 18 #except: 19 HAVE_GEVENT = False 20 21 22 # these are used by all resolvers 23 DNS_TIMEOUT = 5 24 DNS_TIMEOUT_VALUE = "" 25 29 33 34 35 # standard gethostbyname in thread 36 # http://code.activestate.com/recipes/473878/38 """This function will spawn a thread and run the given function 39 using the args, kwargs and return the given default value if the 40 timeout_duration is exceeded. 41 """ 42 class ResultThread(threading.Thread): 43 daemon = True 44 def __init__(self): 45 threading.Thread.__init__(self) 46 self.result, self.error = None, None47 def run(self): 48 try: 49 self.result = func(*args, **kwargs) 50 except Exception, e: 51 self.error = e 52 53 it = ResultThread() 54 it.start() 55 it.join(DNS_TIMEOUT) 56 if it.isAlive(): 57 return DNS_TIMEOUT_VALUE 58 else: 59 if it.error: 60 raise it.error 61 return it.result 62 65 72 73 74 # C-ARES (http://c-ares.haxx.se/)76 # create new c-ares channel 77 careschan = pycares.Channel(timeout=DNS_TIMEOUT, tries=1) 78 79 # if we don't get a response we return the default value 80 result = Resultholder() 81 result.value = DNS_TIMEOUT_VALUE 82 83 def setresult_cb(res, error): 84 # ignore error and just take first result ip (randomized anyway) 85 if res and res.addresses: 86 result.value = res.addresses[0]87 88 # resolve with cb 89 careschan.gethostbyname(name, socket.AF_INET, setresult_cb) 90 91 # now do the actual work 92 readfds, writefds = careschan.getsock() 93 canreadfds, canwritefds, _ = select.select(readfds, writefds, [], 94 DNS_TIMEOUT) 95 for rfd in canreadfds: 96 careschan.process_fd(rfd, -1) 97 98 # if the query did not succeed, setresult was not called and we just 99 # return result destroy the channel first to not leak anything 100 careschan.destroy() 101 return result.value 102 103 # workaround until py3 nonlocal (for c-ares and gevent) 106 107 108 # gevent based resolver with timeout110 result = resolve_gevent_real(name) 111 # if it failed, do this a second time because of strange libevent behavior 112 # basically sometimes the Timeout fires immediately instead of after 113 # DNS_TIMEOUT 114 if result == DNS_TIMEOUT_VALUE: 115 result = resolve_gevent_real(name) 116 return result117119 result = DNS_TIMEOUT_VALUE 120 with gevent.Timeout(DNS_TIMEOUT, False): 121 try: 122 result = gevent.socket.gethostbyname(name) 123 except socket.gaierror: 124 pass 125 126 return result127 128 129 # choose resolver automatically131 if HAVE_CARES: 132 return resolve_cares(name) 133 elif HAVE_GEVENT: 134 return resolve_gevent(name) 135 else: 136 return resolve_thread(name)137 138 # another alias 139 resolve_best = resolve 140
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Apr 7 13:27:49 2014 | http://epydoc.sourceforge.net |