Discussion:
[Dnsmasq-discuss] [PATCH] Improve --address and --ipset docs, fix --help output
Peter Wu
2016-08-18 22:19:53 UTC
Permalink
Manual page: clarify that the --address and --ipset options take one or
more domains rather than just two. Clarify that --ipset puts addresses
in all ipsets, it is not a 1:1 mapping from addresses.

Also increase the width for options output in --help, some options were
truncated leading to confusing output. Almost all options and
descriptions are now within the 120 colums limit.
---
Hi,

Recently I discovered the --ipset option but the manpage and --help output were
slightly confusing, so here are some fixes for that. This patch is best viewed
with git diff --color-words or with side-by-side diff.

The modifications were done based on the implementation (source code). Other
discoveries:

- Once added to the ipset and flushed (or removed due to a timeout), you need
to SIGHUP or restart dnsmasq to make it re-consider future occurrences.
- Due to the use of extract_request() in process_reply(), addresses for queries
with qdcount >= 2 are ignored (not added to the ipset). This is lucky,
because the add_to_ipset() currently assumes that the given address is
always an IPv6 address whenever an AAAA type is present in the question. So
if an A + AAAA is in the question, then it would yield the wrong result.
- ipset errors are not logged. Maybe not a problem for errors where the family
mismatches, but a full ipset could indicate a problem.

Kind regards,
Peter
---
man/dnsmasq.8 | 40 ++++++++++++++++++++++++----------------
src/option.c | 8 ++++----
2 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index 91fe672..a13e4f5 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -480,28 +480,36 @@ but provides some syntactic sugar to make specifying address-to-name queries eas
is exactly equivalent to
.B --server=/3.2.1.in-addr.arpa/192.168.0.1
.TP
-.B \-A, --address=/<domain>/[domain/][<ipaddr>]
+.B \-A, --address=/<domain>[/<domain>...]/[<ipaddr>]
Specify an IP address to return for any host in the given domains.
Queries in the domains are never forwarded and always replied to
with the specified IP address which may be IPv4 or IPv6. To give
-both IPv4 and IPv6 addresses for a domain, use repeated -A flags.
+both IPv4 and IPv6 addresses for a domain, use repeated \fB-A\fP flags.
+To include multiple IP addresses for a single query, use
+\fB--addn-hosts=<path>\fP instead.
Note that /etc/hosts and DHCP leases override this for individual
names. A common use of this is to redirect the entire doubleclick.net
domain to some friendly local web server to avoid banner ads. The
-domain specification works in the same was as for --server, with the
-additional facility that /#/ matches any domain. Thus
---address=/#/1.2.3.4 will always return 1.2.3.4 for any query not
-answered from /etc/hosts or DHCP and not sent to an upstream
-nameserver by a more specific --server directive. As for --server,
-one or more domains with no address returns a no-such-domain answer, so
---address=/example.com/ is equivalent to --server=/example.com/ and returns
-NXDOMAIN for example.com and all its subdomains.
-.TP
-.B --ipset=/<domain>/[domain/]<ipset>[,<ipset>]
-Places the resolved IP addresses of queries for the specified domains
-in the specified netfilter ip sets. Domains and subdomains are matched
-in the same way as --address. These ip sets must already exist. See
-ipset(8) for more details.
+domain specification works in the same was as for \fB--server\fP, with
+the additional facility that \fB/#/\fP matches any domain. Thus
+\fB--address=/#/1.2.3.4\fP will always return \fB1.2.3.4\fP for any
+query not answered from \fB/etc/hosts\fP or DHCP and not sent to an
+upstream nameserver by a more specific \fB--server\fP directive. As for
+\fB--server\fP, one or more domains with no address returns a
+no-such-domain answer, so \fB--address=/example.com/\fP is equivalent to
+\fB--server=/example.com/\fP and returns NXDOMAIN for example.com and
+all its subdomains.
+.TP
+.B --ipset=/<domain>[/<domain>...]/<ipset>[,<ipset>...]
+Places the resolved IP addresses of queries for one or more domains in
+the specified Netfilter IP set. If multiple setnames are given, then the
+addresses are placed in each of them, subject to the limitations of an
+IP set (IPv4 addresses cannot be stored in an IPv6 IP set and vice
+versa). Domains and subdomains are matched in the same way as
+\fB--address\fP.
+These IP sets must already exist. See
+.BR ipset (8)
+for more details.
.TP
.B \-m, --mx-host=<mx name>[[,<hostname>],<preference>]
Return an MX record named <mx name> pointing to the given hostname (if
diff --git a/src/option.c b/src/option.c
index 6cedef3..d811ed3 100644
--- a/src/option.c
+++ b/src/option.c
@@ -452,7 +452,7 @@ static struct {
{ LOPT_DHCP_FQDN, OPT_DHCP_FQDN, NULL, gettext_noop("Use only fully qualified domain names for DHCP clients."), NULL },
{ LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
{ LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
- { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<interface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
+ { LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<iface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
{ LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
{ LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
{ LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
@@ -475,7 +475,7 @@ static struct {
{ LOPT_AUTHSOA, ARG_ONE, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL },
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
- { LOPT_IPSET, ARG_DUP, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
+ { LOPT_IPSET, ARG_DUP, "/<domain>[/<domain>...]/<ipset>...", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
{ LOPT_SEC_VALID, OPT_DNSSEC_VALID, NULL, gettext_noop("Activate DNSSEC validation"), NULL },
{ LOPT_TRUST_ANCHOR, ARG_DUP, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL },
@@ -486,7 +486,7 @@ static struct {
#ifdef OPTION6_PREFIX_CLASS
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
#endif
- { LOPT_RA_PARAM, ARG_DUP, "<interface>,[high,|low,]<interval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL },
+ { LOPT_RA_PARAM, ARG_DUP, "<iface>,[<prio>,]<intval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL },
{ LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
{ LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
@@ -721,7 +721,7 @@ static void do_usage(void)
sprintf(buff, " ");

sprintf(buff+4, "--%s%s%s", opts[j].name, eq, desc);
- printf("%-40.40s", buff);
+ printf("%-55.55s", buff);

if (usage[i].arg)
{
--
2.9.2
Simon Kelley
2016-08-28 20:28:13 UTC
Permalink
Post by Peter Wu
Hi,
Recently I discovered the --ipset option but the manpage and --help output were
slightly confusing, so here are some fixes for that. This patch is best viewed
with git diff --color-words or with side-by-side diff.
Applied. Many thanks.
Post by Peter Wu
The modifications were done based on the implementation (source code). Other
- Once added to the ipset and flushed (or removed due to a timeout), you need
to SIGHUP or restart dnsmasq to make it re-consider future occurrences.
I'm not sure if that's a problem or not, and if it is, how it could be
done better?
Post by Peter Wu
- Due to the use of extract_request() in process_reply(), addresses for queries
with qdcount >= 2 are ignored (not added to the ipset). This is lucky,
because the add_to_ipset() currently assumes that the given address is
always an IPv6 address whenever an AAAA type is present in the question. So
if an A + AAAA is in the question, then it would yield the wrong result.
qdcount is a fossil from the early DNS. It's completely inadmissable
for qdcount to have any value other than one in the modern world. As
long as qdcount != 1 doesn't trigger bad behaviour (like a crash or
information leak) then the actually results of such a query are pretty
much irrelevant.
Post by Peter Wu
- ipset errors are not logged. Maybe not a problem for errors where the family
mismatches, but a full ipset could indicate a problem.
Trivial logging code added to git repo, does that work better?

Cheers,

Simon.
Post by Peter Wu
Kind regards,
Peter
Loading...