/[straw]/straw/src/lib/LookupManager.py
ViewVC logotype

Diff of /straw/src/lib/LookupManager.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by juri, Thu Jul 24 16:12:46 2003 UTC revision 1.7 by juri, Mon Sep 1 16:19:54 2003 UTC
# Line 3  cvs_id = "$Id$" Line 3  cvs_id = "$Id$"
3  import time  import time
4  import socket  import socket
5  import random  import random
6  import adns, ADNS  from error import log
7    try:
8        import adns, ADNS
9        _have_adns = True
10    except ImportError:
11        log("No ADNS library found, using synchronous name lookups.")
12        _have_adns = False
13    
14  class NameFormatException(Exception):  class NameFormatException(Exception):
15      pass      pass
16    
17  class MyQE(ADNS.QueryEngine):  if _have_adns:
18      def lookup_a_record(self, name, callback, extra):      class MyQE(ADNS.QueryEngine):
19          self.submit(name, adns.rr.A, callback = callback, extra = extra)          def lookup_a_record(self, name, callback, extra):
20                self.submit(name, adns.rr.A, callback = callback, extra = extra)
21  class LookupManager:  
22      namecache = {}      class LookupManager:
23      queryengine = MyQE()          namecache = {}
24                queryengine = MyQE()
25      def __init__(self, mintime=86400, maxtime=259200):  
26          self.mintime = mintime          def __init__(self, mintime=86400, maxtime=259200):
27          self.maxtime = maxtime              self.mintime = mintime
28                self.maxtime = maxtime
29      def _lookup(self, name, callback, cbw):  
30          now = time.time()          def _lookup(self, name, callback, cbw):
31          ip = self.namecache.get(name, None)              now = time.time()
32          expiretime = 0              ip = self.namecache.get(name, None)
33          if ip is not None:              expiretime = 0
34              ip, expiretime = ip              if ip is not None:
35              if now < expiretime:                  ip, expiretime = ip
36                  cbw.cb(ip)                  if now < expiretime:
37                  return                      cbw.cb(ip)
38          self.queryengine.lookup_a_record(name, callback, cbw)                      return
39                self.queryengine.lookup_a_record(name, callback, cbw)
40      def lookup(self, name, callback, data=None):  
41          cbw = CBWrapper(name, callback, data)          def lookup(self, name, callback, data=None):
42          try:              cbw = CBWrapper(name, callback, data)
43              name = name.encode('ascii')              try:
44          except UnicodeError:                  name = name.encode('ascii')
45              raise NameFormatException, "Host names must be ASCII"              except UnicodeError:
46          self._lookup(name, self.adns_callback, cbw)                  raise NameFormatException, "Host names must be ASCII"
47                self._lookup(name, self.adns_callback, cbw)
48                    
49      def adns_callback(self, answer, qname, rr, flags, cbwrapper):          def adns_callback(self, answer, qname, rr, flags, cbwrapper):
50          now = int(time.time())              now = int(time.time())
51          ips = answer[3]              ips = answer[3]
52          ip = None              ip = None
53          if answer[1] and not ips:              if answer[1] and not ips:
54              # we got a cname even though we asked for an a record                  # we got a cname even though we asked for an a record
55              self._lookup(answer[1], self.adns_callback, cbwrapper)                  self._lookup(answer[1], self.adns_callback, cbwrapper)
56              return                  return
57          elif ips:              elif ips:
58              ip = ips[0]                  ip = ips[0]
59              self.namecache[qname] = (ip, now + random.randint(                  self.namecache[qname] = (ip, now+random.randint(self.mintime,
60                  now+self.mintime, now+self.maxtime))                                                                  self.maxtime))
61          cbwrapper.cb(ip)              cbwrapper.cb(ip)
62    
63      def poll(self, timeout=0.1):          def poll(self, timeout=0.1):
64          self.queryengine.run(timeout)              self.queryengine.run(timeout)
65    
66  class CBWrapper:      class CBWrapper:
67      def __init__(self, name, callback, data):          def __init__(self, name, callback, data):
68          self.name = name              self.name = name
69          self.data = data              self.data = data
70          self.callback = callback              self.callback = callback
71    
72            def cb(self, ip):
73                self.callback(self.name, ip, self.data)
74    
75    else:
76        class LookupManager:
77            NameFormatException = NameFormatException
78            namecache = {}
79    
80            def __init__(self, mintime=86400, maxtime=259200):
81                self.mintime = mintime
82                self.maxtime = maxtime
83    
84            def _lookup(self, name):
85                now = time.time()
86                ip = self.namecache.get(name, None)
87                expiretime = 0
88                if ip is not None:
89                    ip, expiretime = ip
90                    if now < expiretime:
91                        return ip
92                try:
93                    ip = socket.gethostbyname(name)
94                except socket.error:
95                    ip = None
96                now = int(time.time())
97                self.namecache[name] = (ip, now + random.randint(self.mintime,
98                                                                 self.maxtime))
99                return ip
100    
101            def lookup(self, name, callback, data=None):
102                try:
103                    name = name.encode('ascii')
104                except UnicodeError:
105                    raise NameFormatException, "Host names must be ASCII"
106                ip = self._lookup(name)
107                callback(name, ip, data)
108    
109      def cb(self, ip):          def poll(self, timeout=0.1):
110          self.callback(self.name, ip, self.data)              pass
111    

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26