Commit 916959c1 authored by Olivier Gayot's avatar Olivier Gayot Committed by Simon Kelley

Fix rev-server with /32 prefix.

[ excerpt from the man page ]
The rev-server directive provides a syntactic sugar to make specifying
address-to-name queries easier. For example
--rev-server=1.2.3.0/24,192.168.0.1 is exactly equivalent to
--server=/3.2.1.in-addr.arpa/192.168.0.1

It is not mentioned in the man page but the only prefixes that the
directive properly handles when dealing with IPv4 are /8, /16 and /24.
Specifying anything else as the same effect as specifying /16.

It is not a big deal for subnets on non-octet boundaries since they
cannot be represented using a single in-addr.arpa address. However, it
is unconvenient for /32 prefix while the analogous server directive
behaves as expected. E.g. the following server directive work
as expected:

    server=/42.10.168.192.in-addr.arpa/1.2.3.4

but the following does not:

    rev-server=192.168.10.42/32,1.2.3.4

and, in practice, the later behaves the same as:

    server=/168.192.in-addr.arpa/1.2.3.4

This strange behaviour is fixed by accepting /32 CIDR prefixes as a
valid value. Any other value will still be considered the same as /16.
parent 864913c0
...@@ -850,19 +850,30 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a ...@@ -850,19 +850,30 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
static struct server *add_rev4(struct in_addr addr, int msize) static struct server *add_rev4(struct in_addr addr, int msize)
{ {
struct server *serv = opt_malloc(sizeof(struct server)); struct server *serv = opt_malloc(sizeof(struct server));
in_addr_t a = ntohl(addr.s_addr) >> 8; in_addr_t a = ntohl(addr.s_addr);
char *p; char *p;
memset(serv, 0, sizeof(struct server)); memset(serv, 0, sizeof(struct server));
p = serv->domain = opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */ p = serv->domain = opt_malloc(29); /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
if (msize == 24) switch (msize)
p += sprintf(p, "%d.", a & 0xff); {
a = a >> 8; case 32:
if (msize != 8) p += sprintf(p, "%d.", a & 0xff);
p += sprintf(p, "%d.", a & 0xff); /* fall through */
a = a >> 8; case 24:
p += sprintf(p, "%d.in-addr.arpa", a & 0xff); p += sprintf(p, "%d.", (a >> 8) & 0xff);
/* fall through */
default:
case 16:
p += sprintf(p, "%d.", (a >> 16) & 0xff);
/* fall through */
case 8:
p += sprintf(p, "%d.", (a >> 24) & 0xff);
break;
}
p += sprintf(p, "in-addr.arpa");
serv->flags = SERV_HAS_DOMAIN; serv->flags = SERV_HAS_DOMAIN;
serv->next = daemon->servers; serv->next = daemon->servers;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment