X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/cc72e4b3cc435903ac989d31037806d607f86c7d..ad36789130f4756ba2a27ed9bb8b5ab62a21ce7d:/peerdb/tripe-newpeers.in?ds=inline diff --git a/peerdb/tripe-newpeers.in b/peerdb/tripe-newpeers.in index 88d31549..202cea8c 100644 --- a/peerdb/tripe-newpeers.in +++ b/peerdb/tripe-newpeers.in @@ -34,6 +34,7 @@ import cdb as CDB from sys import stdin, stdout, exit, argv import re as RX import os as OS +import socket as S from cStringIO import StringIO ###-------------------------------------------------------------------------- @@ -71,14 +72,14 @@ class ResolvingHost (object): def __init__(me, name): """Make a new resolving-host object for the host NAME.""" me.name = name - me.addr = { 'INET': [] } + me.addr = { 'INET': [], 'INET6': [] } me.failure = None def addaddr(me, af, addr): """ Add the address ADDR with address family AF. - The address family must currently be `INET'. + The address family may be `INET' or `INET6'. """ me.addr[af].append(addr) @@ -93,17 +94,19 @@ class ResolvingHost (object): if me.failure is not None: raise ResolverFailure(me.name, me.failure) aa = [] a4 = me.addr['INET'] + a6 = me.addr['INET6'] all, any = False, False for ch in flags: if ch == '*': all = True elif ch == '4': aa += a4; any = True + elif ch == '6': aa += a6; any = True else: raise ValueError("unknown address-resolution flag `%s'" % ch) - if not any: aa = a4 + if not any: aa = a4 + a6 if not aa: raise ResolverFailure(me.name, 'no matching addresses found') if not all: aa = [aa[0]] return aa -class BulkResolver (object): +class BaseBulkResolver (object): """ Resolve a number of DNS names in parallel. @@ -122,26 +125,49 @@ class BulkResolver (object): def __init__(me): """Initialize the resolver.""" me._namemap = {} - me._noutstand = 0 def prepare(me, name): """Prime the resolver to resolve the given host NAME.""" if name not in me._namemap: me._namemap[name] = host = ResolvingHost(name) - host._resolv = M.SelResolveByName( - name, - lambda cname, alias, addr: me._resolved(host, cname, addr), - lambda: me._resolved(host, None, [])) - me._noutstand += 1 - - def run(me): - """Run the background DNS resolver until it's finished.""" - while me._noutstand: M.select() + try: + ailist = S.getaddrinfo(name, None, S.AF_UNSPEC, S.SOCK_DGRAM, 0, + S.AI_NUMERICHOST | S.AI_NUMERICSERV) + except S.gaierror: + me._prepare(host, name) + else: + for af, skty, proto, cname, sa in ailist: + if af == S.AF_INET: host.addaddr('INET', sa[0]) + elif af == S.AF_INET6: host.addaddr('INET6', sa[0]) def lookup(me, name, flags): """Fetch the address corresponding to the host NAME.""" return me._namemap[name].get(flags) +class BresBulkResolver (BaseBulkResolver): + """ + A BulkResolver using mLib's `bres' background resolver. + + This is always available (and might use ADNS), but only does IPv4. + """ + + def __init__(me): + super(BresBulkResolver, me).__init__() + """Initialize the resolver.""" + me._noutstand = 0 + + def _prepare(me, host, name): + """Arrange to resolve a NAME, reporting the results to HOST.""" + host._resolv = M.SelResolveByName( + name, + lambda cname, alias, addr: me._resolved(host, cname, addr), + lambda: me._resolved(host, None, [])) + me._noutstand += 1 + + def run(me): + """Run the background DNS resolver until it's finished.""" + while me._noutstand: M.select() + def _resolved(me, host, cname, addr): """Callback function: remember that ADDRs are the addresses for HOST.""" if not addr: @@ -152,6 +178,9 @@ class BulkResolver (object): host._resolv = None me._noutstand -= 1 +## Select a bulk resolver. Currently, there's only one choice. +BulkResolver = BresBulkResolver + ###-------------------------------------------------------------------------- ### The configuration parser. @@ -178,7 +207,7 @@ RX_REF = RX.compile(r'(?x) \$ \( ([^)]+) \)') ## Match a $FLAGS[HOST] name resolution reference; group 1 are the flags; ## group 2 is the HOST. -RX_RESOLVE = RX.compile(r'(?x) \$ ([4*]*) \[ ([^]]+) \]') +RX_RESOLVE = RX.compile(r'(?x) \$ ([46*]*) \[ ([^]]+) \]') class ConfigSyntaxError (ExpectedError): def __init__(me, fname, lno, msg): @@ -397,8 +426,9 @@ class MyConfigParser (object): expansion and processes them correctly. * It recognizes `$FLAGS[HOST]' name-resolver requests and handles them - correctly. FLAGS consists of characters `4' (IPv4 addresses), and `*' - (all addresses, space-separated, rather than just the first). + correctly. FLAGS consists of characters `4' (IPv4 addresses), `6' + (IPv6 addresses), and `*' (all, space-separated, rather than just the + first). * Its parsing behaviour is well-defined.