update dns
This commit is contained in:
parent
de5461a17e
commit
cdd333ea97
1 changed files with 36 additions and 6 deletions
|
@ -22,6 +22,7 @@
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
import os
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import logging
|
import logging
|
||||||
|
@ -173,7 +174,7 @@ def parse_response(data):
|
||||||
# res_ra = header[2] & 128
|
# res_ra = header[2] & 128
|
||||||
res_rcode = header[2] & 15
|
res_rcode = header[2] & 15
|
||||||
assert res_tc == 0
|
assert res_tc == 0
|
||||||
assert res_rcode == 0
|
assert res_rcode in [0, 3]
|
||||||
res_qdcount = header[3]
|
res_qdcount = header[3]
|
||||||
res_ancount = header[4]
|
res_ancount = header[4]
|
||||||
res_nscount = header[5]
|
res_nscount = header[5]
|
||||||
|
@ -238,15 +239,19 @@ class DNSResolver(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._loop = None
|
self._loop = None
|
||||||
self._request_id = 1
|
self._request_id = 1
|
||||||
|
self._hosts = {}
|
||||||
self._hostname_status = {}
|
self._hostname_status = {}
|
||||||
self._hostname_to_cb = {}
|
self._hostname_to_cb = {}
|
||||||
self._cb_to_hostname = {}
|
self._cb_to_hostname = {}
|
||||||
self._cache = lru_cache.LRUCache(timeout=300)
|
self._cache = lru_cache.LRUCache(timeout=300)
|
||||||
self._last_time = time.time()
|
self._last_time = time.time()
|
||||||
self._sock = None
|
self._sock = None
|
||||||
self._parse_config()
|
self._parse_resolv()
|
||||||
|
self._parse_hosts()
|
||||||
|
# TODO monitor hosts change and reload hosts
|
||||||
|
# TODO parse /etc/gai.conf and follow its rules
|
||||||
|
|
||||||
def _parse_config(self):
|
def _parse_resolv(self):
|
||||||
try:
|
try:
|
||||||
with open('/etc/resolv.conf', 'rb') as f:
|
with open('/etc/resolv.conf', 'rb') as f:
|
||||||
servers = []
|
servers = []
|
||||||
|
@ -255,7 +260,7 @@ class DNSResolver(object):
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if line:
|
if line:
|
||||||
if line.startswith('nameserver'):
|
if line.startswith('nameserver'):
|
||||||
parts = line.split(' ')
|
parts = line.split()
|
||||||
if len(parts) >= 2:
|
if len(parts) >= 2:
|
||||||
server = parts[1]
|
server = parts[1]
|
||||||
if is_ip(server):
|
if is_ip(server):
|
||||||
|
@ -268,6 +273,25 @@ class DNSResolver(object):
|
||||||
pass
|
pass
|
||||||
self._dns_server = ('8.8.8.8', 53)
|
self._dns_server = ('8.8.8.8', 53)
|
||||||
|
|
||||||
|
def _parse_hosts(self):
|
||||||
|
etc_path = '/etc/hosts'
|
||||||
|
if os.environ.__contains__('WINDIR'):
|
||||||
|
etc_path = os.environ['WINDIR'] + '/system32/drivers/etc/hosts'
|
||||||
|
try:
|
||||||
|
with open(etc_path, 'rb') as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
line = line.strip()
|
||||||
|
parts = line.split()
|
||||||
|
if len(parts) >= 2:
|
||||||
|
ip = parts[0]
|
||||||
|
if is_ip(ip):
|
||||||
|
for i in xrange(1, len(parts)):
|
||||||
|
hostname = parts[i]
|
||||||
|
if hostname:
|
||||||
|
self._hosts[hostname] = ip
|
||||||
|
except IOError:
|
||||||
|
self._hosts['localhost'] = '127.0.0.1'
|
||||||
|
|
||||||
def add_to_loop(self, loop):
|
def add_to_loop(self, loop):
|
||||||
if self._loop:
|
if self._loop:
|
||||||
raise Exception('already add to loop')
|
raise Exception('already add to loop')
|
||||||
|
@ -356,11 +380,15 @@ class DNSResolver(object):
|
||||||
if not hostname:
|
if not hostname:
|
||||||
callback(None, Exception('empty hostname'))
|
callback(None, Exception('empty hostname'))
|
||||||
elif is_ip(hostname):
|
elif is_ip(hostname):
|
||||||
callback(hostname, None)
|
callback((hostname, hostname), None)
|
||||||
|
elif self._hosts.__contains__(hostname):
|
||||||
|
logging.debug('hit hosts: %s', hostname)
|
||||||
|
ip = self._hosts[hostname]
|
||||||
|
callback((hostname, ip), None)
|
||||||
elif self._cache.__contains__(hostname):
|
elif self._cache.__contains__(hostname):
|
||||||
logging.debug('hit cache: %s', hostname)
|
logging.debug('hit cache: %s', hostname)
|
||||||
ip = self._cache[hostname]
|
ip = self._cache[hostname]
|
||||||
callback(ip, None)
|
callback((hostname, ip), None)
|
||||||
else:
|
else:
|
||||||
arr = self._hostname_to_cb.get(hostname, None)
|
arr = self._hostname_to_cb.get(hostname, None)
|
||||||
if not arr:
|
if not arr:
|
||||||
|
@ -390,6 +418,8 @@ def test():
|
||||||
|
|
||||||
for hostname in ['www.google.com',
|
for hostname in ['www.google.com',
|
||||||
'8.8.8.8',
|
'8.8.8.8',
|
||||||
|
'localhost',
|
||||||
|
'activate.adobe.com',
|
||||||
'www.twitter.com',
|
'www.twitter.com',
|
||||||
'ipv6.google.com',
|
'ipv6.google.com',
|
||||||
'ipv6.l.google.com',
|
'ipv6.l.google.com',
|
||||||
|
|
Loading…
Reference in a new issue