diff --git a/CHANGELOG b/CHANGELOG index 4f89799..2731cc4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,7 +24,12 @@ version 2.77 Bump zone serial on reloading /etc/hosts and friends when providing authoritative DNS. Thanks to Harrald Dunkel for spotting this. - + + Handle v4-mapped IPv6 addresses sanely in --synth-domain. + These have standard representation like ::ffff:1.2.3.4 + and are now converted to names like + --ffff-1-2-3-4. + version 2.76 Include 0.0.0.0/8 in DNS rebind checks. This range diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 8910947..91fe672 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -619,6 +619,8 @@ but IPv6 addresses may start with '::' but DNS labels may not start with '-' so in this case if no prefix is configured a zero is added in front of the label. ::1 becomes 0--1. +V4 mapped IPv6 addresses, which have a representation like ::ffff:1.2.3.4 are handled specially, and become like 0--ffff-1-2-3-4 + The address range can be of the form , or / .TP diff --git a/src/domain.c b/src/domain.c index 1dd5027..a007acd 100644 --- a/src/domain.c +++ b/src/domain.c @@ -77,18 +77,31 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr) *p = 0; - /* swap . or : for - */ - for (p = tail; *p; p++) - if (*p == '-') - { - if (prot == AF_INET) + #ifdef HAVE_IPV6 + if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail) + { + /* special hack for v4-mapped. */ + memcpy(tail, "::ffff:", 7); + for (p = tail + 7; *p; p++) + if (*p == '-') *p = '.'; -#ifdef HAVE_IPV6 - else - *p = ':'; + } + else #endif - } - + { + /* swap . or : for - */ + for (p = tail; *p; p++) + if (*p == '-') + { + if (prot == AF_INET) + *p = '.'; +#ifdef HAVE_IPV6 + else + *p = ':'; +#endif + } + } + if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr)) { if (prot == AF_INET) @@ -169,8 +182,9 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name) inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN); } + /* V4-mapped have periods.... */ for (p = name; *p; p++) - if (*p == ':') + if (*p == ':' || *p == '.') *p = '-'; strncat(name, ".", MAXDNAME);