标签:
class DNSServer(object): @staticmethod def start(): # 缓存队列,收到的请求都先放在这里,然后从这里拿数据处理 DNSServer.deq_cache = Queue(maxsize=deq_size) if deq_size > 0 else Queue() # LRU Cache,使用近期最少使用覆盖原则 DNSServer.dns_cache = pylru.lrucache(lru_size) # 启动协程,循环处理缓存队列 gevent.spawn(_init_cache_queue) # 启动DNS服务器 print ‘Start DNS server at %s:%d\n‘ % (ip, port) dns_server = SocketServer.UDPServer((ip, port), DNSHandler) dns_server.serve_forever()
class DNSHandler(SocketServer.BaseRequestHandler): def handle(self): # 若缓存队列没有存满,把接收到的包放进缓存队列中(存满则直接丢弃包) if not DNSServer.deq_cache.full(): # 缓存队列保存元组:(请求包,请求地址,sock) DNSServer.deq_cache.put((self.request[0], self.client_address, self.request[1]))
def _init_cache_queue(): while True: data, addr, sock = DNSServer.deq_cache.get() gevent.spawn(handler, data, addr, sock)
dns.header.set_qr(dnslib.QR.RESPONSE) qname = dns.q.qname try: dns = dnslib.DNSRecord.parse(data) except Exception as e: print ‘Not a DNS packet.\n‘, e
response = DNSServer.dns_cache.get(qname) if response: # goto 5 else: # goto 6
response[:2] = data[:2]
sock.sendto(response, addr)
answers, soa = query(str(qname).rstrip(‘.‘)) answer_dns = pack_dns(dns, answers, soa) DNSServer.dns_cache[qname] = answer_dns.pack() sock.sendto(answer_dns.pack(), addr)
第一、在开启服务器时将内容全部加载到内存,这样可以去掉LRUCache;
第二、使用redis或mysql之类的数据库;
第三、注意数据的验证,例如判断ip的正则,域名的内容等等。
标签:
原文地址:http://www.cnblogs.com/anpengapple/p/5664500.html