From 97567475d4a5cd2860df6aeac5cef30be4342da6 Mon Sep 17 00:00:00 2001 Message-Id: <97567475d4a5cd2860df6aeac5cef30be4342da6.1719076106.git.mdw@distorted.org.uk> From: Mark Wooding Date: Wed, 27 Sep 2017 09:07:20 +0100 Subject: [PATCH] peerdb/tripe-newpeers.in: Add support for v4 and v6 address literals. Organization: Straylight/Edgeware From: Mark Wooding At least they get canonified now. I think v4 literals should have worked before, but it seems that they didn't. This adds a `6' flag to request only the v6 addresses for a name, but currently you can predict which addresses you get pretty well. --- peerdb/peers.in.5.in | 12 +++++++++++- peerdb/tripe-newpeers.in | 26 +++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/peerdb/peers.in.5.in b/peerdb/peers.in.5.in index 4e6d5cad..6aa8ffca 100644 --- a/peerdb/peers.in.5.in +++ b/peerdb/peers.in.5.in @@ -97,9 +97,19 @@ consist of zero or more of the following characters: looks up the .IR host 's IPv4 address(es); +.RB ` 6 ' +looks up the +.IR host 's +IPv6 address(es); +and .RB ` * ' returns all of the found addresses, separated by spaces, rather than -just the first one. +just the first one. If neither address family is requested, then +.RB ` 46 ' +is assumed. Currently, +.BR tripe-newpeers(8) +can only resolve hostnames to IPv4 addresses, but it can `resolve' +numeric addresses of either kind. .PP There is a simple concept of .I inheritance diff --git a/peerdb/tripe-newpeers.in b/peerdb/tripe-newpeers.in index 44761972..5f33f5bd 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,12 +94,14 @@ 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 @@ -136,7 +139,15 @@ class BulkResolver (object): """Prime the resolver to resolve the given host NAME.""" if name not in me._namemap: me._namemap[name] = host = ResolvingHost(name) - me._prepare(host, name) + 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 run(me): """Run the background DNS resolver until it's finished.""" @@ -182,7 +193,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): @@ -401,8 +412,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. -- [mdw]