Remove other resolvers
This commit is contained in:
parent
a2e5924146
commit
17c482205e
|
@ -35,22 +35,6 @@ from nbxmpp.idlequeue import IdleCommand
|
|||
from gi.repository import Gio, GLib
|
||||
|
||||
|
||||
# it is good to check validity of arguments, when calling system commands
|
||||
ns_type_pattern = re.compile('^[a-z]+$')
|
||||
|
||||
# match srv host_name
|
||||
host_pattern = re.compile('^[a-z0-9\-._]*[a-z0-9]\.[a-z]{2,}$')
|
||||
|
||||
try:
|
||||
#raise ImportError("Manually disabled libasync")
|
||||
import libasyncns
|
||||
USE_LIBASYNCNS = True
|
||||
log.info("libasyncns-python loaded")
|
||||
except ImportError:
|
||||
USE_LIBASYNCNS = False
|
||||
log.debug("Import of libasyncns-python failed, getaddrinfo will block", exc_info=True)
|
||||
|
||||
|
||||
def get_resolver(idlequeue):
|
||||
return GioResolver()
|
||||
|
||||
|
@ -101,296 +85,6 @@ class CommonResolver():
|
|||
def start_resolve(self, host, type_):
|
||||
pass
|
||||
|
||||
# FIXME: API usage is not consistent! This one requires that process is called
|
||||
class LibAsyncNSResolver(CommonResolver):
|
||||
"""
|
||||
Asynchronous resolver using libasyncns-python. process() method has to be
|
||||
called in order to proceed the pending requests. Based on patch submitted by
|
||||
Damien Thebault.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.asyncns = libasyncns.Asyncns()
|
||||
CommonResolver.__init__(self)
|
||||
|
||||
def start_resolve(self, host, type_):
|
||||
type_ = libasyncns.ns_t_srv
|
||||
if type_ == 'txt': type_ = libasyncns.ns_t_txt
|
||||
resq = self.asyncns.res_query(host, libasyncns.ns_c_in, type_)
|
||||
resq.userdata = {'host':host, 'type':type_}
|
||||
|
||||
# getaddrinfo to be done
|
||||
#def resolve_name(self, dname, callback):
|
||||
#resq = self.asyncns.getaddrinfo(dname)
|
||||
#resq.userdata = {'callback':callback, 'dname':dname}
|
||||
|
||||
def _on_ready(self, host, type_, result_list):
|
||||
if type_ == libasyncns.ns_t_srv: type_ = 'srv'
|
||||
elif type_ == libasyncns.ns_t_txt: type_ = 'txt'
|
||||
|
||||
CommonResolver._on_ready(self, host, type_, result_list)
|
||||
|
||||
def process(self):
|
||||
try:
|
||||
self.asyncns.wait(False)
|
||||
resq = self.asyncns.get_next()
|
||||
except:
|
||||
return True
|
||||
if type(resq) == libasyncns.ResQuery:
|
||||
# TXT or SRV result
|
||||
while resq is not None:
|
||||
try:
|
||||
rl = resq.get_done()
|
||||
except Exception:
|
||||
rl = []
|
||||
hosts = []
|
||||
requested_type = resq.userdata['type']
|
||||
requested_host = resq.userdata['host']
|
||||
if rl:
|
||||
for r in rl:
|
||||
if r['type'] != requested_type:
|
||||
# Answer doesn't contain valid SRV data
|
||||
continue
|
||||
r['prio'] = r['pref']
|
||||
hosts.append(r)
|
||||
self._on_ready(host=requested_host, type_=requested_type,
|
||||
result_list=hosts)
|
||||
try:
|
||||
resq = self.asyncns.get_next()
|
||||
except Exception:
|
||||
resq = None
|
||||
elif type(resq) == libasyncns.AddrInfoQuery:
|
||||
# getaddrinfo result (A or AAAA)
|
||||
rl = resq.get_done()
|
||||
resq.userdata['callback'](resq.userdata['dname'], rl)
|
||||
return True
|
||||
|
||||
|
||||
class NSLookupResolver(CommonResolver):
|
||||
"""
|
||||
Asynchronous DNS resolver calling nslookup. Processing of pending requests
|
||||
is invoked from idlequeue which is watching file descriptor of pipe of
|
||||
stdout of nslookup process.
|
||||
"""
|
||||
|
||||
def __init__(self, idlequeue):
|
||||
self.idlequeue = idlequeue
|
||||
self.process = False
|
||||
CommonResolver.__init__(self)
|
||||
|
||||
def parse_srv_result(self, fqdn, result):
|
||||
"""
|
||||
Parse the output of nslookup command and return list of properties:
|
||||
'host', 'port','weight', 'priority' corresponding to the found srv hosts
|
||||
"""
|
||||
if os.name == 'nt':
|
||||
return self._parse_srv_result_nt(fqdn, result)
|
||||
elif os.name == 'posix':
|
||||
return self._parse_srv_result_posix(fqdn, result)
|
||||
|
||||
def _parse_srv_result_nt(self, fqdn, result):
|
||||
# output from win32 nslookup command
|
||||
if not result:
|
||||
return []
|
||||
hosts = []
|
||||
result = result.decode(sys.stdout.encoding)
|
||||
lines = result.replace('\r', '').split('\n')
|
||||
current_host = None
|
||||
for line in lines:
|
||||
line = line.lstrip()
|
||||
if line == '':
|
||||
continue
|
||||
if line.startswith(fqdn):
|
||||
rest = line[len(fqdn):]
|
||||
if rest.find('service') > -1:
|
||||
current_host = {}
|
||||
elif isinstance(current_host, dict):
|
||||
res = line.strip().split('=')
|
||||
if len(res) != 2:
|
||||
if len(current_host) == 4:
|
||||
hosts.append(current_host)
|
||||
current_host = None
|
||||
continue
|
||||
prop_type = res[0].strip()
|
||||
prop_value = res[1].strip()
|
||||
if prop_type.find('prio') > -1:
|
||||
try:
|
||||
current_host['prio'] = int(prop_value)
|
||||
except ValueError:
|
||||
continue
|
||||
elif prop_type.find('weight') > -1:
|
||||
try:
|
||||
current_host['weight'] = int(prop_value)
|
||||
except ValueError:
|
||||
continue
|
||||
elif prop_type.find('port') > -1:
|
||||
try:
|
||||
current_host['port'] = int(prop_value)
|
||||
except ValueError:
|
||||
continue
|
||||
elif prop_type.find('host') > -1:
|
||||
# strip '.' at the end of hostname
|
||||
if prop_value[-1] == '.':
|
||||
prop_value = prop_value[:-1]
|
||||
current_host['host'] = prop_value
|
||||
if len(current_host) == 4:
|
||||
hosts.append(current_host)
|
||||
current_host = None
|
||||
return hosts
|
||||
|
||||
def _parse_srv_result_posix(self, fqdn, result):
|
||||
# typical output of bind-tools nslookup command:
|
||||
# _xmpp-client._tcp.jabber.org service = 30 30 5222 jabber.org.
|
||||
if not result:
|
||||
return []
|
||||
ufqdn = helpers.ascii_to_idn(fqdn) # Unicode domain name
|
||||
hosts = []
|
||||
lines = result.split('\n')
|
||||
for line in lines:
|
||||
if line == '':
|
||||
continue
|
||||
domain = None
|
||||
if line.startswith(fqdn):
|
||||
domain = fqdn # For nslookup 9.5
|
||||
elif line.startswith(ufqdn):
|
||||
domain = ufqdn # For nslookup 9.6
|
||||
if domain:
|
||||
rest = line[len(domain):].split('=')
|
||||
if len(rest) != 2:
|
||||
continue
|
||||
answer_type, props_str = rest
|
||||
if answer_type.strip() != 'service':
|
||||
continue
|
||||
props = props_str.strip().split(' ')
|
||||
if len(props) < 4:
|
||||
continue
|
||||
prio, weight, port, host = props[-4:]
|
||||
if host[-1] == '.':
|
||||
host = host[:-1]
|
||||
try:
|
||||
prio = int(prio)
|
||||
weight = int(weight)
|
||||
port = int(port)
|
||||
except ValueError:
|
||||
continue
|
||||
hosts.append({'host': host, 'port': port, 'weight': weight,
|
||||
'prio': prio})
|
||||
return hosts
|
||||
|
||||
def _on_ready(self, host, type_, result):
|
||||
# nslookup finished, parse the result and call the handlers
|
||||
result_list = self.parse_srv_result(host, result)
|
||||
CommonResolver._on_ready(self, host, type_, result_list)
|
||||
|
||||
def start_resolve(self, host, type_):
|
||||
"""
|
||||
Spawn new nslookup process and start waiting for results
|
||||
"""
|
||||
ns = NsLookup(self._on_ready, host, type_)
|
||||
ns.set_idlequeue(self.idlequeue)
|
||||
ns.commandtimeout = 20
|
||||
ns.start()
|
||||
|
||||
|
||||
class HostResolver(CommonResolver):
|
||||
"""
|
||||
Asynchronous DNS resolver calling host. Processing of pending requests
|
||||
is invoked from idlequeue which is watching file descriptor of pipe of
|
||||
stdout of host process.
|
||||
"""
|
||||
|
||||
def __init__(self, idlequeue):
|
||||
self.idlequeue = idlequeue
|
||||
self.process = False
|
||||
CommonResolver.__init__(self)
|
||||
|
||||
def parse_srv_result(self, fqdn, result):
|
||||
"""
|
||||
Parse the output of host command and return list of properties:
|
||||
'host', 'port','weight', 'priority' corresponding to the found srv hosts
|
||||
"""
|
||||
# typical output of host command:
|
||||
# _xmpp-client._tcp.jabber.org has SRV record 30 30 5222 jabber.org.
|
||||
if not result:
|
||||
return []
|
||||
ufqdn = helpers.ascii_to_idn(fqdn) # Unicode domain name
|
||||
hosts = []
|
||||
lines = result.split('\n')
|
||||
for line in lines:
|
||||
if line == '':
|
||||
continue
|
||||
domain = None
|
||||
if line.startswith(fqdn):
|
||||
domain = fqdn # For nslookup 9.5
|
||||
elif line.startswith(ufqdn):
|
||||
domain = ufqdn # For nslookup 9.6
|
||||
if domain:
|
||||
# add 4 for ' has' after domain name
|
||||
rest = line[len(domain)+4:].split('record')
|
||||
if len(rest) != 2:
|
||||
continue
|
||||
answer_type, props_str = rest
|
||||
if answer_type.strip() != 'SRV':
|
||||
continue
|
||||
props = props_str.strip().split(' ')
|
||||
if len(props) < 4:
|
||||
continue
|
||||
prio, weight, port, host = props[-4:]
|
||||
if host[-1] == '.':
|
||||
host = host[:-1]
|
||||
try:
|
||||
prio = int(prio)
|
||||
weight = int(weight)
|
||||
port = int(port)
|
||||
except ValueError:
|
||||
continue
|
||||
hosts.append({'host': host, 'port': port, 'weight': weight,
|
||||
'prio': prio})
|
||||
return hosts
|
||||
|
||||
def _on_ready(self, host, type_, result):
|
||||
# host finished, parse the result and call the handlers
|
||||
result_list = self.parse_srv_result(host, result)
|
||||
CommonResolver._on_ready(self, host, type_, result_list)
|
||||
|
||||
def start_resolve(self, host, type_):
|
||||
"""
|
||||
Spawn new nslookup process and start waiting for results
|
||||
"""
|
||||
ns = Host(self._on_ready, host, type_)
|
||||
ns.set_idlequeue(self.idlequeue)
|
||||
ns.commandtimeout = 20
|
||||
ns.start()
|
||||
|
||||
class NsLookup(IdleCommand):
|
||||
def __init__(self, on_result, host='_xmpp-client', type_='srv'):
|
||||
IdleCommand.__init__(self, on_result)
|
||||
self.commandtimeout = 10
|
||||
self.host = host.lower()
|
||||
self.type_ = type_.lower()
|
||||
if not host_pattern.match(self.host):
|
||||
# invalid host name
|
||||
log.error('Invalid host: %s' % self.host)
|
||||
self.canexecute = False
|
||||
return
|
||||
if not ns_type_pattern.match(self.type_):
|
||||
log.error('Invalid querytype: %s' % self.type_)
|
||||
self.canexecute = False
|
||||
return
|
||||
|
||||
def _compose_command_args(self):
|
||||
return ['nslookup', '-type=' + self.type_, self.host]
|
||||
|
||||
def _return_result(self):
|
||||
if self.result_handler:
|
||||
self.result_handler(self.host, self.type_, self.result)
|
||||
self.result_handler = None
|
||||
|
||||
|
||||
class Host(NsLookup):
|
||||
def _compose_command_args(self):
|
||||
return ['host', '-t', self.type_, self.host]
|
||||
|
||||
|
||||
class GioResolver(CommonResolver):
|
||||
"""
|
||||
|
|
|
@ -2748,10 +2748,6 @@ class Interface:
|
|||
GLib.timeout_add_seconds(gajim.config.get(
|
||||
'check_idle_every_foo_seconds'), self.read_sleepy)
|
||||
|
||||
# when using libasyncns we need to process resolver in regular intervals
|
||||
if resolver.USE_LIBASYNCNS:
|
||||
GLib.timeout_add(200, gajim.resolver.process)
|
||||
|
||||
def remote_init():
|
||||
if gajim.config.get('remote_control'):
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue