chiark / gitweb /
peerdb/tripe-newpeers.in: Add support for v4 and v6 address literals.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 27 Sep 2017 08:07:20 +0000 (09:07 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 16 Jun 2018 18:14:10 +0000 (19:14 +0100)
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
peerdb/tripe-newpeers.in

index 4e6d5cadd765bcb1f7154f69a7dc10ff9299d8e1..6aa8ffca460d641a068c40404f8281ab5bd49f76 100644 (file)
@@ -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
index 44761972fd3b9db5a137aefb86f94e4797eb1b0f..5f33f5bdda8cf6f3d806bf212df220b04f43f447 100644 (file)
@@ -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.